无法使用 STREAM_VOICE_CALL 在 android java 中通过 MediaPlayer 播放音频

Usm*_*man 3 java audio android soundpool android-mediaplayer

我尝试通过 MediaPlayer 的 setAudioStreamType(AudioManager.STREAM_VOICE_CALL); 播放许多音频(mp3)文件;但是 mp.start(); 不播放也不抛出异常。该设置适用于 SoundPool,但时间限制为 5 秒左右,某些文件播放时间长达 8 秒。我在这里附上部分代码:

    String s = absolutepath.get(position);
    Uri u = Uri.parse(s);
    playing = (MediaPlayer) MediaPlayer.create(MainActivity.this, u);
    playing.setOnPreparedListener(this);
Run Code Online (Sandbox Code Playgroud)

onPrepared 包括:

    @Override
public void onPrepared(MediaPlayer mp) {
    // TODO Auto-generated method stub
    spProgress.cancel();
    mp.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
    try {
    mp.start();
    } catch (IllegalStateException e) {
        Toast.makeText(this, "exception", Toast.LENGTH_SHORT).show();
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经在没有 try/catch 甚至没有监听器的情况下尝试过这个。它唯一播放的时间是当我不使用流类型 STREAM_VOICE_CALL 时。

可以使用 SoundPool 播放相同的文件:

SoundPool sp = new SoundPool(1, AudioManager.STREAM_VOICE_CALL, 0);
sp.load(s, 1);
sp.setOnLoadCompleteListener(this);
Run Code Online (Sandbox Code Playgroud)

听众:

@Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
    // TODO Auto-generated method stub
    if (status == 0) {
        spProgress.cancel();
        sp.play(sampleId, 1, 1, 1, 0, 1);
    } else {
        Toast.makeText(this, "failed to load", Toast.LENGTH_SHORT).show();
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 5

我实际上也遇到了同样的问题,谷歌的指南在这里非常糟糕 - 它确实有点棘手,但解释起来很简单:

当您需要更改 STREAM,然后再次准备()您的 MediaPlayer 时,您可以通过执行以下操作来使其工作:

    Resources res = getResources();
    AssetFileDescriptor afd = res.openRawResourceFd(R.raw.tts_a);

    mp = new MediaPlayer();
    //mp.reset();
    mp.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
    mp.setLooping(false);
    try {
        mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
        mp.prepare();
    } catch (IOException e) {
        e.printStackTrace();
    }

    mp.start();
Run Code Online (Sandbox Code Playgroud)

实际的技巧是不要使用 MediaPlayer.create,因为它正在调用准备本身!因此您无法设置流。通过使用 AssetFileDescriptor 设置文件,您可以设置流并随后调用您的prepare()!