使用现有 MediaPlayer 更改音频播放的数据源?
我正在尝试使用相同的媒体播放器但更改数据源。这是我正在尝试做的事情:
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 中的一个错误吗?
I'm trying to use the same media player but change the data source. Here is what I'm trying to do:
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!
}
I just call this when I want to change to a new mediafile. It doesn't appear to be changing the data source successfully though. First question: is it possible to do it this way, or do I have to release the media player and create a new one for each new file? If it is possible, then why isn't my code working right?
Edit: well, releasing and recreating the media player isn't doing it either! It just keeps playing the same song!?!? How is that even possible? New idea -- create a different media player for each track, is that really what I have to do here? Is this a bug in Android perhaps?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
确保在更改数据源之前停止并重置媒体播放器。
当你停止呼叫时,更重要的事情
.. 因此,请检查您在此方法中所做的事情。然后打电话
Make sure to stop and reset mediaplayer before changing datasource.
On more important thing when you stop it calls
.. So do check what you are doing in this method. Then call
事实上,我今天也遇到了同样的资产问题,而且我知道解决办法。
问题在于,资产被存储为一大块数据,而不是实际作为真实文件系统上某处的一堆单独文件。因此,当您获得 assetfiledescriptor 时,它不仅指向一个文件,而且还具有偏移量和长度。如果您只是将
mediaplayer
指向assetfiledescriptor
本身,它始终会播放资产文件夹(或其他文件夹)中的第一个媒体文件。如果你这样做:
mMediaPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
然后它会播放正确的文件。
I've actually had this same problem with assets today, and I know the fix.
The problem is that the assets are stored as one big chunk of data rather than actually as a bunch of individual files on a real file system somewhere. So, when you get an
assetfiledescriptor
, it points both to a file, but also has an offset and a length. If you just pointmediaplayer
at theassetfiledescriptor
itself, it always plays the first media file in your assets folder (or something).If you do this:
mMediaPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
then it plays the right file.
您声明
private String mediafile="my.mp3";
然后使用AssetFileDescriptor afd = getAssets().openFd(mediafile);
但绝对不会(从您的代码中)已发布)您是否更改mediafile
的值。我建议将
mediafile = theNextFile;
放在afd = getAssets().openFd(mediafile);
之前,其中theNextFile
可能指的是用户在单击所述按钮之前选择的 SD 卡上的文件。我不确定如何管理从 SD 卡获取文件名,但我认为使用
startActivityForResult
将是一种方法。You declare
private String mediafile="my.mp3";
then you useAssetFileDescriptor afd = getAssets().openFd(mediafile);
but at no point (from the code you posted) do you change the value ofmediafile
.I would recommend putting
mediafile = theNextFile;
onthe line beforeafd = getAssets().openFd(mediafile);
wheretheNextFile
would likely refer to a file on the sd card that the user chose before clicking said button.I'm not sure how to manage getting the file names from sd card, but I'd think using a
startActivityForResult
would be one way to do it.好吧,我从来没有得到过一个很好的答案。我认为模拟器中可能会发生一些有趣的事情。我所做的对我来说非常有用,即将文件下载到外部 SD 卡并从那里播放它们。这将代码稍微更改为:
其余部分保持不变。
Well, I never did get a really good answer for this. I think it might be something funny that happens in the emulator. What I have done that is working great for me, is to download the files to the external SD card and play them from there. That changes the code slightly to this:
the rest remains the same.