Android音视频开发-AudioTrack

本文详细介绍了Android平台的AudioTrack类,包括其构造、音频数据写入、播放控制、音量设置以及资源管理。重点讨论了AudioTrack的参数配置和使用场景,如音频流类型、采样率、声道选择等。
摘要由CSDN通过智能技术生成

Android音视频开发-AudioTrack

本篇文章我们主要介绍下AudioTrack.

1: 简介

AudioTrack是Android平台上的一个类,用于播放音频数据.

它允许PCM音频缓冲区流式传输到音频接收器进行播放.

  1. 创建AudioTrack对象:可以通过构造函数创建AudioTrack对象,需要指定音频流类型、采样率、音频通道配置和音频格式等参数。
  2. 写入音频数据:可以使用write()方法将音频数据写入AudioTrack对象。写入的数据可以是PCM格式的原始音频数据,也可以是压缩格式的音频数据(如MP3、AAC等)。
  3. 播放音频数据:在写入音频数据后,可以调用play()方法开始播放音频数据。可以使用pause()方法暂停播放,使用stop()方法停止播放。
  4. 设置音量:可以使用setVolume()方法设置音量大小,范围为0.0到1.0之间。
  5. 设置播放模式:可以使用setPlaybackRate()方法设置播放速率,使用setLoopPoints()方法设置循环播放的起始点和结束点。
  6. 监听播放状态:可以使用OnPlaybackPositionUpdateListener接口监听播放进度和播放完成事件。
  7. 释放资源:在不再需要使用AudioTrack对象时,应该调用release()方法释放资源。

2: 创建AudioTrack对象

public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
        int bufferSizeInBytes, int mode)
throws IllegalArgumentException {
    this(streamType, sampleRateInHz, channelConfig, audioFormat,
            bufferSizeInBytes, mode, AudioManager.AUDIO_SESSION_ID_GENERATE);
}

参数配置:

1: streamType

  1. AudioManager.STREAM_VOICE_CALL:用于语音通话的音频流类型。
  2. AudioManager.STREAM_SYSTEM:用于系统声音的音频流类型,例如按键声音、提示音等。
  3. AudioManager.STREAM_RING: 用于电话铃声的音频流类型。
  4. AudioManager.STREAM_MUSIC:用于音乐播放的音频流类型。
  5. AudioManager.STREAM_ALARM:用于闹钟的音频流类型。
  6. AudioManager.STREAM_NOTIFICATION:用于通知的音频流类型。
  7. AudioManager.STREAM_DTMF:用于双音多频信号的音频流类型

2: sampleRateInHz

采样率的大小限制是4000~192000; 可以在源码中查看:

/** Minimum value for sample rate,
 *  assuming AudioTrack and AudioRecord share the same limitations.
 * @hide
 */
// never unhide
public static final int SAMPLE_RATE_HZ_MIN = 4000;
/** Maximum value for sample rate,
 *  assuming AudioTrack and AudioRecord share the same limitations.
 * @hide
 */
// never unhide
public static final int SAMPLE_RATE_HZ_MAX = 192000;
/** Sample rate will be a route-dependent value.
 * For AudioTrack, it is usually the sink sample rate,
 * and for AudioRecord it is usually the source sample rate.
 */
public static final int SAMPLE_RATE_UNSPECIFIED = 0;

如果不在这个区间,系统则抛出异常:

调用setSampleRate指定sampleRate时,如果不在4000~192000区间则怕出new IllegalArgumentException("Invalid sample rate " + sampleRate).

public Builder setSampleRate(int sampleRate) throws IllegalArgumentException {
    // TODO Consider whether to keep the MIN and MAX range checks here.
    // It is not necessary and poses the problem of defining the limits independently from
    // native implementation or platform capabilities.
    if (((sampleRate < SAMPLE_RATE_HZ_MIN) || (sampleRate > SAMPLE_RATE_HZ_MAX)) &&
            sampleRate != SAMPLE_RATE_UNSPECIFIED) {
        throw new IllegalArgumentException("Invalid sample rate " + sampleRate);
    }
    mSampleRate = sampleRate;
    mPropertySetMask |= AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE;
    return this;
}

至于初始化时,校验的方法在audioParamCheck方法中:

// sample rate, note these values are subject to change
if ((sampleRateInHz < AudioFormat.SAMPLE_RATE_HZ_MIN ||
        sampleRateInHz > AudioFormat.SAMPLE_RATE_HZ_MAX) &&
        sampleRateInHz != AudioFormat.SAMPLE_RATE_UNSPECIFIED) {
    throw new IllegalArgumentException(sampleRateInHz
            + "Hz is not a supported sample rate.");
}

3: channelConfig

声道配置同样在AudioFormat中定义,常用的有:

AudioFormat.CHANNEL_OUT_MONO:单声道 AudioFormat.CHANNEL_OUT_STEREO:双声道

4:audioFormat

该参数定义音频格式:

  1. AudioFormat.ENCODING_PCM_8BIT:8位PCM编码
  2. AudioFormat.ENCODING_PCM_16BIT:16位PCM编码
  3. AudioFormat.ENCODING_PCM_FLOAT:浮点型PCM编码

5:bufferSizeInBytes

音频缓冲区的大小,以字节为单位.我们可以通过getMinBufferSize()来获取最小缓冲区大小.

6: mode

指定音频输出模式.

Android 系统提供了两种模式如下:

/**
 * Creation mode where audio data is transferred from Java to the native layer
 * only once before the audio starts playing.
 */
