Не могу использовать STREAM_VOICE_CALL для воспроизведения аудио через MediaPlayer в Android Java

Я пытался воспроизвести много аудио (mp3) файлов через setAudioStreamType MediaPlayer (AudioManager.STREAM_VOICE_CALL); но 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);

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();
    }
}

Я пробовал это без try/catch и даже без слушателя. Единственный раз, когда он воспроизводится, я не использую тип потока STREAM_VOICE_CALL.

Те же файлы могут быть воспроизведены с SoundPool:

SoundPool sp = new SoundPool(1, AudioManager.STREAM_VOICE_CALL, 0);
sp.load(s, 1);
sp.setOnLoadCompleteListener(this);

Слушатель:

@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();
    }
}

1 ответ

Решение

У меня на самом деле была та же проблема, и руководство Google здесь очень плохое - оно действительно немного сложнее, но легко объяснить:

Поскольку вам нужно изменить 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();

Фактический трюк состоит в том, чтобы НЕ использовать MediaPlayer.create, так как он вызывает саму подготовку! Поэтому вы не можете установить поток. Установив файл с помощью AssetFileDescriptor, вы можете установить Stream и впоследствии вызывать метод prepare()!

Другие вопросы по тегам