【问题标题】:How to correctly pause AudioTrack and resume playing smoothly?如何正确暂停 AudioTrack 并恢复流畅播放?
【发布时间】:2019-09-13 10:32:57
【问题描述】:

我正在使用 Android 的 AudioTrack 播放之前录制的 PCM 文件。如果我在播放时不暂停,一切都很好;但如果我暂停并继续,则会跳过一大段音频(大约 1 秒)。这是我的代码:

// Player thread
audioTrack = new AudioTrack(
                    AudioManager.STREAM_MUSIC,
                    RECORDER_SAMPLERATE,
                    AudioFormat.CHANNEL_OUT_MONO,
                    RECORDER_AUDIO_ENCODING,
                    bufferSize,
                    AudioTrack.MODE_STREAM);

audioTrack.play();

FileInputStream is = null;
try {
    is = new FileInputStream(filePath);
} catch (FileNotFoundException e){
    e.printStackTrace();
    return;
}

byte[] buffer = new byte[bufferSize];
int offset = 0;

while (true) {
    if(paused) { continue;}

    int cnt = 0;
    try {
       cnt = is.read(buffer, 0, bufferSize);
    } catch (IOException e){
       e.printStackTrace();
    }
    if(cnt < 0) break;
    audioTrack.write(buffer, 0, cnt);
    audioTrack.play();
}
audioTrack.release();

这是暂停和恢复播放的代码:

public void pause(){
    this.paused = true;
    audioTrack.pause();
}

public void resume(){
    this.paused = false;
}

出了什么问题? pause的正确做法是什么?

【问题讨论】:

  • 你是在没有任何服务的情况下在主线程(Activity/Fragment 类)中调用audioTrack.play(); 吗?
  • 我建议将音轨播放代码包装在后台线程的服务类中。然后,您可以在广播接收器的帮助下实现播放/暂停功能。
  • 不,第一部分代码被包装在一个单独的线程中。

标签: android audio audiotrack


【解决方案1】:

很可能,write 正在返回一个简短的传输计数。根据documentation

...如果轨道在进入时停止或暂停...那么写入可能会返回一个短的传输计数。

您的代码没有解决这种边缘情况,因此很可能整个缓冲区的音频都被丢弃了。

一个简单的解决方案可能是在play() 之后立即尝试第二个write,但前提是第一个write 返回一个短计数。第二个write 需要准确说明在第一个write 期间未写入的那些字节。

【讨论】:

    猜你喜欢
    • 2013-11-21
    • 1970-01-01
    • 2021-09-02
    • 1970-01-01
    • 2021-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多