public static final int MODE_STATIC = 0;
/**
 * Creation mode where audio data is streamed from Java to the native layer
 * as the audio is playing.
 */
public static final int MODE_STREAM = 1;
  1. MODE_STATIC:静态模式,适用于一次性播放完整音频数据的场景
  2. MODE_STREAM:流模式,不间断地写入音频数据.

创建代码如下:

int streamType = AudioManager.STREAM_MUSIC; // 音频流类型
int sampleRateInHz = 44100; // 采样率
int channelConfig = AudioFormat.CHANNEL_OUT_MONO; // 声道配置
int audioFormat = AudioFormat.ENCODING_PCM_16BIT; // 音频格式
int bufferSizeInBytes = AudioTrack.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat); // 缓冲区大小
audioTrack = new AudioTrack(streamType, sampleRateInHz, channelConfig, audioFormat, bufferSizeInBytes, AudioTrack.MODE_STREAM);

3: 写入音频数据+播放

    /**
     * 播放录音
     */
    private void playAudio() {
        stopPlay();

        File file = new File("sdcard/audioRecord.pcm");
        if (!file.exists()) return;

        int streamType = AudioManager.STREAM_MUSIC; // 音频流类型
        int sampleRateInHz = 44100; // 采样率
        int channelConfig = AudioFormat.CHANNEL_OUT_STEREO; // 声道配置
        int audioFormat = AudioFormat.ENCODING_PCM_16BIT; // 音频格式
        int bufferSizeInBytes = AudioTrack.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat); // 缓冲区大小
        audioTrack = new AudioTrack(streamType, sampleRateInHz, channelConfig, audioFormat, bufferSizeInBytes, AudioTrack.MODE_STREAM);


//        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
//            /**
//             * 设置音频信息属性
//             * 1.设置支持多媒体属性,比如audio,video
//             * 2.设置音频格式,比如 music
//             */
//            AudioAttributes attributes = new AudioAttributes.Builder()
//                    .setUsage(AudioAttributes.USAGE_MEDIA)
//                    .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
//                    .build();
//            /**
//             * 设置音频格式
//             * 1. 设置采样率
//             * 2. 设置采样位数
//             * 3. 设置声道
//             */
//            AudioFormat format = new AudioFormat.Builder()
//                    .setSampleRate(sampleRateInHz)
//                    .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
//                    .setChannelMask(channelConfig)
//                    .build();
//            audioTrack = new AudioTrack(attributes,format,bufferSizeInBytes,AudioTrack.MODE_STREAM, AudioManager.AUDIO_SESSION_ID_GENERATE);
//
//        }
        audioTrack.play();
        new Thread(() -> {
            FileInputStream fileInputStream = null;
            try {
                fileInputStream = new FileInputStream(file);
                byte[] buffer = new byte[bufferSizeInBytes];
                Log.i(TAG, "playAudio: "+bufferSizeInBytes);
                int read = 0;
                while (read != -1) {
                    read = fileInputStream.read(buffer);
                    //将缓冲区buffer写入audioTrack进行播放
                    audioTrack.write(buffer, 0, buffer.length);

                }
                audioTrack.stop();
                audioTrack.release();
            } catch (Throwable e) {

            }

        }).start();
    }

4: 释放

/**
 * 停止播放录音,并释放资源
 */
private void stopPlay() {
    if (audioTrack != null) {
        audioTrack.release();
    }
}

这里注意下,release方法内部实现了stop,所以我们不需要额外的调用stop停止播放.

另外,如果调用停止播放, 内部会判断当前状态,如果非STATE_INITIALIZED下调用,则会抛出异常.

public void stop()
throws IllegalStateException {
    if (mState != STATE_INITIALIZED) {
        throw new IllegalStateException("stop() called on uninitialized AudioTrack.");
    }

    // stop playing
    synchronized(mPlayStateLock) {
        native_stop();
        baseStop();
        mPlayState = PLAYSTATE_STOPPED;
        mAvSyncHeader = null;
        mAvSyncBytesRemaining = 0;
    }
}
  • 7
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
Android音视频开发是指在Android平台上进行音频和视频相关功能的开发。它涉及到音频的录制、播放,视频的采集、编码、解码和播放等方面。 在Android音视频开发中,可以使用Android提供的多媒体框架来实现各种功能。以下是Android音视频开发的一些关键点: 1. 音频开发: - 音频录制:可以使用AudioRecord类进行音频的录制,通过设置音频源、采样率、声道数等参数来实现。 - 音频播放:可以使用MediaPlayer类或AudioTrack类进行音频的播放,通过设置音频文件路径或音频数据来实现。 2. 视频开发: - 视频采集:可以使用Camera类或Camera2 API进行视频的采集,通过设置摄像头参数、预览尺寸等来实现。 - 视频编码:可以使用MediaCodec类进行视频的编码,通过设置编码器类型、编码参数等来实现。 - 视频解码:可以使用MediaCodec类进行视频的解码,通过设置解码器类型、解码参数等来实现。 - 视频播放:可以使用SurfaceView或TextureView进行视频的播放,通过设置视频文件路径或视频数据来实现。 3. 音视频处理: - 音频处理:可以使用AudioEffect类进行音频的处理,如混音、变声等。 - 视频处理:可以使用OpenGL ES进行视频的处理,如滤镜、特效等。 4. 直播和推流: - 直播:可以使用第三方库,如librtmp、FFmpeg等来实现音视频的直播功能。 - 推流:可以使用第三方库,如librtmp、FFmpeg等来实现音视频的推流功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值