使用现有的MediaPlayer更改audio播放的数据源?

我试图使用相同的媒体播放器,但更改数据源。 这是我想要做的:

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! } 

我只是想在更改为新的媒体文件时调用它。 它似乎并没有成功改变数据源。 第一个问题:是否可以这样做,还是必须发布媒体播放器,并为每个新文件创build一个新的? 如果可能的话,为什么我的代码不能正常工作?

编辑:好吧,释放和重新创build媒体播放器也没有这样做! 它只是继续播放同一首歌曲!?!? 这怎么可能呢? 新的想法 – 为每个轨道创build一个不同的媒体播放器,这真的是我必须做的吗? 这可能是Android的错误吗?

Solutions Collecting From Web of "使用现有的MediaPlayer更改audio播放的数据源?"

确保在更改数据源之前停止并重置mediaplayer。 更重要的是当你停止通话

在完成的时候

所以请检查你在这个方法中做什么。 然后打电话

 mplayer.setDataSource(audioPath); mplayer.setOnPreparedListener(this); mplayer.prepareAsync(); 

我今天的资产实际上也有这个问题,我知道这个问题。

问题在于资产是作为一大块数据存储的,而不是真正的文件系统上的一堆单独文件。 所以,当你得到一个assetfiledescriptor ,它既指向一个文件,又有一个偏移量和一个长度。 如果您只是将媒体播放器指向assetfiledescriptor本身,它总是播放资产文件夹(或其他)中的第一个媒体文件。

如果你这样做: mMediaPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());

那么它会播放正确的文件。

你声明private String mediafile="my.mp3"; 那么你使用AssetFileDescriptor afd = getAssets().openFd(mediafile); 但在任何时候(从你发布的代码),你是否改变mediafile的价值。
我会build议把mediafile = theNextFile;afd = getAssets().openFd(mediafile);之前的行上afd = getAssets().openFd(mediafile); 其中下一个文件可能会引用用户在点击所述button之前select的SD卡上的文件。
我不知道如何pipe理从SD卡获取文件名,但我认为使用startActivityForResult将是一个方法来做到这一点。

那么,我从来没有得到一个很好的答案。 我觉得在模拟器中可能会发生一些有趣的事情。 我所做的是对我很好,是将文件下载到外部SD卡,并从那里播放。 这稍微改变了这个代码:

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

其余的保持不变。