问题描述
我的目标是向用户显示9帧已录制的视频,以便他可以选择其中之一.
所以我要做的是一个活动来录制视频,并将视频中的URI发送到另一个活动,该活动将显示该录制的视频中的9帧.
So what i did was make an activity to record the video and send the URI from the video to another activity that will show 9 frames from that recorded video.
界面中有9个VideoView,每个视频都通过一次seekTo进行更改,该值由此变量计算得出:
There're 9 VideoViews in the interface each one being change with a seekTo with value calculated by this variable:
video_frames_to_jump = (mediaPlayer.getDuration() - MILISECONDS_TO_JUMP)/10;
换句话说,我将视频分为10段,从视频开头开始使用MILISECONDS_TO_JUMP.
In other words, i divided the video in 10 pieces, with MILISECONDS_TO_JUMP from the beginning of the video.
此后,我使用 onPrepared
方法中的 mediaPlayer.seekTo(video_seek);
中的seekTo在不同的时间启动每个VideoView.
After that i use the seekTo from mediaPlayer.seekTo(video_seek);
in the method onPrepared
to start each of the VideoViews in a different time.
完整代码如下:
// Activity OnCreated
OnCreated(){
// preparing the Video file for the VideoView
video_file_string = getIntent().getStringExtra("video_file");
video_file = new File(video_file_string);
Uri videoUri = Uri.fromFile(video_file);
// Using OnPrepared so we can use the mediaPlayer.getDuration() and to avoid further problems
MediaPlayer.OnPreparedListener onpreparedlistener = new MediaPlayer.OnPreparedListener() {
// Make some important initialization explained above to calculate video_frames_to_jump and
// video_seek
videoseek_initialization();
// here i update the variable, so the next video will seekTo a later point in the video
video_seek = (video_seek > mediaPlayer.getDuration())?
(mediaPlayer.getDuration()-1) : (video_seek+video_frames_to_jump);
mediaPlayer.seekTo(video_seek);
Log.v(TAG, "FramesSelection VideoSeek(" + video_seek + ") MaxDuration(" +mediaPlayer.getDuration() +")");
// the two lines below was me trying to fix the black screen error, but it didn't work
// some people said that playing and pause the video would update the VideoView and fix the
// black screen
mediaPlayer.start();
mediaPlayer.pause();
}
// here i'm initializing the videoviews
VideoView video_view1 = (VideoView) this.findViewById(R.id.video_view1);
VideoView video_view2 = (VideoView) this.findViewById(R.id.video_view2);
...
VideoView video_view8 = (VideoView) this.findViewById(R.id.video_view8);
VideoView video_view9 = (VideoView) this.findViewById(R.id.video_view9);
video_view1.setVideoURI(videoUri);
video_view1.setZOrderOnTop(false);
// The line above was a possible fix for the black screen, i changed it to true/false but
// when false - nothing changes and my problem continues.
// when true - the issue continues but instead of black screen, i got a white screen
video_view1.setOnPreparedListener(onpreparedlistener);
video_view2.setVideoURI(videoUri);
video_view2.setZOrderOnTop(false);
video_view2.setOnPreparedListener(onpreparedlistener);
...
video_view8.setVideoURI(videoUri);
video_view8.setZOrderOnTop(false);
video_view8.setOnPreparedListener(onpreparedlistener);
video_view9.setVideoURI(videoUri);
video_view9.setZOrderOnTop(false);
video_view9.setOnPreparedListener(onpreparedlistener);
}
应用程序的日志显示,我正在计算所需的正确毫秒数.
The log from the application shows that i'm calculating the correct miliseconds that i wanted.
例如,在每帧之间跳跃256毫秒,并在视频中跳跃前10帧,结果是:
For example with a jump of 256 miliseconds between frames and jumping the first 10 frames in the video the result was:
myapplication: FramesSelection VideoSeek(266) MaxDuration(2576)
myapplication: FramesSelection VideoSeek(522) MaxDuration(2576)
myapplication: FramesSelection VideoSeek(778) MaxDuration(2576)
myapplication: FramesSelection VideoSeek(1034) MaxDuration(2576)
myapplication: FramesSelection VideoSeek(1290) MaxDuration(2576)
myapplication: FramesSelection VideoSeek(1546) MaxDuration(2576)
myapplication: FramesSelection VideoSeek(1802) MaxDuration(2576)
myapplication: FramesSelection VideoSeek(2058) MaxDuration(2576)
myapplication: FramesSelection VideoSeek(2314) MaxDuration(2576)
请注意,我不是在播放视频,只是在VideoView中显示了固定的图像"或帧".
所以问题在于某些VideoView随机显示黑屏.
例如,有时第一个VideoView(video_view1)显示来自录制视频的图像,有时不显示.所有其他VideoView也会发生同样的情况,有时它们可以正常工作,有时却无法正常工作.
For example, sometimes the first VideoView (video_view1)show a image from the recorded video and sometimes don't. The same happens with all the other VideoViews, sometimes they work correctly, sometimes don't.
所以我的问题是:为什么显示黑屏,我在做什么错,我该如何解决?
我已经搜索了问题,并且在上面的代码中显示了一些解决此问题的尝试.问题在大多数时候都会发生.至少有3个VideoView显示黑屏.
I already search for the problem and some of the tries to fix it i showed in the code above. The problems happens most of the times. At least 3 VideoViews are showing black screens.
下图显示了一个示例...感谢您的帮助!抱歉,很长的描述
The following image shows an example... Thanks for any help! Sorry for long description
推荐答案
好吧,我找不到黑屏的原因,但是由于我只需要显示图像(而不是视频),所以我找到了解决方案问题,我将在这里发布.
Well i couldn't find the reason of the black screens, however since i just need to show a image (not a video) i found a solution to my problem, which i'll post here.
我没有使用VideoViews,而是将它们更改为ImageViews,并使用MediaMetadataRetriever提供的图像.
Instead of using VideoViews i changed them to ImageViews and use the images provided by MediaMetadataRetriever.
我的代码
// Lines below are to find the video duration and to initialize the MediaMetadataRetriever
MediaMetadataRetriever mediaMetadataretriever = new MediaMetadataRetriever();
mediaMetadataretriever.setDataSource(video_file_string);
// getting video duration
String time = mediaMetadataretriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
final int timeInMillisec = Integer.parseInt(time);
// again finding the frames to jump between frames
video_frames_to_jump = (timeInMillisec - MILISECONDS_TO_JUMP)/10;
video_seek = MILISECONDS_TO_JUMP;
Bitmap[] bmFrame = new Bitmap[NUMBER_OF_IMAGEVIEW];
ImageView[] img_view = new ImageView[NUMBER_OF_IMAGEVIEW];
// get imageview components
img_view[0] = this.findViewById(R.id.image_view1);
img_view[1] = this.findViewById(R.id.image_view2);
...
img_view[7] = this.findViewById(R.id.image_view8);
img_view[8] = this.findViewById(R.id.image_view9);
for(int i = 0; i < bmFrame.length; i++) {
// calculating the video frames that i want
video_seek = (video_seek >= timeInMillisec) ? (timeInMillisec - 1) : (video_seek + video_frames_to_jump);
// setting a frame image to ImageView
bmFrame[i] = mediaMetadataretriever.getFrameAtTime(video_seek * 1000); // time MUST be in MICROseconds
img_view[i].setImageBitmap(bmFrame[i]);
}
// Release the mediaMetadataretriever
mediaMetadataretriever.release();
这篇关于在Android中将seekTo与MediaPlayer一起使用时出现黑屏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!