2015-01-15 6 views
4

Я заинтересован в возможности «буфера записи» VideoView в то время как VideoView B играет. Это возможно?Как VideoView А буфера записи, а другой VideoView B играет - Android

  • У меня есть два экземпляра VideoView.
  • В течение определенного времени будет отображаться только один VideoView, который охватывает весь экран телефона.
  • Цель состоит в том, чтобы уменьшить «черный экран» при переключении с VideoView A и VideoView B.
  • Приложение воспроизводит список видео один за другим.

Добавлен код ниже 19 янв 2015

ниже код захватывает ссылку на MediaPlayer каждого игрока. Когда MediaPlayer A начнет рендеринг, MediaPlayer B вызовет stop(), release(), setDataSource (url), prepareAsync(). Когда MediaPlayer A будет завершен, Media Player B вызовет start().

public class PrebufferingActivity extends Activity { 
    private VideoView player1; 
    private VideoView player2; 
    private MediaPlayer mediaPlayer1; 
    private MediaPlayer mediaPlayer2; 
    public static final String URL_1 = "sample1.mp4"; 
    public static final String URL_2 = "sample2.mp4"; 

    public boolean FIRST_TIME = true; 

    @SuppressLint("NewApi") 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_prebuffering); 

     player1 = (VideoView) findViewById(R.id.videoPlayer1); 
     player2 = (VideoView) findViewById(R.id.videoPlayer2); 

     player1.setOnTouchListener(new OnTouchListener(){ 

      @Override 
      public boolean onTouch(View v, MotionEvent event) { 
       // TODO Auto-generated method stub 
       return false; 
      } 

     }); 

     player2.setOnTouchListener(new OnTouchListener(){ 

      @Override 
      public boolean onTouch(View v, MotionEvent event) { 
       // TODO Auto-generated method stub 
       return false; 
      } 
     }); 
     player1.setOnCompletionListener(new OnCompletionListener(){ 
      @Override 
      public void onCompletion(MediaPlayer mp)   { 
       mediaPlayer2.start(); 

       // Toggle visibility. Player1 is completed. Hide Player1. Show Player2. 
       player2.setVisibility(View.VISIBLE); 
       player1.setVisibility(View.INVISIBLE); 
      } 
     }); 

     player1.setOnInfoListener(new OnInfoListener(){ 
      @Override 
      public boolean onInfo(MediaPlayer mp, int what, int extra) 
      { 
       if(what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) 
       { 
        mediaPlayer2.stop(); 
        mediaPlayer2.release(); 

        try { 
         mediaPlayer2.setDataSource(URL_2); 
         mediaPlayer2.prepareAsync(); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
       } 
       return false; 
      } 
     }); 

     player1.setOnPreparedListener(new OnPreparedListener(){ 
      @Override 
      public void onPrepared(MediaPlayer mp)   { 
       mediaPlayer1 = mp; 

       if(FIRST_TIME == true) { 
        mediaPlayer1.start(); 
        player1.requestFocus(); 
        FIRST_TIME = false; 
       } 
      } 
     }); 

     player2.setOnCompletionListener(new OnCompletionListener(){ 

      @Override 
      public void onCompletion(MediaPlayer mp)   { 
       mediaPlayer1.start(); 
       player1.requestFocus(); 

       // Toggle visibility. Player2 is completed. Hide Player2. Show Player1. 
       player1.setVisibility(View.VISIBLE); 
       player2.setVisibility(View.INVISIBLE); 
      } 
     }); 

     player2.setOnInfoListener(new OnInfoListener(){ 
      @Override 
      public boolean onInfo(MediaPlayer mp, int what, int extra) 
      { 
       if(what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) 
       { 
        // Prepare Player 2 
        mediaPlayer1.stop(); 
        mediaPlayer1.release(); 
        try { 
         mediaPlayer1.setDataSource(PrebufferingActivity.URL_1); 
         mediaPlayer1.prepareAsync(); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
       } 

       return false; 
      } 
     }); 

     player2.setOnPreparedListener(new OnPreparedListener(){ 
      @Override 
      public void onPrepared(MediaPlayer mp) { 
       mediaPlayer2 = mp; 
      } 
     }); 

     // Player 1 
     player1.setMediaController(new MediaController(this)); 
     player1.setVideoURI(Uri.parse(URL_1)); 

     // Player 2 
     player2.setMediaController(new MediaController(this)); 
     player2.setVideoURI(Uri.parse(URL_2)); 
    } 

ответ

3

Предполагая, что вы используете MediaPlayer для обработки воспроизведения видео в вашем VideoView, вы можете использовать метод prepareAsync() для того чтобы достигнуть этого. Метод prepareAsync() по существу выполняет ту же функцию, что и prepare(), которая используется для буферизации и подготовки видео, за исключением того, что она может выполняться асинхронно в фоновом режиме.

EDIT

я сделал что-то похож, но я использовал SurfaceView. Чтобы обрабатывать другой поток, просто создайте еще один экземпляр MediaPlayer. В следующем примере будут созданы два экземпляра MediaPlayer и буферизация первого видео. После того, как будет подготовлено первое видео, второе видео будет асинхронно буферизировано. Первый MediaPlayer затем привязан к SurfaceView и запускается первое видео. Когда первое видео завершено, появляется соответствующий экземпляр MediaPlayer, дополнительный экземпляр подключен, и второе видео автоматически запускается. Следующий примерный код был протестирован и отлично работает:

public class StreamingActivity extends Activity implements SurfaceHolder.Callback, MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener 
{ 

    MediaPlayer  mediaPlayerPrimary; 
    MediaPlayer  mediaPlayerSecondary; 
    SurfaceHolder surfaceHolder; 
    SurfaceView  surfaceView; 
    String   videoSourcePrimary = "videoSourcePrimaryURL"; 
    String   videoSourceSecondary = "videoSourceSecondaryURL"; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.streaming_activity_layout); 
     /** Create SurfaceView */ 
     surfaceView = (SurfaceView) findViewById(R.id.surface_view); 
     surfaceHolder = surfaceView.getHolder(); 
     surfaceHolder.addCallback(this); 
    } 

    @Override 
    public void surfaceCreated(SurfaceHolder arg0) 
    { 
     try 
     { 
      /** Create MediaPlayer(s) */ 
      mediaPlayerPrimary = new MediaPlayer(); 
      mediaPlayerSecondary = new MediaPlayer(); 
      /** Attach primary MediaPlayer to SurfaceView */ 
      mediaPlayerPrimary.setDisplay(surfaceHolder); 
      /** Set sources */ 
      mediaPlayerPrimary.setDataSource(videoSourcePrimary); 
      mediaPlayerSecondary.setDataSource(videoSourceSecondary); 
      /** Prepare MediaPlayer(s) */ 
      mediaPlayerPrimary.prepare(); 
      mediaPlayerSecondary.prepareAsync(); 
      /** Set listeners */ 
      mediaPlayerPrimary.setOnPreparedListener(this); 
      mediaPlayerPrimary.setOnCompletionListener(this); 
      mediaPlayerSecondary.setOnPreparedListener(this); 
      mediaPlayerSecondary.setOnCompletionListener(this); 
      /** Set audio stream type */ 
      mediaPlayerPrimary.setAudioStreamType(AudioManager.STREAM_MUSIC); 
      mediaPlayerSecondary.setAudioStreamType(AudioManager.STREAM_MUSIC); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) 
    { 
    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder arg0) 
    { 
    } 

    @Override 
    public void onPrepared(MediaPlayer mp) 
    { 
     if (mp == mediaPlayerPrimary) 
     { 
      /** First video ready, start playback */ 
      mediaPlayerPrimary.start(); 
     } 
     else if (mp == mediaPlayerSecondary) 
     { 
      /** Second video is ready */ 
     } 
    } 

    @Override 
    public void onCompletion(MediaPlayer mp) 
    { 
     /** First video is completed, start second video */ 
     mediaPlayerPrimary.release(); 
     mediaPlayerSecondary.setDisplay(surfaceHolder); 
     mediaPlayerSecondary.start(); 

    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) 
    { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.streaming_activity_menu, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) 
    { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 

     //noinspection SimplifiableIfStatement 
     if (id == R.id.action_settings) 
     { 
      return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 
} 
+0

Спасибо, Уиллис. Вы случайно знаете, как получить объект MediaPlayer из объекта VideoView? Кажется, что-то не похоже на getMediaPlayer() ... – codeshark

+0

Кроме того, скажем, я хочу изменить URL-адрес на VideoView A перед вызовом prepareAsync() в его объекте MediaPlayer. Должен ли я сделать следующее: videoViewA.stopPlayback(); videoViewA.setVideoURI (Uri.parse (URL)); . VideoViewA.getMediaPlayer() prepareAsync(); – codeshark

+0

См. Обновленный ответ ... – Willis