web-dev-qa-db-ja.com

Android VideoView黒い画面

私は、start()メソッドが実行される前にVideoViewの厄介な黒い初期画面を取り除く方法を探していました。

ウィジェットで背景画像を試しましたが、期待どおりに機能しません。また、ビデオの最初のフレームの画像をVideoViewの上に配置し、stars()メソッドの後に非表示にしてみました。 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);
50
SergioM

私は同じ問題を抱え、解決策を見つけました。その少しハックが、トリックを行います。したがって、基本的にはVideoViewをFrameLayoutに配置する必要があります。 videoviewの上に、ビデオの背景を持つ別の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);
}

そのため、ビデオの準備ができたら、プレースホルダーを非表示にし、そのトリックが黒いちらつき画面を回避します。

これが誰かを助けることを願っています。

36
M to the K

私は同じ問題に出会い、上記の受け入れられた解決策とこれで解決します:

  @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では、このソリューションはうまく機能します。

49
wizardlee

Galaxyタブ2でも同じ問題が発生しましたAndroid 4.1.1。

videoView.setZOrderOnTop(true);と次のvideoView.start()を実行します

それは私のためにうまく機能します。

40
jc_35

私は同じ問題を抱えており、これは私のために働いています..

ビデオを表示する場合は、videoView.setZOrderOnTop(false);を作成します。また、ビデオを非表示にする場合は、videoView.setZOrderOnTop(true);を作成します。

26
Ravi Bhojani

私はちょうど私がvideov.setBackgroundColor(Color.WHITE)を使用し、次にColor.TRANSPARENTを使用して準備したのと同じ問題を抱えています

21

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) {}
}
17
Carl B

これは私のために働いた:

videoView.setBackgroundColor(Color.WHITE); // Your color.
videoView.start();
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        videoView.setBackgroundColor(Color.TRANSPARENT);
    }
});

少なくとも2年後ですが、それが役に立てば幸いです。

9
emmgfx

これは間違いなくハックですが、画像をオーバーレイする(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);
}

savedInstanceStateonSaveInstanceStateに物を入れていると仮定します。

4
Paul Burke

上記のどれも私にとってはうまくいきませんでした。私の場合、onPreparedは、黒のフレームがなくなる前に呼び出されるため、黒のフレームが表示されます。

最初のフレームの直後にビデオが表示されるソリューションが必要でした。

だから、私はxmlでVideoViewアルファを0に設定しました:

Android:alpha="0"

そして、ビデオを開始する前に、アルファを1に戻します。

videoView.animate().alpha(1);
videoView.seekTo(0);
videoView.start();

または、遅延Runnableをポストして、アルファをアニメートする代わりに1に設定することもできます。

4
Siavash

これは私のために働く:

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

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

お役に立てれば。

2
Ramza

まだこれに対する答えを探している人々のために、onPrepared内でVideoView.start()VideoView.pause()を連続して呼び出すことは私のために働いた。私はこれがこれを達成する理想的な方法ではないかもしれないことを知っていますが、コードで必要な回避策が最小限であるかもしれません。これがあなたにも役立つことを願っています。

@Override
public void onPrepared(MediaPlayer mp) {
    mVideoView.start();
    mVideoView.pause();
}
2
Gagan

VideoView#setBackgroundDrawable()を使用するだけです。

  1. 初期設定。

    VideoView.setBackgroundDrawable(yourdrawableid);
    
  2. ビデオを開始

    VideoView.start();
    VideoView.setBackgroundDrawable(0);
    
2
Takeaki Kubota

ビデオのフレームをプレビューとして表示するだけです。

vSurface.SeekTo(100);
2
j7nn7k

アクティビティとフラグメントの両方で機能します。

VideoView mVideo = (VideoView) findViewById(R.id.yourViewViewId);
          mVideo.setVideoURI(mUri);
          mVideo.setZOrderOnTop(false);

SurfaceHolder surfaceholder = mVideo.getHolder();
surfaceholder.setFormat(PixelFormat.TRANSPARENT);
1
Nam lê đình

同じ問題がありました。その主な理由は、親レイアウトとしてFrameLayoutを使用していることにあります。 RelativeLayoutの親レイアウトとしてVideoViewを使用します

0
Vinil Chandran

@emmgfxの答えを修正することでうまくいきました:

videoView.setBackgroundColor(Color.WHITE)
videoView.start()
Timer().schedule(100){
  videoView?.setBackgroundColor(Color.TRANSPARENT)
}

トリックは、ビデオがロードされるまでビデオ表示を遅らせることです。 PS:それはkotlinです。

0
Fawaz

私はこのソリューションを好むでしょう: https://stackoverflow.com/a/11016465/226772

その表面については、ダミーの@fragmentレイアウトを作成すると、この黒いフラッシュが再び表示されることはありません..

0
Maher Abuthraa

svVideoView.seekTo(position)を使用します。

5(ms)以内に位置を与えます。

onPause():
position=svVideoView.getCurrentPosition()

onResume():
svVideoView.seekTo(position);
0
Raj

この回答には少し遅れていますが、他のユーザーにも同じ問題があり、この質問を見つける可能性があります。

最初にBackgroundResourceを設定し、その後ビデオを開始するときに、背景を不可視の色に設定し、対処しました。

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();
0
MalaKa

迷惑なちらつきや黒い画面の問題を避けるために、私は FrameVideoView と書きました。

「プレースホルダーソリューション」と(デバイスがAPIレベル14以上を実行している場合)TextureViewからメリットを享受します。これはVideoViewよりもはるかに効率的です。

ブログで article と書いて、実際に何をするのかを説明しました。

使い方は簡単です:

レイアウトにFrameVideoViewを追加します。

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

Activityでインスタンスを見つけ、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();
    }
  }
0
klimat

これは素晴らしい解決策です:

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>
0
OShiffer