Изменение источника данных для воспроизведения звука с использованием существующего MediaPlayer? - PullRequest
8 голосов
/ 30 августа 2011

Я пытаюсь использовать тот же медиаплеер, но меняю источник данных.Вот что я пытаюсь сделать:

    private MediaPlayer mMediaPlayer;

    public void pickFile1() {
       initMediaPlayer("myfile1.mp3");
    }

    public void pickFile2() {
       initMediaPlayer("myfile2.mp3");
    }

    private void initMediaPlayer(String mediafile) {
    // Setup media player, but don't start until user clicks button!
    try {
        if (mMediaPlayer == null) {
            mMediaPlayer = new MediaPlayer();
        } else {
            mMediaPlayer.reset();   // so can change data source etc.
        }
        mMediaPlayer.setOnErrorListener(this);
        AssetFileDescriptor afd = getAssets().openFd(mediafile); 
        mMediaPlayer.setDataSource(afd.getFileDescriptor());
    }
    catch (IllegalStateException e) {
        Log.d(TAG, "IllegalStateException: " + e.getMessage());
    }
    catch (IOException e) {
        Log.d(TAG, "IOException: " + e.getMessage());
    }
    catch (IllegalArgumentException e) {
        Log.d(TAG, "IllegalArgumentException: " + e.getMessage());
    }
    catch (SecurityException e) {
        Log.d(TAG, "SecurityException: " + e.getMessage());
    }

    mMediaPlayer.setOnPreparedListener(this);
    mMediaPlayer.prepareAsync(); // prepare async to not block main thread
    mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);  // Keep playing when screen goes off!
}

Я просто называю это, когда хочу перейти на новый медиафайл.Похоже, что он не меняет источник данных успешно.Первый вопрос: возможно ли это сделать таким образом, или мне нужно выпустить медиаплеер и создать новый для каждого нового файла?Если это возможно, то почему мой код не работает правильно?

Правка: ну, выпуск и воссоздание медиаплеера тоже не делают этого!Он просто продолжает играть ту же песню!?!?Как это вообще возможно?Новая идея - создать отдельный медиаплеер для каждого трека, это действительно то, что я должен сделать здесь?Возможно, это ошибка в Android?

Ответы [ 4 ]

7 голосов
/ 30 мая 2013

Обязательно остановите и перезагрузите медиаплеер перед изменением источника данных. На более важной вещи при остановке звонит

onCompletion

.. Так что проверьте, что вы делаете в этом методе. Затем позвоните

mplayer.setDataSource(audioPath);
mplayer.setOnPreparedListener(this);
mplayer.prepareAsync();
2 голосов
/ 09 июля 2012

Сегодня у меня действительно была такая же проблема с активами, и я знаю, как это исправить.

Проблема в том, что активы хранятся как один большой кусок данных, а не как группа отдельных файлов.в реальной файловой системе где-то.Таким образом, когда вы получаете assetfiledescriptor, оно указывает и на файл, но также имеет смещение и длину.Если вы просто указываете mediaplayer на assetfiledescriptor, он всегда воспроизводит первый медиафайл в вашей папке ресурсов (или что-то в этом роде).

Если вы делаете это: mMediaPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());

затем он воспроизводит правильный файл.

0 голосов
/ 05 сентября 2011

Ну, я никогда не получал действительно хороший ответ на это. Я думаю, что это может быть что-то смешное, что происходит в эмуляторе. То, что я сделал, работает отлично для меня, это загрузить файлы на внешнюю SD-карту и воспроизвести их оттуда. Это немного меняет код на это:

String path = getExternalFilesDir(null).toString() + "/";
mMediaPlayer.setDataSource(path + mediafile);

остальное остается прежним.

0 голосов
/ 31 августа 2011

Вы объявляете private String mediafile="my.mp3";, затем используете AssetFileDescriptor afd = getAssets().openFd(mediafile);, но ни в коем случае (из кода, который вы разместили) вы не меняете значение mediafile.
Я бы рекомендовал поставить mediafile = theNextFile; в строке перед afd = getAssets().openFd(mediafile); где theNextFile скорее всего будет ссылаться на файл на SD-карте, который пользователь выбрал перед нажатием указанной кнопки.
Я не уверен, как управлять получением имен файлов с SD-карты, но я бы подумал, используяstartActivityForResult будет одним из способов сделать это.

...