安卓VideoView出现错误(1,16)并显示黑屏

5

我有一个应用程序,其中包含一个VideoView,在内部存储(我的包的“files”目录)中播放mp4文件。

在某些三星Epic Touch 4g(Galaxy SII)设备上,视频不会显示,屏幕完全是黑色的。我的应用程序中的其他所有内容都表现正常并正常响应,因此设备并未“冻结”,只是屏幕上仅显示黑色而不是视频。

为了启动我的视频,我使用onPreparedListener回调来调用start():

mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer arg0) {
        mVideoView.start();
    }
});

我使用以下代码调用播放视频:

//file is the reference to my video File object. 
//I am positive that it is correct
mVideoView.setVideoPath(file.getAbsolutePath());

我已经设置了一个 onErrorListener,就像这样:

mVideoView.setOnErrorListener(new OnErrorListener(){
    @Override
    public boolean onError(MediaPlayer arg0, int arg1, int arg2) {  
        Log.i(myTag, "MP ERROR: "+ arg1 + " - " + arg2);
        /* I have also tried this here, no luck this way either
        mVideoView.setVideoPath(file.getAbsolutePath());
        return true;
        */
        return false;
    }       
});

仔细检查后,我意识到我的onErrorListener根本没有接收到回调。

当屏幕变黑时,日志一遍又一遍地被这些消息刷屏:

V/PlayerDriver(2579): HandleInformationalEvent: PVMFInfoProcessingFailure
V/PlayerDriver(2579): HandleInformationalEvent: type=16 UNHANDLED
E/MFC_DEC_APP(2579): SsbSipMfcDecExe] IOCTL_MFC_DEC_EXE failed(ret : -2001)
E/PVMFOMXVideoDecNode(2579): Ln 1652 OMX_EventError nData1 -2147479541 nData2 0

有时候,下面这两行会与以上4行的垃圾邮件一起混杂在一起。但是其他时候,在以上4行垃圾邮件的几次迭代后,这两行会单独被垃圾邮件攻击。

W/MediaPlayer(30537): info/warning (1, 16)
I/MediaPlayer(30537): Info (1,16)

我不认为我的视频出现编码问题(AVC MP4),因为完全相同的视频在一些Epic Touch 4g设备上运行良好(甚至在同一版本的操作系统上也是如此)。而且我以前在这个设备上使用了完全相同的视频,但是当该设备升级到2.3.6版本的操作系统时,就开始出现这些问题了。
有没有人能解释一下我看到的OMX/MFC错误?或者其他人是否遇到过VideoView仅显示黑屏而不是视频的问题?最后,还有其他方法可以启动准备/播放视频文件,以避免出现这些错误和黑屏?
编辑:我在这个文件中发现警告#16是:
/*
Notification that a processing failure occurred (not fatal error)
*/
const PVMFStatus PVMFInfoProcessingFailure = 16;

这应该是一个非致命性错误。我想这不是崩溃,所以它不是“致命”的,但无论发生了什么,都导致我的视频无法正确显示。

编辑2:在视频开始播放时从设备中获得更多日志。这些日志都在上面的日志垃圾邮件之前:

