Android VideoView黑屏
我一直在寻找一种方法,在运行Android VideoView黑屏,android,flicker,android-videoview,Android,Flicker,Android Videoview,我一直在寻找一种方法,在运行start()方法之前,消除VideoView上令人讨厌的黑色初始屏幕 我已经尝试过在小部件上使用背景图像,但它根本没有按预期工作。 我还尝试将视频中第一帧的图像放在VideoView的顶部,并在start()方法之后隐藏它。 添加onPrepared侦听器以启动视频,然后隐藏图像。这是可行的,但在转换过程中出现了可怕的闪烁,我不知道如何消除它 添加MediaController没有任何效果。问题依然存在(我仍然看到黑色闪烁),我根本不想让视频控件可见。 我的代码如
start()
方法之前,消除VideoView上令人讨厌的黑色初始屏幕
我已经尝试过在小部件上使用背景图像,但它根本没有按预期工作。
我还尝试将视频中第一帧的图像放在VideoView的顶部,并在start()
方法之后隐藏它。
添加onPrepared侦听器以启动视频,然后隐藏图像。这是可行的,但在转换过程中出现了可怕的闪烁,我不知道如何消除它
添加MediaController没有任何效果。问题依然存在(我仍然看到黑色闪烁),我根本不想让视频控件可见。 我的代码如下所示:
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);
看到这个了吗
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();
我遇到了同样的问题,我找到了解决办法。这有点老套,但确实很管用。 所以基本上你需要把你的视频视图放到一个框架布局中。 在视频视图上,您需要添加另一个带有视频背景的框架布局,当您的视频加载并准备播放时,您可以隐藏占位符
<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>
因此,当视频准备好时,我们隐藏占位符,这样可以避免黑色闪烁屏幕
希望这能帮助到别人。我也遇到过同样的问题,这对我来说很有效
当你想显示视频时,使videoView.setZOrderOnTop(false);当你想隐藏视频时,只需设置videoView.setZOrderOnTop(true) 现在回答这个问题有点晚了,但也许其他用户也有同样的问题,并找到了这个问题
我已经处理过了,首先设置了背景资源,然后在开始视频时,我将背景设置为不可见的颜色
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();
这无疑是一个骇客,但比叠加图像(IMO)要好
假设你把东西放到saveInstanceState的
savedInstanceState
中,我也遇到了同样的问题,我刚刚用了videov.setBackgroundColor(Color.WHITE),然后用了prepare,我用了Color.TRANSPARENT)白色对我来说仍然比黑色好我在Galaxy tab 2,Android 4.1.1上也遇到了同样的问题
DovideoView.setZOrderOnTop(true)代码>和下一步videoView.start()
它对我来说很好。通过扩展TextureView,我在开始或结束时都不会出现黑屏。如果您希望避免使用ZOrderOnTop(true)
,则可以使用此选项
我想,只要使用VideoView#setBackgroundDrawable()
初始设置
VideoView.setBackgroundDrawable(yourdrawableid);
开始视频
VideoView.start();
VideoView.setBackgroundDrawable(0);
这对我很有用:
videoView.setBackgroundColor(Color.WHITE); // Your color.
videoView.start();
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
videoView.setBackgroundColor(Color.TRANSPARENT);
}
});
videoView.setBackgroundColor(Color.WHITE)
videoView.start()
Timer().schedule(100){
videoView?.setBackgroundColor(Color.TRANSPARENT)
}
至少两年后,但我希望这会有所帮助。这是一个很好的解决方案:
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();
}
}
<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>
活动\u main.xml:
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();
}
}
<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>
使用svVideoView.seekTo(位置)
在5(ms)内给出位置
我遇到了同样的问题,并用上述公认的解决方案加上:
@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只是意味着视频已经准备好播放,但并不意味着视频已经开始播放。如果在onPrepared中隐藏占位符,屏幕仍显示黑屏
在我的Note3和Nexus上,此解决方案运行良好。只需将视频中的一帧显示为预览
vSurface.SeekTo(100);
为了避免令人讨厌的闪烁和黑屏问题,我写了一篇文章
它从“占位符解决方案”和TextureView
中(如果您的设备运行的是API级别14或更高)中获益,后者比VideoView
效率更高
我在我们的博客上写下了它的实际功能
使用简单:
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();
}
}
<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
添加到布局:
<mateuszklimek.framevideoview.FrameVideoView
android:id="@+id/frame_video_view"
android:layout_width="@dimen/video_width"
android:layout_height="@dimen/video_height"
/>
对于仍在寻找答案的人来说,在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>
启动:
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();
希望这对我有帮助。以上这些都不适合我。
在我的例子中,onPrepared
在黑框消失之前被调用,所以我仍然可以看到黑框
我需要一个解决方案,视频在第一帧后不久出现
因此,我在xml中将VideoView alpha设置为0:
android:alpha="0"
然后在开始视频之前,我将alpha设置为1:
videoView.animate().alpha(1);
videoView.seekTo(0);
videoView.start();
或者,您可以发布一个延迟的Runnable,将alpha设置为1,而不是设置动画 我也有同样的问题。我发现这样做的主要原因是使用FrameLayout
作为父布局。使用RelativeLayout
作为VideoView
的父布局,它对我的活动和片段都有效
VideoView mVideo = (VideoView) findViewById(R.id.yourViewViewId);
mVideo.setVideoURI(mUri);
mVideo.setZOrderOnTop(false);
SurfaceHolder surfaceholder = mVideo.getHolder();
surfaceholder.setFormat(PixelFormat.TRANSPARENT);
修改@emmgfx的答案对我很有用:
videoView.setBackgroundColor(Color.WHITE); // Your color.
videoView.start();
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
videoView.setBackgroundColor(Color.TRANSPARENT);
}
});
videoView.setBackgroundColor(Color.WHITE)
videoView.start()
Timer().schedule(100){
videoView?.setBackgroundColor(Color.TRANSPARENT)
}
诀窍是延迟视频查看直到加载视频。
PS:我是kotlin。对我来说,在播放mp4视频时设置setZOrderOnTop
并没有完全删除初始黑框。然而,它确实缩短了黑框出现的时间。我想完全删除最初的黑色帧,所以我四处玩,发现将视频向前搜索100毫秒对我来说是个好办法
请注意,我正在循环使用视频,因此如果您不想循环视频,请删除
mp.isLooping=true
以下是我用来解决此问题的代码段:
val path = "android.resource://" + packageName + "/" + R.raw.my_video
videoView.setVideoURI(Uri.parse(path))
videoView.setZOrderOnTop(true)
videoView.seekTo(100)
videoView.start()
videoView.setOnPreparedListener { mp ->
videoView.setZOrderOnTop(false)
mp.isLooping = true // Loops the video
}
如果有人认为上面的方法有用,我能得到一个确切的解释,说明为什么它会起作用,那就太好了。我找到了解决这个问题的好办法。(科特林)
在视频视图上方创建图像视图。
使用处理程序创建函数,并检查(videoview.duration>0)
如果持续时间大于零,则将imageview.visibility设置为不可见,然后立即
val handler = Handler()
handler.postDelayed(object : Runnable {
override fun run() {
try {
if (videoplayer_topthree.currentPosition > 0) {
videoview_topthreeloadingimage.visibility = View.INVISIBLE
videoview_topthreeprogressbar.visibility = View.VISIBLE
videoview_topthreefullname.visibility = View.VISIBLE
videoview_topthreeviews.visibility = View.VISIBLE
videoview_topthreedate.visibility = View.VISIBLE
videoview_topthreedescription.visibility = View.VISIBLE
videoview_topthreedimview.visibility = View.VISIBLE
handler.removeCallbacks(this)
}
handler.postDelayed(this, 250)
} catch (e: Exception) {
println("SHOW VIDEOVIEW CATCH WAS CAUGHT")
}
}
}, 0)
}
prepareSizing(it)
initializeProgressBar()
showVideoView()
}