英文:
Android MediaPlayer unexpectedly stops playback (without being finalized)
问题
我刚刚偶然发现了一个问题,涉及到它那并不那么明显的解决方案,我想如果我分享一下我的发现,可能会对一些人有所帮助。
虽然有很多类似的问题,但它们没有帮助我解决我的问题(是不同的)。
我有一个活动,它播放带声音的视频,然后显示一张图像持续3秒,然后显示一个动画地图视图持续10秒,然后再播放另一个视频。
- 视频1(约60秒)
- 图像(约3秒)
- 动画地图视图(约10秒)
- 视频2(约30秒)
问题出现在试图从第一个视频结束的时刻开始播放音频时。
音频在地图视图的持续时间内正常播放,然后停止了。
我尝试了各种情况,但音乐总是在某些改变时停止播放,尽管某些组合是有效的(例如,没有地图和视频2(仅为空黑屏))。
我确实仔细查看了所有日志,但没有找到任何有用的信息。
问题不是由于媒体播放器在完成前被垃圾收集或终止。
private static MediaPlayer mediaplayer;
在OnCreate方法中:
mediaplayer = new MediaPlayer();
AudioFocusRequest.Builder mp;
mediaplayer.setAudioAttributes(
new AudioAttributes
.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build());
try {
mediaplayer.setDataSource(getApplicationContext(), Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.audio));
} catch (IOException e) {
e.printStackTrace();
Log.e("audio_management","error trying to set data source for audio");
}
try {
mediaplayer.prepare();
} catch (IOException e) {
e.printStackTrace();
Log.e("audio_management","error preparing");
}
这是播放视频的示例:
z.schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
playPart2();
}
});
}
}, PARTONELENGTH + MAPDISPLAYTIME + IMAGEDISPLAYTIME);
这是playPart2()函数:
public void playPart2() {
ImageView imgbg = findViewById(R.id.imageView);
ImageView agO = findViewById(R.id.agent1);
ImageView agTw = findViewById(R.id.agent2);
ImageView agTh = findViewById(R.id.agent3);
ImageView agFo = findViewById(R.id.agent4);
ImageView agFi = findViewById(R.id.agent5);
ImageView agSi = findViewById(R.id.agent6);
VideoView player = findViewById(R.id.videoView);
MapView mMap = findViewById(R.id.map);
mMap.setVisibility(View.INVISIBLE);
imgbg.setVisibility(View.INVISIBLE);
agO.setVisibility(View.INVISIBLE);
agTw.setVisibility(View.INVISIBLE);
agTh.setVisibility(View.INVISIBLE);
agFo.setVisibility(View.INVISIBLE);
agFi.setVisibility(View.INVISIBLE);
agSi.setVisibility(View.INVISIBLE);
player.setVisibility(View.VISIBLE);
Uri uri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.part2);
player.setVideoURI(uri);
player.start();
}
我真的不知道发生了什么 - 我已经阅读了有关MediaPlayer和VideoViews的所有文档。文档说可以同时输出2个音频流。但实际上不起作用。
英文:
I just stumbled across problem with it's this not-so-obvious solution and thought it might be helpful to some if I share my findings.
There are lots of similar questions but they didn't help me solve mine. (are different)
I have a activity that plays a video with sound, then displays an image for 3 seconds, then displays an animated mapview for 10 seconds and then plays another video.
- video1 (~60sec)
- image (~3sec)
- animated mapview (~10sec)
- video2 (~30sec)
the arose when trying to play audio from the moment the first video finished.
the audio played fine for the duration of the mapview, then stopped.
I tried all sorts of scenarios but the music always stopped when something changed, although some combinations worked (e.g. without map and video2 (just blackscreen instead)).
I did take a very close look at all the logs but didnt find anything helpful.
The issue is not that the mediaplayer is being gc'd or finalized somehow before finishing.
private static MediaPlayer mediaplayer;
and in OnCreate:
mediaplayer = new MediaPlayer();
AudioFocusRequest.Builder mp;
mediaplayer.setAudioAttributes(
new AudioAttributes
.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build());
try {
mediaplayer.setDataSource(getApplicationContext(), Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.audio));
} catch (IOException e) {
e.printStackTrace();
Log.e("audio_management","error trying to set data source for audio");
}
try {
mediaplayer.prepare();
} catch (IOException e) {
e.printStackTrace();
Log.e("audio_management","error preparing");
}
Here's an example of how I play the videos
z.schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
playPart2();
}
});
}
}, PARTONELENGTH + MAPDISPLAYTIME + IMAGEDISPLAYTIME);
and this is the playPart2() function:
public void playPart2() {
ImageView imgbg = findViewById(R.id.imageView);
ImageView agO = findViewById(R.id.agent1);
ImageView agTw = findViewById(R.id.agent2);
ImageView agTh = findViewById(R.id.agent3);
ImageView agFo = findViewById(R.id.agent4);
ImageView agFi = findViewById(R.id.agent5);
ImageView agSi = findViewById(R.id.agent6);
VideoView player = findViewById(R.id.videoView);
MapView mMap = findViewById(R.id.map);
mMap.setVisibility(View.INVISIBLE);
imgbg.setVisibility(View.INVISIBLE);
agO.setVisibility(View.INVISIBLE);
agTw.setVisibility(View.INVISIBLE);
agTh.setVisibility(View.INVISIBLE);
agFo.setVisibility(View.INVISIBLE);
agFi.setVisibility(View.INVISIBLE);
agSi.setVisibility(View.INVISIBLE);
player.setVisibility(View.VISIBLE);
Uri uri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.part2);
player.setVideoURI(uri);
player.start();
}
I really dont know what is going on - I 've read through all the documentation concerning MediaPlayer and VideoViews. It says that it is possible to output 2 streams of audio at the same time. But it doesnt work.
答案1
得分: 0
原来是视频播放开始后,VideoView 的播放有些方式会暂停 MediaPlayer 的播放。
解决问题的方法只是再次调用 mediaplayer.start()。它会从之前停止的位置继续播放,之前所有的时间都有。
(显然存在的)播放中的短暂中断是不可察觉的。
为什么这个 MediaPlayer/VideoView 的行为没有在任何地方提到?
问题解决代码:
z.schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
playPart2();
mediaplayer.start();
}
});
}
}, PARTONELENGTH + MAPDISPLAYTIME + IMAGEDISPLAYTIME);
英文:
turns out the videoView starting playback somehow paused the mediaplayer.
what solved the problem was just calling mediaplayer.start() again. it did resume where it had stopped all the times before. the (apparently existing) short break in playback is not noticeable.
why is this behaviour of mediaplayer/videoview not mentioned anywhere?
issue-solving-code:
z.schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
playPart2();
mediaplayer.start();
}
});
}
}, PARTONELENGTH + MAPDISPLAYTIME + IMAGEDISPLAYTIME);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论