D/PowerManagerService(2677): acquireWakeLock flags=0xa tag=KEEP_SCREEN_ON_FLAG uid=1000 pid=2677   myUID=1000 myPID=2677 myTID=23672
I/ALSAModule(2579): Initialized ALSA PLAYBACK device hifi
W/AudioFlinger(2579): write blocked for 99 msecs, 318 delayed writes, thread 0x61a00
I/libfimc(2677): bool SecFimc::create(SecFimc::FIMC_DEV, fimc_overlay_mode, unsigned int):: Fimc reserved memory =0x57da0000
E/Surface(6585): Surface::init token -2 identity 3401
E/action=%s(2677): com.android.music.musicservicecommand
D/AudioService(2677): musicservicecommand
E/MediaPlayer-JNI(6585): setDataSource: outside path in JNI is ?x@
I/WindowManager(2677):   CREATE SURFACE Surface(name=SurfaceView, identity=3401, mNativeSurface=0) IN SESSION android.view.SurfaceSession@40825e90: pid=6585 format=4 flags=0x200 / Window{40bbc478 SurfaceView paused=false}
D/MediaPlayerService(2579): getPlayerType. Ln=935
D/MediaPlayerService(2579): createPlayer. type=1
D/MediaPlayerService(2579):  create PVPlayer
V/PlayerDriver(2579): PVSuspensionState struct constructor
V/PVPlayer(2579): PVPlayer constructor
V/PVPlayer(2579): construct PlayerDriver
V/PlayerDriver(2579): constructor
V/PlayerDriver(2579): OpenCore hardware module not found
V/PlayerDriver(2579): start player thread
V/PlayerDriver(2579): startPlayerThread
V/PlayerDriver(2579): InitializeForThread
V/PlayerDriver(2579): OMX_MasterInit
V/PlayerDriver(2579): OsclScheduler::Init
V/PlayerDriver(2579): CreatePlayer
D/(2579): SISO TEST registering PVMFRecognizerPluginFactory
D/(2579): SISO TEST registering PVMFRecognizerPluginFactory success
V/PlayerDriver(2579): AddToScheduler
V/PlayerDriver(2579): PendForExec
V/PlayerDriver(2579): OsclActiveScheduler::Current
V/PlayerDriver(2579): StartScheduler
V/PVPlayer(2579): send PLAYER_SETUP
V/PlayerDriver(2579): Send player code: 2
V/PlayerDriver(2579): CommandCompleted
V/PlayerDriver(2579): Completed command PLAYER_SETUP status=PVMFSuccess
V/PVPlayer(2579): setVideoSurface(0x46b0d0)
V/PVPlayer(2579): setVideoSurface(0x2d8cd0)
V/PVPlayer(2579): prepareAsync
D/ViewRoot(3990): handleAppVisibility:TN_USA_U1_SPR
V/PlayerDriver(2579): Send player code: 3
V/PlayerDriver(2579): handleSetDataSource
V/PlayerDriver(2579): handleSetDataSource- scanning for extension
V/PlayerDriver(2579): CommandCompleted
V/PlayerDriver(2579): Completed command PLAYER_SET_DATA_SOURCE status=PVMFSuccess
V/PVPlayer(2579): run_init s=0, cancelled=0
V/PlayerDriver(2579): Send player code: 6
V/PlayerDriver(2579): release string is 2.3.6 len 5
V/PlayerDriver(2579): HandleInformationalEvent: PVMFInfoDurationAvailable
V/PlayerDriver(2579): .... with duration = 168483 ms
V/PlayerDriver(2579): CommandCompleted
V/PlayerDriver(2579): Completed command PLAYER_INIT status=PVMFSuccess
V/PlayerDriver(2579): dongju PlayerCommand::PLAYER_INIT enter
V/PlayerDriver(2579): File EXT is : .mp4
E/PlayerDriver(2579): PlayerDriver::it is a not Protected file
V/PlayerDriver(2579): PlayerCommand::PLAYER_INIT exit
V/PVPlayer(2579): run_set_video_surface s=0, cancelled=0
V/PlayerDriver(2579): Send player code: 4
W/PlayerDriver(2579): Using generic video MIO
V/PlayerDriver(2579): CommandCompleted
V/PlayerDriver(2579): Completed command PLAYER_SET_VIDEO_SURFACE status=PVMFSuccess
V/PVPlayer(2579): run_set_audio_output s=0, cancelled=0
V/PlayerDriver(2579): Send player code: 5
V/PlayerDriver(2579): Create realtime output
V/PlayerDriver(2579): CommandCompleted
V/PlayerDriver(2579): Completed command PLAYER_SET_AUDIO_SINK status=PVMFSuccess
V/PVPlayer(2579): run_prepare s=0, cancelled=0
V/PlayerDriver(2579): Send player code: 7
V/PlayerDriver(2579): disable natpkt - 0
I/MFC_DEC_APP(2579): [SsbSipMfcDecOpen] MFC Library Ver 1.00
I/MFC_DEC_APP(2579): [SsbSipMfcDecOpen] handle(61) 
V/PlayerDriver(2579): HandleInformationalEvent: UNKNOWN PVMFStatus
V/PlayerDriver(2579): HandleInformationalEvent: type=44 UNHANDLED
W/MediaPlayer(6585): info/warning (1, 44)
I/MediaPlayer(6585): Info (1,44)
V/PlayerDriver(2579): CommandCompleted
V/PlayerDriver(2579): Completed command PLAYER_PREPARE status=PVMFSuccess
V/PlayerDriver(2579): PLAYER_PREPARE complete mDownloadContextData=0x0, mDataReadyReceived=0
D/MediaPlayer(6585): getMetadata
V/PVPlayer(2579): setLooping(0)
V/PVPlayer(2579): check_for_live_streaming s=0, cancelled=0
V/PlayerDriver(2579): Send player code: 12
V/PVPlayer(2579): setLooping(0)
V/PlayerDriver(2579): Send player code: 12
E/PVPlayer(2579): isDrmfile playing 0
E/PVPlayer(2579): OPLBlocked = 0
E/MediaPlayerService(2579): MediaPlayerService::mIsAnyDrmVideoPlaying : 0
E/MediaPlayerService(2579): MediaPlayerService::mpCheckOPLBlocked : 0
V/PVPlayer(2579): start
E/AudioPolicyManager(2579): getParamFromPolicy
D/AudioPolicyManager(2579): mCurDevice is 2
V/AudioPolicyManager(2579): getDeviceForStrategy() strategy 0, device 2
V/AudioPolicyManager(2579): getNewDevice() selected device 2
I/FmRadioController(2677): Jni player_SetVolume :7 
I/FmRadioController(2677): ---Jni player_SetVolume---
V/PlayerDriver(2579): Send player code: 8
V/PlayerDriver(2579): dongju handleStart
E/PlayerDriver(2579): PlayerDriver::handleTvOut state=[1]
E/PlayerDriver(2579): PlayerDriver::it is not a DRM file.So don't suspend TVOUT
V/PlayerDriver(2579): CommandCompleted
V/PlayerDriver(2579): Completed command PLAYER_START status=PVMFSuccess

