美文网首页
Audroid AudioTrack音频播放

Audroid AudioTrack音频播放

作者: 懒烂蓝 | 来源:发表于2019-08-20 16:53 被阅读0次

    1、简介

    Android 中用于播放音频的API有三种,分别是:MediaPlayer,SoundPool,AudioTrack。MediaPlayer适合长时间在后台播放媒体音乐,包括本地音乐或在线流媒体资源。SoundPool适合播放比较短的音频片段,比如游戏音效、铃声片段等,它可以同时播放多个音频。AudioTrack更接近底层,它提供了强大的音频控制能力,支持低延迟播放,适合流媒体播放等。AudioTrack播放的音频必须是解码后的PCM数据。

    2、MediaPlayer的创建

    public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
                int bufferSizeInBytes, int mode)
    
    • streamType 这个参数代表当前应用使用哪种音频管理策略。当系统有多个进程需要播放音频时,这个策略会决定最终展示的效果。该参数值在AudioManager类中,主要包括:
      STREAM_VOCIE_CALL:电话声音
      STREAM_SYSTEM:系统声音
      STREAM_RING:铃声
      STREAM_MUSCI:音乐声
      STREAM_ALARM:警告声
      STREAM_NOTIFICATION:通知声

    • sampleRateInHz 该参数表示采样率。44100Hz是科学家给出的最佳采样频率,并且在Android中也是多所有Android设备兼容最好的采样频率。

    • channelConfig 通道数,也就是声道数。常量定义在AudioFormat类中,CHANNEL_OUT_MONO表示单声道,CHANNEL_OUT_STEREO表示双声道。

    • audioFormat 指音频采样精度,或者说是音频位宽。常量定义在AudioFormat类中,可选AudioFormat.ENCODING_PCM_16BIT或AudioFormat.ENCODING_PCM_8BIT等。16位将占用更多的空间,但采集的音频也更加接近原声。AudioFormat.ENCODING_PCM_16BIT目前兼容性更好。

    • bufferSizeInBytes 这个参数是AudioRecoder内部音频缓冲区的大小。该缓冲区的大小不能小于一个“音频帧”的大小。音频帧的计算方法为:int size = 采样率 x 位宽 x 采样时间 x 声道数。
      采样时间是指采集一帧数据所用的时间,它的取值一般在2.5ms~120ms 之间,根据手机厂商等因素决定。每一帧采样的时间越短,产生的延时就越小,但是碎片化的数据也就越多。
      AudioRecoder类中提供了一个静态方法int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat)来获取缓冲区大小。音频缓冲区大小必须是“音频帧”大小的2~N倍。这里强烈建议使用该方法去计算缓冲区大小,而不是手动去计算。

    • mode AudioTrack提供两种播放方式,一种是static,另外一种是stream。static方式需要一次性的将所有的音频数据全部写入音频缓冲区,这样简单高效,适用于铃声、系统提示音等比较短的音频片段。stream方式是按一定的时间间隔将音频数据不断的写入到缓存区,比如音频通话,视频直播的声音播放,理论上适用于所有的音频播放场景。

    3、音频播放

    AudioTrack创建完成后,就可以在一个新的线程中,调用以下方法将数据写入到缓存区进行播放
    AudioTrack.write(byte[] audioData, int offsetInBytes, int sizeInBytes)
    AudioTrack.write方法需要在子线程中调用。

    4、代码示例

        private static final int DEFAULT_STREAM_TYPE = AudioManager.STREAM_MUSIC;
        private static final int DEFAULT_PLAY_MODE = AudioTrack.MODE_STREAM;
        private static final int DEFAULT_CHANNEL = AudioFormat.CHANNEL_OUT_MONO;
    
        /**
         * 缓存的音频大小
         */
        private int mBufferSize;
    
    
        private boolean isPlaying = false;
    
        private AudioTrack audioTrack;
       /**
         * @param sampleRate sample rate、采样率
         * @param encoding   Audio data format、音频格式
         */
        AudioPlayer(int sampleRate, int encoding) {
            this.mSampleRate = sampleRate;
            this.mBufferSize = AudioTrack.getMinBufferSize(sampleRate, DEFAULT_CHANNEL, encoding);
    
            if (mBufferSize == AudioTrack.ERROR_BAD_VALUE) {
                Log.e(TAG, "获取BufferSize失败");
                return;
            }
    
            this.audioTrack = new AudioTrack(DEFAULT_STREAM_TYPE, sampleRate, DEFAULT_CHANNEL, encoding, mBufferSize, DEFAULT_PLAY_MODE);
    
            isPlaying = false;
        }
    
        /**
         * 播放音频
         *
         * @param audioData
         */
        public void startPlay(final byte[] audioData) {
            if (isPlaying) {
                return;
            }
            if (audioData.length < mBufferSize) {
                Log.e(TAG, "startPlay: 录音太短");
                return;
            }
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    if (audioTrack.write(audioData, 0, audioData.length) != audioData.length) {
                        Log.e(TAG, "startPlay: 播放出错");
                    }
                    audioTrack.play();
                }
            }).start();
        }
    
         /**
         * 停止播放
         */
        public void stopPlay() {
            if (!isPlaying) {
                return;
            }
            if (audioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING) {
                audioTrack.stop();
            }
            audioTrack.release();
            isPlaying = false;
        }
    

    这里只是介绍了使用AudioTrack进行音频的播放,示例代码只是部分代码。在这里记录一下自己学习的过程。

    相关文章

      网友评论

          本文标题:Audroid AudioTrack音频播放

          本文链接:https://www.haomeiwen.com/subject/rvbpsctx.html