黑屏

我一直在寻找一种方法,以摆脱讨厌的黑色初始屏幕上的一个视频观看之前的 start()方法运行。

我试过在小部件上使用背景图片,但它根本不能像预期的那样工作。 我还尝试把视频中第一帧的图像放在 VideoView 的顶部,然后用 start()方法隐藏它。 添加一个 onPreready 侦听器以启动视频,然后隐藏图像。这个工作,但有一个可怕的闪烁在过渡,我不知道如何摆脱它。


添加 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);
78873 次浏览

看这个

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,当您的视频加载并准备播放时,您需要隐藏占位符。

<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 View.setZOrderOnTop (假) ; 当你想隐藏视频时,只需设置 video View.setZOrderOnTop (真) ;

现在回答这个问题有点晚了,但是也许其他用户也有同样的问题,并且发现了这个问题。

I have dealt with it, by setting a BackgroundResource initially and then, when starting the video, i have set the background to an invisible color..

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)更好。

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

我也遇到了同样的问题,我刚刚使用了 Videov.setBackoundColor (Color.WHITE) ,然后在准备阶段我使用了 Color.TRANSPARENT)白色对我来说仍然比黑色好

我在 Galaxy tab 2,Android 4.1.1上也遇到了同样的问题。

videoView.setZOrderOnTop(true);和下一个 videoView.start()

我觉得挺好的。

通过扩展 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 # setBackoundDrawable () ,我想。

  1. 初始设置。

    VideoView.setBackgroundDrawable(yourdrawableid);
    
  2. start video

    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);
}
});

至少两年后,但我希望这能有所帮助。

这是一个不错的解决方案:

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>

使用 SekTo (position)

在5(毫秒)内给定位置。

onPause():
position=svVideoView.getCurrentPosition()


onResume():
svVideoView.seekTo(position);

我遇到了同样的问题,并用上述公认的解决方案加上以下内容解决了它:

  @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;
}
});

我认为在预备只是意味着视频准备播放,但不意味着视频开始播放。如果将占位符隐藏在 onPreready 中,屏幕仍然显示黑色屏幕。

在我的 Note3和 Nexus 上,这个解决方案运行良好。

只要展示视频中的一帧作为预览。

vSurface.SeekTo(100);

为了避免恼人的闪烁和黑屏问题,我写了 < strong > FrameVideoView

它从“占位符解决方案”和(如果您的设备运行的是 API 级别14或更高)从 TextureView中获益,后者比 VideoView高效得多。< br/> < br/> 我在我们的博客上写了 文章来报道它的实际功能。

使用起来很简单:

在布局中添加 FrameVideoView:

<mateuszklimek.framevideoview.FrameVideoView
android:id="@+id/frame_video_view"
android:layout_width="@dimen/video_width"
android:layout_height="@dimen/video_height"
/>

Activity中找到它的实例并在 onResumeonPause中调用相应的方法:

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();
}
}

对于仍然在寻找答案的人来说,在 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>

以及活动: 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();
}

开始:

 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"

然后在我开始录像之前,我把阿尔法变回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)
videoView.start()
Timer().schedule(100){
videoView?.setBackgroundColor(Color.TRANSPARENT)
}

技巧是延迟视频观看,直到视频加载。 附言: 是 Kotlin。

对于我设置的 setZOrderOnTop没有完全删除最初的黑色框架,而播放 MP4视频。然而,它确实缩短了黑框出现的时间。我想删除最初的黑色框架完全,所以我发现寻找视频向前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
}

如果有人认为它有帮助的话,那么如果我能得到一个确切的解释为什么上述方法有效的话,那就太好了。

我找到了一个解决这个问题的好办法。(在 Kotlin)

在你的视频视图上方创建一个图像视图。 使用一个处理程序创建一个函数,并检查它是否(viewview.duration> 0)

如果持续时间大于零,那么将 imageview.ability 设置为 INVISABLE,然后立即使用 handler.RemoveCallback (this)

在调用 video view.start 之后调用上面的函数

密码如下:

()(只提供英文版本)

    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)


}

这就是我调用这个函数的地方。

视频播放器 _ topthree. setOnPreparedListener {

        prepareSizing(it)
initializeProgressBar()
showVideoView()
        

}

试图在一个大部分是白色的布局上播放一个大部分是白色的视频会以一种非常明显和恼人的方式显示这些小故障,特别是在活动过渡期间。我完全摆脱这些小故障的唯一方法是将这个帖子中的几个不同的答案和厄普尔在 https://stackoverflow.com/a/9089245/3997253中的答案混合在一起。

创建覆盖 VideoView 的纯色视图

<View
android:id="@+id/coverView"
android:background="@color/white"
android:layout_width="match_parent"
android:layout_height="match_parent" />

在 onCreate 中

...
coverView = findViewById(R.id.coverView)
videoView = findViewById(R.id.videoView)


videoView.setZOrderOnTop(false)
val surfaceHolder = videoView.holder
surfaceHolder.setFormat(PixelFormat.TRANSPARENT)

开始

...
videoView.setOnPreparedListener { mp ->
// Fade out cover View to show VideoView once rendering has started
mp.setOnInfoListener { _, what, _ ->
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
coverView.animate().alpha(0F)
return@setOnInfoListener true
}
return@setOnInfoListener false
}
mp.isLooping = true
videoView.start()
videoView.requestFocus()
}

完成视频浏览后

// Fade in cover View to hide the VideoView
coverView.animate().alpha(1F)