重新安装应用程序对于出现此问题的设备有任何影响吗?我想知道视频文件是否在内部存储中损坏或类似的情况。 - Joe
1
如果有帮助的话,我怀疑错误信息是由这个SsbSipMfcDecAPI.c文件中的第231行产生的。根据其头文件,代码-2001似乎指定了MFC_RET_DEC_EXE_TIME_OUT。不过没有修复的想法 :) - Joe
我尝试过的每个MP4文件都出现了这种情况(大约有六个),所有这些文件在旧操作系统上的同一设备上都可以工作,并且在某些相同操作系统的同一设备实例上也可以工作。 - FoamyGuy
如果唯一的更改是升级到2.3.6,可能是由于权限问题。请确保您拥有所有所需的权限。 - Sunny Kumar Aditya
如果您还没有查看,那么在播放成功和播放失败的日志消息之间有没有明显的区别(当然除了所有错误)? - blahdiblah
显示剩余5条评论
3个回答

4
我曾经遇到过类似的问题,当我的回调出现错误时,我通过重新加载活动来解决它。起初它起作用,但后来它一直失败,导致活动无限重启循环。然后我决定在这种情况下放置图片而不是视频(它确实不是那么重要)。
我想值得一试......如果您没有收到任何onErrorListener的回调,请在活动存活5秒钟后运行它,以测试是否解决了您的问题。
以下是我编写的重新加载活动的代码:
public void reload(String boolExtra) {
    Intent intent = getIntent();
    overridePendingTransition(0, 0);
    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    finish();

    overridePendingTransition(0, 0);
    startActivity(intent);
}

我可以提供另一种方法-尝试更改编解码器。我知道它在其他设备上运行良好,但您永远不知道此特定设备使用的编解码器(带有此特定Android版本)是否存在错误。也可以尝试更改其尺寸。

祝你好运 :)


它可以在运行相同操作系统版本的同一设备的其他实例上运行。我尝试过调整视频编码,但没有成功 =/ - FoamyGuy
重新启动活动有时似乎会有所帮助。但我不能将其作为永久解决方案。 - FoamyGuy
您可以考虑在活动“开始”几秒钟后启动视频。使用postDelayed(Runnable, Delay)将可运行的内容发布到Handle中。这个可运行的内容将负责启动视频。从较长的延迟(10秒)开始,然后进行调整,直到找到最佳位置。它并不完美,但它会解决大多数情况。 - Udinic

1
File filepath = new File(Environment.getExternalStorageDirectory()+"/Video/"+"abc_video.mp4");

Uri path = Uri.fromFile(filepath);

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(path, "video/*");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

使用这个来运行你的视频,我相信你的问题会得到解决。

我需要视频在我的Activity中播放,当视频正在播放时还有其他事情发生。 - FoamyGuy
这将播放视频,当视频停止并按下返回按钮时,您将返回到您的活动。此代码仅将视频重定向到视频播放器以播放视频。 - user1550860
我知道,但我的应用程序在视频播放时正在执行其他任务,因此我需要它在我的Activity中播放。 - FoamyGuy

0

既然您已经说过重新启动活动有时会起作用,我敢打赌这是一个多线程事件触发器,通常在您的onPrepared()监听器触发之前发生,但在导致问题的特定手机情况下并不总是如此。我无法确定您实际上何时准备播放视频,但我猜测它是在onCreate()中进行的。如果是这样,我建议尝试以下机制:

在您的Activity类中,创建一个布尔成员,如下所示:

protected boolean bMyVideoIsReady = false;

一旦你拥有了那个,修改你的监听器:

    mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer arg0) {
            if (MyActivity.this.bMyVideoIsReady)
                mVideoView.start();
            else
                MyActivity.this.bMyVideoIsReady = true;
        }
    });

一旦这些修改完成,请在您的活动的onResume()方法中添加以下内容:

@Override
protected void onResume() {
    super.onResume();
    if (bMyVideoIsReady) 
        mVideoView.start();
    else
        bMyVideoIsReady = true;
}

这样做的作用是,如果您的视频在 Activity 准备好播放之前加载,您的监听器将简单地将布尔标志设置为 TRUE,然后 onResume() 将看到标志已设置并开始播放您的视频。如果 onResume() 在视频加载完成之前被调用,则它将简单地设置标志,现在您的监听器将看到它并在那时开始播放视频。这样,您的视频不会在 Activity 准备好之前开始播放,希望能防止您正在观察的奇怪行为。

但是我该如何强制视频视图准备好视频? - touti

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接