2015-10-22 16 views
8

Jedes Mal, wenn ich meine Aktivität pausiere (eigentlich Fragment), um zu einer anderen App zu gehen, versuche ich mit onResume das Video wiederzugeben, aber es wird nicht abgespielt Bildschirm. Bei der Untersuchung, sehe ich die folgend in der LogcatBufferQueue wurde aufgegeben: Bei der Wiedergabe von Video mit TextureView

E/BufferQueueProducer: [unnamed-23827-0] queueBuffer: BufferQueue has been abandoned 
E/MediaPlayer: error (1, -38) 
E/MediaPlayer: error (1, -38) 
E/MediaPlayer: error (1, -38) 
E/MediaPlayer: error (1, -38) 
E/BufferQueueProducer: [unnamed-23827-0] connect(P): BufferQueue has been abandoned 

Hier ist der Code, den ich innen rufen Lebenslauf

player.seekTo(mVideoSeekPosition); 
player.start(); 

Zur Info: Ich habe diese Antwort auf meinen Fall anzuwenden versucht, aber ich kann ‚t: What can I do when the BufferQueue has been abandoned?

UPDATE

ich kämpfte um es allein zu gehen, aber ich bin immer noch abstürzt. So bin Entsendung ich den ganzen Code für Hilfe

private void setupVideoPlayingSystem(View root) { 
    textureView = (TextureView) root.findViewById(R.id.textureView);
  
    textureView.setSurfaceTextureListener(this); 
}
 
 
  

@Override 
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) { 
    Log.d(TAG, "onSurfaceTextureAvailable"); 
    if (null == surface) { 
    Log.d(TAG, "new surface"); 
    surface = new Surface(surfaceTexture); 
    mediaPlayer = new MediaPlayer(); 
    mediaPlayer.setSurface(surface); 
    mediaPlayer.setLooping(false); 
    }
  
    /*
  
    outstandingVideoRequest is IOU for orentation change (verifed: onResume before onSurfaceTextureAvailable) 
    but for cold startup, must check mVideoUrl 
    */
  
    if (outstandingVideoRequest && null != mVideoUrl) {
  
    outstandingVideoRequest = false; 

  playNewVideo(mVideoUrl); 
    }
  
}
 
  

@Override
  
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
  
    Log.d(TAG, "onSurfaceTextureSizeChanged"); 

 }
 
  

@Override 

 public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
  
    Log.d(TAG, "onSurfaceTextureDestroyed"); 
    return false;//leave destruction for onDestroy
  
} 

@Override 
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
  }
  

    private void playNewVideo(String url) {
   
     if (null == mediaPlayer || null == surface) {
   
     Log.d(TAG, "playNewVideo not ready"); 
    
   synchronized (outstandingVideoRequest) { 
    
    Log.d(TAG, "playNewVideo outstandingVideoRequest"); 
    
    outstandingVideoRequest = true; 
     }
   
     } else {
   
     try {
   
      mediaPlayer.reset();
   
      mediaPlayer.setDataSource(getContext(), Uri.parse(url));
   
      mediaPlayer.setLooping(false);
   
      mediaPlayer.prepareAsync();
   
      mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { 

      @Override
   
      public void onPrepared(MediaPlayer player) {
   
       Log.d(TAG, "onPrepared changeMediaPlayerDatasource");
   
       onReadyToPlay(player); 
      }
   
      });
   
     } catch (Exception e) {//IOException && IllegalStateException
   
     Log.d(TAG, "textureview playNewVideo ERORR");
   
     e.printStackTrace();
   
     }
  
   
    }
   
    } 

    private void resumeVideoUponReturningFromAnotherActivity() { 

   if (null == mediaPlayer || null == surface) { 

    Log.d(TAG, "resumeVideoUponReturningFromAnotherActivity outstandingVideoRequest"); 

    outstandingVideoRequest = true;
  
     } else {
  
//   playNewVideo(mVideoUrl); 

    Log.d(TAG, "resumeVideoUponReturningFromAnotherActivity go NOW"); 

    mediaPlayer.setSurface(surface);
  
      onReadyToPlay(mediaPlayer); 

   }
 
  
    }
 
  

    private void onReadyToPlay(MediaPlayer player) {
  
     //play video
  
     mProgressCircle.setVisibility(View.GONE); 

   showVideoOverlayChildren();
  
     if (0 == mVideoSeekPosition) {
  
      Log.d(TAG, "onReadyToPlay start"); 

    player.start(); 

   } else {
  
      Log.d(TAG, "onReadyToPlay seek"); 

    player.seekTo(mVideoSeekPosition);
  
      player.start(); 

   }
  
     mHandler.postDelayed(new Runnable() { 

    @Override 

    public void run() { 

     Log.d(TAG, "postDelayed resumeVideo");
  
       hideVideoOverlayChildren(); 

    }
  
     }, Constant.BEFORE_VIDEO_OVERLAY_DISAPPEAR); 

  } 


 
  private void destroyMediaPlayer() { 

   if (null != mediaPlayer) {//move to video todo
  
      mediaPlayer.stop(); 

    mediaPlayer.release();
  
      mediaPlayer = null; 

   }
  
     if (null != surface) { 

    surface.release(); 

    surface = null;
  
     }
  
    }
 
  

    private void pauseVideo() { 

   if (null != mediaPlayer) { 

    Log.d(TAG, "pause");
  
      mediaPlayer.pause(); 

    mVideoSeekPosition = mediaPlayer.getCurrentPosition(); 

   }
  
    } 


 
  private void stopVideo(){
  
     if (null != mediaPlayer) { 

    Log.d(TAG, "stop video"); 

    mediaPlayer.pause(); 

    mVideoSeekPosition = mediaPlayer.getCurrentPosition(); 

    mediaPlayer.stop(); 

   }
  
    } 

