我有一个带视频视图的应用程序,它正在播放内部存储(我的包< code >文件目录)中的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
我曾经遇到过类似的问题,当我在回调时遇到错误时,我通过重新加载活动来克服它。起初它工作,但后来它一直失败,这导致了活动的无限重启循环。然后我决定在这种情况下放一张图片而不是视频(这真的不是那么重要)。
我想这值得一试...如果您没有得到对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);
}
我可以建议的另一种方法-使用编解码器。我知道它在其他设备上运行良好,但您永远无法知道此特定设备的编解码器是否具有bug。也尝试更改其尺寸。
祝你好运:)
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);
用这个来运行你的视频,我相信你的问题会得到解决。
既然您已经声明重新启动活动有时是可行的,我敢打赌这是一个多线程事件触发器,通常发生在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;
}
这将实现的是,如果您的视频在“活动”准备好开始播放之前加载,您的听众只需将布尔标志设置为TRUE,然后onResume()将看到该标志已设置并开始播放视频。如果在视频加载完成之前调用onResume(),那么它只需设置标志,此时听众就会看到它并开始播放视频。这样,在“活动”准备就绪之前,您的视频不会开始播放,希望它可以防止您看到的这种奇怪行为。