Android音視頻開發(fā)(二):音頻播放

簡介

上一篇Android音視頻開發(fā)(一):音頻錄制
我們介紹了如何用AudioRecorder進行錄音,但是我們得到是PCM格式的錄音文件,PCM用平常的軟件是無法播放的,但是我們有不想轉(zhuǎn)換成WAV或者其他格式怎么辦呢,有沒有什么方法可以直接播放PCM格式的文件呢

當然有,那就是使用AudioTrack,可能有的人是第一次見,別擔(dān)心,今天我們就來一起研究下,如何使用AudioTrack播放PCM文件

為什么要使用AudioTrack

有的人可能會說,不能教我們怎么轉(zhuǎn)換成WAV,MP3格式然后直接用MediaPlayer播放嗎,偏偏要用AudioTrack,聽都沒聽過

各位看官別著急,怎么轉(zhuǎn)換格式我之后的章節(jié)會說,我講AudioTrack的目的是因為之后PCM還有更多的應(yīng)用,比如變聲,語音識別等,所以讓我們先學(xué)會怎么播放PCM吧

創(chuàng)建AudioTrack

我們先來創(chuàng)建AudioTrack,創(chuàng)建AudioTrack很簡單,和當時我們創(chuàng)建AudioRecorder差不多

private static final int AUDIO_SAMPLE_RATE = 16000;//采樣率
private static final int AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;//編碼格式 PCM 16位
private static final int MODE = AudioTrack.MODE_STREAM;//音頻流的形式
private static final int STREAM_TYPE = android.media.AudioManager.STREAM_MUSIC;//音頻流類型 音樂(用于系統(tǒng)管理)
private static final int AUDIO_OUT_CHANNEL = AudioFormat.CHANNEL_OUT_STEREO;//雙聲道
private int bufferSizeInBytes2 = 0;//最小播放錄音緩存
private AudioTrack mAudioTrack;//AudioTrack
public void createDefaultPlay() {
    bufferSizeInBytes2 = AudioTrack.getMinBufferSize(AUDIO_SAMPLE_RATE, AUDIO_OUT_CHANNEL, AUDIO_ENCODING);
    mAudioTrack = new AudioTrack(STREAM_TYPE, AUDIO_SAMPLE_RATE, AUDIO_OUT_CHANNEL, AUDIO_ENCODING, bufferSizeInBytes2, MODE);
}

之前我們創(chuàng)建AudioRecorder需要一個叫做最小緩存整數(shù)值,現(xiàn)在我們創(chuàng)建AudioTrack也同樣需要創(chuàng)建一個這樣的值,因為我們播放是以流的形式播放的,也就是一邊讀一邊播,

注意區(qū)分AudioRecorder創(chuàng)建的細小差別,還有就是要保證采樣率,編碼格式、聲道數(shù)與錄音文件保持一致

這樣,我們的AudioTrack就創(chuàng)建成功了

開始播放

AudioRecorder有些許不同的是播放不是一開始就啟動的,請注意下面代碼

/**
 * 開啟播放子線程
 */
private void startPlayThread() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            readDataToAudioTrack();
        }
    }).start();
}

我們要先開啟播放錄音的子線程,不能直接在主線程操作,因為會阻塞主線程

/**
 * 將文件內(nèi)容輸出到AudioTrack
 */
private void readDataToAudioTrack() {
    byte[] audioData = new byte[bufferSizeInBytes2];
    DataInputStream stream = null;
    int readSize = 0;
    try {
        stream = new DataInputStream(new FileInputStream(mPlayFileName));
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    try {
        while (stream.available() > 0) {
            readSize = stream.read(audioData);
            if (readSize == AudioTrack.ERROR_INVALID_OPERATION || readSize == AudioTrack.ERROR_BAD_VALUE) {
                continue;
            }
            if (readSize > 0) {
                mAudioTrack.play();
                mAudioTrack.write(audioData, 0, readSize);
            }
        }
        mAudioTrack.stop();
        stream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

可以看到,我們是在去讀到文件內(nèi)容后再去調(diào)用mAudioTrack.play()mAudioTrack.write(audioData, 0, readSize),當然,這也符合邏輯,因為必須得到數(shù)據(jù)才可以去播放,當我們while循環(huán)結(jié)束后,我們就停止播放,并關(guān)閉相應(yīng)的文件流

最后

這樣,我們完整地播放了一段PCM格式的錄音文件,希望大家能喜歡。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容