Android VideoView黑屏
我一直在寻找一种方法,在start()方法运行之前摆脱VideoView上令人讨厌的黑色初始屏幕。
我已经尝试与小部件上的背景图像,但它并不像预期的那样工作。 我也尝试在VideoView顶部的video中放置第一帧的图像,并在stars()方法之后隐藏它。 添加onPrepared侦听器来启动video,然后隐藏图像。 这种方法很有效,但是在转换中有一个可怕的闪烁,我不知道如何摆脱它。
感谢您的回复。 添加MediaController根本没有效果。 问题依然存在(我仍然看到黑色闪烁),我不想让video控件可见。 我的代码如下所示:
VideoView vSurface= (VideoView) findViewById(R.id.surfaceView1); vSurface.setVideoURI(Uri.parse("android.resource://com.mypackage/" + R.raw.video1)); vSurface.setVisibility(View.VISIBLE); vSurface.setOnPreparedListener(this); vSurface.setDrawingCacheEnabled(true); vSurface.setOnErrorListener(this);
我得到了同样的问题,我find了解决scheme。 它有点hacky,但它伎俩。 所以基本上你需要把你的VideoView放到FrameLayout中。 在video视图中,您需要添加另一个带有video背景的FrameLayout,并且当您的video加载并准备播放时,您可以隐藏占位符。
<FrameLayout android:id="@+id/frameLayout1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="center" android:layout_marginTop="50dip" > <VideoView android:id="@+id/geoloc_anim" android:layout_width="fill_parent" android:layout_height="172dip" android:layout_gravity="top|center" android:visibility="visible"/> <FrameLayout android:id="@+id/placeholder" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/fondvert_anim"> </FrameLayout>
在你的活动中,你需要实现OnPreparedListener并添加这个
//Called when the video is ready to play public void onPrepared(MediaPlayer mp) { View placeholder = (View) findViewById(R.id.placeholder); placeholder.setVisibility(View.GONE); }
所以,当video准备好了,我们隐藏了我们的占位符,这个技巧避免了黑色的闪烁屏幕。
希望这可以帮助别人。
我遇到了同样的问题,并用上面所接受的解决scheme加以解决:
@Override public void onPrepared(MediaPlayer mp) { mp.setOnInfoListener(new MediaPlayer.OnInfoListener() { @Override public boolean onInfo(MediaPlayer mp, int what, int extra) { Log.d(TAG, "onInfo, what = " + what); if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) { // video started; hide the placeholder. placeholder.setVisibility(View.GONE); return true; } return false; } });
我认为onPrepared只是意味着video已经准备好播放,但并不意味着video开始播放。 如果在onPrepared中隐藏占位符,屏幕仍然显示黑屏。
在我的Note3和Nexus上,这个解决scheme运行良好。
我在Galaxy Tab 2,Android 4.1.1上遇到了同样的问题。
做videoView.setZOrderOnTop(true);
和下一个videoView.start()
它对我来说工作正常。
我有同样的问题,这对我工作..
当你想显示video,使videoView.setZOrderOnTop(假); 当你想要隐藏video,只需要videoView.setZOrderOnTop(true);
我有同样的问题,我只是用videov.setBackgroundColor(Color.WHITE),然后onprepare我使用Color.TRANSPARENT)白色仍然比黑色更好
通过扩展一个TextureView,我在开头或结尾都没有黑屏。 这是如果你想避免使用ZOrderOnTop(true)
。
public class MyVideoView extends TextureView implements TextureView.SurfaceTextureListener { private MediaPlayer mMediaPlayer; private Uri mSource; private MediaPlayer.OnCompletionListener mCompletionListener; private boolean isLooping = false; public MyVideoView(Context context) { this(context, null, 0); } public MyVideoView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyVideoView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); setSurfaceTextureListener(this); } public void setSource(Uri source) { mSource = source; } public void setOnCompletionListener(MediaPlayer.OnCompletionListener listener) { mCompletionListener = listener; } public void setLooping(boolean looping) { isLooping = looping; } @Override protected void onDetachedFromWindow() { // release resources on detach if (mMediaPlayer != null) { mMediaPlayer.release(); mMediaPlayer = null; } super.onDetachedFromWindow(); } /* * TextureView.SurfaceTextureListener */ @Override public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) { Surface surface = new Surface(surfaceTexture); try { mMediaPlayer = new MediaPlayer(); mMediaPlayer.setOnCompletionListener(mCompletionListener); mMediaPlayer.setOnBufferingUpdateListener(this); mMediaPlayer.setOnErrorListener(this); mMediaPlayer.setLooping(isLooping); mMediaPlayer.setDataSource(getContext(), mSource); mMediaPlayer.setSurface(surface); mMediaPlayer.prepare(); mMediaPlayer.start(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); mMediaPlayer.reset(); } catch (IOException e) { e.printStackTrace(); } } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {} @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { surface.release(); return true; } @Override public void onSurfaceTextureUpdated(SurfaceTexture surface) {} }
这对我工作:
videoView.setBackgroundColor(Color.WHITE); // Your color. videoView.start(); videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { videoView.setBackgroundColor(Color.TRANSPARENT); } });
至less两年后,但我希望这是有帮助的。
这绝对是不吉利的,但比覆盖图像(IMO)更好。
boolean mRestored = false; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mRestored = savedInstanceState != null; } @Override public void onPrepared(MediaPlayer mp) { if (!mRestored) vSurface.seekTo(1); }
假设你将东西放入onSaveInstanceState
savedInstanceState
中。
只要使用VideoView#setBackgroundDrawable(),我想。
-
初始设置。
VideoView.setBackgroundDrawable(yourdrawableid);
-
开始video
VideoView.start(); VideoView.setBackgroundDrawable(0);
只需从video中显示一帧即可预览。
vSurface.SeekTo(100);
对于仍在寻找答案的人来说,在onPrepared
中连续调用VideoView.start()
和VideoView.pause()
为我工作。 我知道这可能不是实现这一目标的理想方式,但是它可能是代码中所需的最小解决方法之一。 希望这也适用于你。
@Override public void onPrepared(MediaPlayer mp) { mVideoView.start(); mVideoView.pause(); }
这个为我工作:
在XML中:VideoView隐藏在具有白色背景的相对布局之后
<VideoView android:id="@+id/myVideo" android:layout_below="@+id/logo_top" android:layout_width="200dp" android:layout_height="200dp" android:layout_centerHorizontal="true" /> <RelativeLayout android:id="@+id/mask" android:background="#FFFFFF" android:layout_below="@+id/logo_top" android:layout_centerHorizontal="true" android:layout_width="200dp" android:layout_height="200dp" > </RelativeLayout>
并在Activity:onCreate
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.acceuil); myVideo = (VideoView) findViewById(R.id.myVideo); mask = (RelativeLayout) findViewById(R.id.mask); String path = "android.resource://" + getPackageName() + "/" + R.raw.anim_normal; myVideo.setVideoURI(Uri.parse(path)); myVideo.start(); }
onStart:
public void onStart() { final long time = System.currentTimeMillis(); super.onStart(); new CountDownTimer(5000, 100) { @Override public void onTick(long l) { long time2 = System.currentTimeMillis(); if((time2 - time) > 500) { mask.setVisibility(View.GONE); } } }.start();
希望这可以帮助。
这个答案有点晚,但也许其他用户有同样的问题,并find这个问题..
我已经处理了它,通过最初设置一个BackgroundResource,然后,当开始video,我已经把背景设置为一个不可见的颜色..
VideoView myView = findViewById(R.id.my_view); myView.setBackgroundResource(R.drawable.some_resource); // some stuff // this is when starting the video myView.setVideoUri(someUri); // also set MediaController somewhere... //... // now set the backgroundcolor to be not visible (first val of Color.argb(..) is the alpha) myView.setBackGroundColor(Color.argb(0, 0, 0, 0)); //... myView.start();
我更喜欢这个解决scheme: https : //stackoverflow.com/a/11016465/2267723
它的表面,所以创build一个虚拟的@片段布局,你不会再看到这个黑色闪光..
这是一个很好的解决scheme:
package com.example.videoviewpractice; import android.app.Activity; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.MediaController; import android.widget.VideoView; public class MainActivity extends Activity { VideoView myVideoView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initVideo(); } private void initVideo() { myVideoView = (VideoView) findViewById(R.id.videoView1); String url = "http://mtc.cdn.vine.co/r/videos/3DF00EB7001110633055418310656_1e50d6d9a65.3.2.mp4?" + "versionId=KVMUFFGqe6rYRrGKgl8hxL6eakVAErPy"; myVideoView.setVideoURI(Uri.parse(url)); myVideoView.setMediaController(new MediaController(this)); myVideoView.requestFocus(); } public void gone(View v){ myVideoView.setZOrderOnTop(true); View placeholder = (View) findViewById(R.id.placeholder); placeholder.setVisibility(View.GONE); myVideoView.start(); } }
activity_main.xml中:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/LinearLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="${relativePackage}.${activityClass}" > <FrameLayout android:id="@+id/frameLayout1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="center" android:layout_marginTop="50dip" > <VideoView android:id="@+id/videoView1" android:layout_width="300dp" android:layout_height="300dp" android:layout_gravity="top|center" android:visibility="visible" /> <FrameLayout android:id="@+id/placeholder" android:layout_width="300dp" android:layout_height="300dp" android:layout_gravity="top|center" android:background="@drawable/ic_launcher" android:onClick="gone" > </FrameLayout> </FrameLayout> </LinearLayout>
为了避免恼人的闪烁和黑屏问题,我写了FrameVideoView 。
它从TextureView
获取“占位符解决scheme”和(如果您的设备运行API级别14或更高)的TextureView
,它比VideoView
更有效率。
我在我们的博客上写了一篇文章来介绍它实际上做了什么。
使用起来很简单:
将FrameVideoView
添加到布局:
<mateuszklimek.framevideoview.FrameVideoView android:id="@+id/frame_video_view" android:layout_width="@dimen/video_width" android:layout_height="@dimen/video_height" />
在Activity
find它的实例并在onResume
和onPause
调用相应的方法:
public class SampleActivity extends Activity { private FrameVideoView videoView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.simple); String uriString = "android.resource://" + getPackageName() + "/" + R.raw.movie; videoView = (FrameVideoView) findViewById(R.id.frame_video_view); videoView.setup(Uri.parse(uriString), Color.GREEN); } @Override protected void onResume() { super.onResume(); videoView.onResume(); } @Override protected void onPause() { videoView.onPause(); super.onPause(); } }
使用svVideoView.seekTo(位置) 。
在5(ms)内给位置。
onPause(): position=svVideoView.getCurrentPosition() onResume(): svVideoView.seekTo(position);
以上都没有为我工作。 在我的情况下, onPrepared
被调用之前,黑框消失,所以我仍然会看到黑框。
我需要一个解决scheme,在第一帧之后不久出现video。
所以我所做的是将VideoView alpha设置为0:
android:alpha="0"
然后在我开始video之前,我将alpha设置回1:
videoView.animate().alpha(1); videoView.seekTo(0); videoView.start();
或者,您可以发布一个延迟的Runnable来将alpha设置为1,而不是将其设置为animation。
我遇到过同样的问题。 我发现主要原因是使用FrameLayout
作为父级布局。 使用RelativeLayout
作为VideoView
的父级布局
看到这个
VideoView videoView = (VideoView) findViewById(R.id.VideoView); MediaController mediaController = new MediaController(this); mediaController.setAnchorView(videoView); Uri video = Uri.parse("android.resource://your_package_name/"+R.raw.monkeysonthebed_video); videoView.setMediaController(mediaController); videoView.setVideoURI(video); videoView.start();
- ADT 22.3(android 4.4) – 获取错误“场景创build后,#init()必须被称为”
- Android在列表上滑动
- 自定义列表视图上的选定项目与上下文操作栏
- Android的textview大纲文本
- Android和设置(图片)视图alpha的alpha
- java.util.zip.ZipException:在packageAllDebugClassesForMultiDex期间重复条目
- 有没有回购你可以下载Android的虚拟设备?
- J2ME / Android /黑莓 – 行车路线,两地之间的路线
- 如何解决getActionBar方法可能会产生java.lang.NullPointerException