@Override
 public void onResume() { 

  super.onResume(); 

  Log.d(TAG, "onResume");
  
    mLocalBroadcastManager.registerReceiver(mVideoSelectionReceiver, mVideoSelectedIntentFilter);
  
    resumeVideoUponReturningFromAnotherActivity(); 

 
 } 
+0

Wenn die Anzeigefläche entfernt wird, wenn Aktivitäten Schalt dann werden Sie brauchen SetDisplay()/setSurface() mit der neuen Oberfläche aufzurufen. – fadden

+0

Ich kann es nicht herausfinden. Ich legte 'mediaPlayer.setSurface (surface);' direkt vor dem Suchabschnitt, es funktionierte immer noch nicht. Außerdem habe ich ein paar andere Sachen ausprobiert. – learner

+0

Haben Sie eine neue Oberfläche von der neuen TextureView übergeben? – fadden

Antwort

8

hatte ich das gleiche Problem, wenn zwischen den Aktivitäten eingeschaltet und hatte auch Mediaplayer (1971): Fehler (100,0). Gelöst es durch diese Zeilen innerhalb Zugabe onSurfaceTextureDestroyed

@Override 
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 
     if (mediaPlayer != null) { 
      mediaPlayer.stop(); 
      mediaPlayer.release(); 
      mediaPlayer = null; 
     } 
     return true; 
    } 
+0

Danke Kumpel, das hat es für mich gelöst – josemigallas

0

Es scheint ein Fehler im Code: in SurfaceTextureDestroyed() nicht Fläche zurückgesetzt haben oder Mediaplayer. Wenn resume, weder mediaPlayer noch Oberfläche ist null, so in resumeVideoUponReturningFromAnotherActivity() legen Sie die Oberfläche und Aufruf starten zu spielen, aber Oberfläche bereits wegen der vorherigen SurfaceTextureDestroyed ungültig werden. Deshalb bekommst du Fehler.

Um es zu beheben, sollten Sie Oberfläche in Callback SurfaceTextureDestroyed zurücksetzen. Wenn Sie fortfahren, bauen Sie die Oberfläche im Callback SurfaceTextureAvailable neu auf, legen Sie sie auf mediaPlayer fest und rufen Sie start to play auf. Die Codes gehen so:

Und Sie müssen Media Player überhaupt nicht zurücksetzen. Wenn Sie es zurücksetzen, müssen Sie es erneut instanziieren und erneut puffern, was zu Verzögerungen führt. Dies schadet der Benutzererfahrung, da keine verzögerte Pause/Fortsetzung mehr gewünscht wird.

0

Ich finde setSurface(null) ist nützlich.

Wenn Sie eine TextureView verwenden, um etwas anzuzeigen, wenn TextureView.SurfaceTextureListener Rückruf onSurfaceTextureDestroyed genannt wurde, Sie verwenden SurfaceTexture/new Surface(SurfaceTexture) binded von camera2, MediaCodec oder MediaPlayer stoppen müssen.

Gefällt Ihnen dieses

@Override 
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 
    mediaPlayer.setDisplayer(null); 
    return false;//do not return true if you reuse it. 
}