java Android MediaPlayer - 有时即使播放音频也不播放视频
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7509818/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android MediaPlayer - Sometimes No Video is Played Even Though Audio Plays
提问by speedplane
I am developing an Android App and I'm using the Android SDK's MediaPlayer
to play some videos in my app. When I play the video in my app, about one out of five times, the audio plays without video. It's not a simple coding error because most of the time the video plays perfectly.
我正在开发一个 Android 应用程序,我正在使用 Android SDKMediaPlayer
在我的应用程序中播放一些视频。当我在我的应用程序中播放视频时,大约五分之一的时间,音频在没有视频的情况下播放。这不是一个简单的编码错误,因为大部分时间视频都能完美播放。
I have considered that a race condition in my code caused the bug. However, I added a number of debug statements and everything seems to be set up properly when the video does not play.
我认为我的代码中的竞争条件导致了该错误。但是,我添加了许多调试语句,当视频无法播放时,一切似乎都设置正确。
I have scanned the web and SO trying to find solutions but none have been adequate (see below).
我已经浏览了网络并试图找到解决方案,但没有一个是足够的(见下文)。
Has anyone run into this type of problem before? If so, what did you do?
有没有人遇到过这种类型的问题?如果是这样,你做了什么?
Similar Questions:
类似问题:
android media player shows audio but no video
android video, hear sound but no video
Some More Details:
更多细节:
- I've come across this bug on two phones. On a Samsung Charge video plays 80% of the time and 20% of the time there's audio but no video. On a T-Mobile Comet it's much worse; video only plays about 10% of the time.
- It's not a problem with the file, I've tried various video files and codecs and get the same issues.
- It's not a problem with the storage medium. I've tried playing the video when it was stored on internal storage and the sdcard, neither makes a difference. I have even tried reading some of the file before playing it, hoping that the system will cache it, but that doesn't seem to help either.
- 我在两部手机上遇到过这个错误。在三星 Charge 视频上,80% 的时间播放视频,20% 的时间有音频但没有视频。在 T-Mobile Comet 上,情况要糟糕得多;视频仅播放约 10% 的时间。
- 这不是文件的问题,我尝试了各种视频文件和编解码器并遇到了相同的问题。
- 这不是存储介质的问题。当视频存储在内部存储器和 SD 卡上时,我尝试播放视频,两者都没有区别。我什至尝试在播放之前阅读一些文件,希望系统能够缓存它,但这似乎也无济于事。
Update:
更新:
I've been debugging this and looking through logcat. I've found that when the video works, something like the following appears in logcat:
我一直在调试这个并查看logcat。我发现当视频有效时,logcat 中会出现类似以下内容:
09-28 00:09:03.651: VERBOSE/PVPlayer(10875): setVideoSurface(0x65638)
But when video doesn't play, it looks like there's a null entry:
但是当视频不播放时,它看起来像一个空条目:
09-28 00:03:35.284: VERBOSE/PVPlayer(10875): setVideoSurface(0x0)
Update 2:
更新 2:
When the video fails to play, the function MediaPlayer.OnInfoListener with parameters what==MEDIA_ERROR_UNKNOWN(0x1)
and extra==35
. I looked through the Android code-base to try to determine what unknown error 35 means. I came across the file pv_player_interface.h, which indicates that error code 35 corresponds to something called a PVMFInfoTrackDisable
. I googled that term which brought me to a file called pvmf_return_codes.pdf
. That file gave me the following unintelligible explanation:
当视频无法播放时,函数 MediaPlayer.OnInfoListener 带有参数 what==MEDIA_ERROR_UNKNOWN(0x1)
和extra==35
. 我查看了 Android 代码库以尝试确定未知错误 35 的含义。我遇到了文件 pv_player_interface.h,它表明错误代码 35 对应于一个叫做PVMFInfoTrackDisable
. 我用谷歌搜索了这个词,它把我带到了一个名为 pvmf_return_codes.pdf
. 该文件给了我以下难以理解的解释:
4.34. PVMFInfoTrackDisable
Notification that paticular track is disable. This one is on a per track basis. For uncompressed audio/video formats, during the process of selecting tracks available in content, if the decoder doesn't support the track, a PVMFInfoTrackDisable event is sent. The event, if necessary, will be sent once per track.
4.34. PVMFInfoTrackDisable
特定轨道已禁用的通知。这是基于每个轨道的。对于未压缩的音频/视频格式,在选择内容中可用轨道的过程中,如果解码器不支持该轨道,则会发送 PVMFInfoTrackDisable 事件。如有必要,事件将在每个轨道上发送一次。
I feel like I've gone a long way, but am no closer to finding an answer... still investigating.
我觉得我已经走了很长一段路,但离找到答案还很远……仍在调查中。
采纳答案by speedplane
I solved the problem, albeit in a totally hackish way. There are two problems actually:
我解决了这个问题,尽管以一种完全黑客的方式。其实有两个问题:
The Evil Info 35 Message:I found that occasionally MediaPlayer.OnInfoListener will get called with extra==35. When this happens, you're screwed and the video will not play properly. I have no idea what causes it. The only fix I found was to try restarting the video and going through the whole prepareAsync process over again. Video playback usually works the second time.
Video Size Not Set:Even after MediaPlayer.OnPreparedListener gets issued (or equivalently prepare() returns) the video size may not be been set. The video size will usually be set a couple of miliseconds after prepare returns, but for a few moments it is in a nebulous state. If you call MediaPlayer.start() before the video size is set, then playback will sometimes (but not always) fail. There are two potential solutions to this: (1) poll MediaPlayer.getVideoHeight() or getVideoWidth() until they're non-zero or (2) wait until OnVideoSizeChangedListener is called. Only after one of these two events, should you call start().
Evil Info 35 消息:我发现偶尔 MediaPlayer.OnInfoListener 会被调用为 extra==35。发生这种情况时,您就搞砸了,视频将无法正常播放。我不知道是什么原因造成的。我找到的唯一解决方法是尝试重新启动视频并重新执行整个 prepareAsync 过程。视频播放通常会进行第二次。
未设置视频大小:即使在 MediaPlayer.OnPreparedListener 发出(或等效地准备()返回)之后,也可能未设置视频大小。视频大小通常会在准备返回后的几毫秒内设置,但有一段时间它处于模糊状态。如果在设置视频大小之前调用 MediaPlayer.start(),则播放有时(但并非总是)会失败。对此有两种可能的解决方案:(1) 轮询 MediaPlayer.getVideoHeight() 或 getVideoWidth() 直到它们不为零或 (2) 等到 OnVideoSizeChangedListener 被调用。只有在这两个事件之一之后,才应该调用 start()。
With these two fixes, video playback is much more consistent. It's very likely that these problems are bugs with my phones (Samsung Charge and a T-Mobile Comet) so I won't be surprised if there are different, but similar problems on other phones.
通过这两个修复,视频播放更加一致。这些问题很可能是我的手机(Samsung Charge 和 T-Mobile Comet)的错误,所以如果其他手机上存在不同但类似的问题,我不会感到惊讶。
回答by cdavidyoung
Following speedplane's suggestions I came up with the following code. If the MediaPlayer.getVideoHeight() returns 0 in onPrepared then I delay for 1 second and try again. Now if it does not play the first time it usually will play 1 second later. I have seen it take several tries though.
按照 speedplane 的建议,我想出了以下代码。如果 MediaPlayer.getVideoHeight() 在 onPrepared 中返回 0,则我延迟 1 秒并重试。现在,如果它第一次不播放,它通常会在 1 秒后播放。我已经看到它需要多次尝试。
private void videoPlayer(String path){
if (mMediaController == null)
{
mMediaController = new MediaController(this);
mVideoView.setMediaController(mMediaController);
}
if (!mMediaController.isShowing())
mMediaController.show();
getWindow().setFormat(PixelFormat.TRANSLUCENT);
mVideoView.setVideoPath(path);
mVideoView.requestFocus();
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(final MediaPlayer mp) {
mVideoView.seekTo(mImageSeek);
if (mp.getVideoHeight() == 0) {
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
mVideoView.stopPlayback();
mMediaController = null;
videoPlayer(mImageFilepath);
}
}, 1000);
} else
mVideoView.start();
}
});
}
回答by A.Quiroga
I have been studying this bug 2 weeks , and i have understand more or less the real problem . Of course i'm talking about The Evil Info 35 Message. If you have met this wonderfull strange error , now you can be happy and shot some vendors like samsung :D ...
我已经研究这个错误 2 周了,我或多或少地了解了真正的问题。当然,我说的是The Evil Info 35 Message。如果您遇到了这个奇妙的奇怪错误,现在您可以高兴地射击一些像三星这样的供应商:D ...
The problem comes cause the surface view can't be seen by the user (activity in tabhost or pause-wakeup function , not in focus sometimes , not in front sometimes too (maybe)).
问题来了,因为用户无法看到表面视图(tabhost 中的活动或暂停唤醒功能,有时不聚焦,有时也不在前面(可能))。
That's cause when some reset that video it runs ok , cause it gains focus or maybe another activity/object is not overlapping it.
这是因为当某些人重置该视频时,它运行正常,导致它获得焦点,或者另一个活动/对象可能没有与它重叠。
When some of those happen , the mediaplayer thinks you can't see the video or it can't play , and it disable video track, giving you the worst headache in your worklife while listening the music track.
当其中一些发生时,媒体播放器认为您看不到视频或无法播放,并禁用视频轨道,让您在听音乐轨道的同时工作生活中最头疼。
Will see next bug , good luck . :D
会看到下一个错误,祝你好运。:D
回答by safari
I had that problem too on my Desire HD about 1 or 2 times. I tried many things but the error was allways there. Afterall i choosed to install a custom rom on my device. Afterwards it worked perfectly and I never had a this issue again.
我在我的 Desire HD 上也遇到过这个问题大约 1 到 2 次。我尝试了很多东西,但错误始终存在。毕竟我选择在我的设备上安装自定义 rom。之后它工作得很好,我再也没有遇到过这个问题。
I know its not that kind of answer you'd like to hear but i didn't find an other soultions.
我知道这不是您想听到的那种答案,但我没有找到其他答案。
Here you find custom roms for your device: XDA Developers
在这里您可以找到适合您设备的自定义 rom:XDA 开发人员
I hope I could help you out.
我希望我能帮到你。
Best Regards and Happy Movie watching
最好的问候和快乐的电影观看
safari =)
野生动物园 =)
回答by yichouangle
The fundamental question is: before surfaceCreated invoked you start video playback, when the holder is not ready for MediaPlayer, so that you only hear the sound but can not see the picture!
最根本的问题是:在surfaceCreated调用之前你开始播放视频,当持有者没有准备好MediaPlayer的时候,让你只听到声音看不到画面!
The right way is:
正确的方法是: