在安卓系统中播放PCM流

4
我通过以太网端口获取PCM流。到目前为止,我能够捕获数据包并从中提取出pcm_payload数据。
如何在Android上播放这些原始PCM数据?该PCM数据是16位2通道,44.1kHZ速率的流。
我对Android应用程序编程和音频编程都很陌生。如果这是一个琐碎的问题,请谅解。
2个回答

7
您可以使用AudioTrack播放PCM数据!
可能像这样:
int bufsize = AudioTrack.getMinBufferSize(44100,
           AudioFormat.CHANNEL_OUT_STEREO,
           AudioFormat.ENCODING_PCM_16BIT);

AudioTrack audio = new AudioTrack(AudioManager.STREAM_MUSIC, 
                       44100, //sample rate
                       AudioFormat.CHANNEL_OUT_STEREO, //2 channel
                       AudioFormat.ENCODING_PCM_16BIT, // 16-bit
                       bufsize, 
                       AudioTrack.MODE_STREAM );
audio.play()

然后调用 audio.write() 来写入您的 PCM 数据。

CHANNEL_CONFIGURATION_STEREO 似乎已经过时了。我使用了 CHANNEL_OUT_STEREO 替代它。它可以正常工作,没问题吧? - Sandeep
是的,CHANNEL_CONFIGURATION_STEREO和CHANNEL_OUT_STEREO都是2通道! - 木大白易
好的。我已经相应地编辑了答案。此外,在write()之前必须调用play()..而且只需要一个play()就足以支持多个write()调用。但是,在写入audioTrack()之前,我必须将数据从大端转换为小端。在我的编辑后,如果您觉得有进一步编辑答案的需要,请随时进行编辑。谢谢。 - Sandeep
对于我的粗心大意,我感到很抱歉。也许我没有表达清楚,你所编辑和评论的内容似乎更加清晰和正确! - 木大白易
1
有没有办法将来自远程服务器的PCM流输入?我的意思是,对于audio.write() - cantona_7

1

这是我的解决方案。将流写入文件并播放。

public class AudioTrackPlayer {
private String pathAudio;
private AudioTrack audioPlayer;
private Thread mThread;
private int bytesread = 0, ret = 0;
private int size;
private FileInputStream in = null;
private byte[] byteData = null;
private int count = 512 * 1024; // 512 kb
private boolean isPlay = true;
private boolean isLooping = false;
private static Handler mHandler;

public AudioTrackPlayer() {

}

public void prepare(String pathAudio){
    this.pathAudio = pathAudio;
    mHandler = new Handler();
}

public void play(){
    stop();

    isPlay = true;
    bytesread = 0;
    ret = 0;
    if (pathAudio == null)
        return;

    audioPlayer = createAudioPlayer();
    if (audioPlayer == null) return;
    audioPlayer.play();

    mThread = new Thread(new PlayerProcess());
    mThread.start();
}

private final Runnable mLopingRunnable = new Runnable() {
    @Override
    public void run() {
        play();
    }
};

private AudioTrack createAudioPlayer(){
    int intSize = android.media.AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_STEREO,
            AudioFormat.ENCODING_PCM_16BIT);
    AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_STEREO,
            AudioFormat.ENCODING_PCM_16BIT, intSize, AudioTrack.MODE_STREAM);
    if (audioTrack == null) {
        Log.d("TCAudio", "audio track is not initialised ");
        return null;
    }

    File file = null;
    file = new File(pathAudio);

    byteData = new byte[(int) count];
    try {
        in = new FileInputStream(file);

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    size = (int) file.length();
    return  audioTrack;
}

private class PlayerProcess implements Runnable{

    @Override
    public void run() {
        while (bytesread < size && isPlay) {
            if (Thread.currentThread().isInterrupted()) {
                break;
            }
            try {
                ret = in.read(byteData, 0, count);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (ret != -1) { // Write the byte array to the track
                audioPlayer.write(byteData,0, ret);
                bytesread += ret;
            } else break;
        }
        try {
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (audioPlayer!=null){
            if (audioPlayer.getState()!=AudioTrack.PLAYSTATE_STOPPED){
                audioPlayer.stop();
                audioPlayer.release();
                mThread = null;
            }
        }
        if (isLooping && isPlay ) mHandler.postDelayed(mLopingRunnable,100);
    }
}

public void setLooping(){
    isLooping = !isLooping;
}

public void pause(){

}

public void stop(){
    isPlay = false;
    if (mThread != null) {
        mThread.interrupt();
        mThread = null;
    }
    if (audioPlayer != null) {
        audioPlayer.stop();
        audioPlayer.release();
        audioPlayer = null;
    }
}

public void reset(){

}

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接