2015-10-22 22 views
8

Mỗi khi tôi tạm dừng hoạt động của mình (thực sự là Phân đoạn) để chuyển sang ứng dụng khác, khi trở về với onResume tôi cố gắng tiếp tục phát video nhưng không phát: Tôi nhận được trống màn. Sau khi điều tra, tôi thấy sau trong LogcatBufferQueue đã bị hủy: Khi phát video với 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 

Đây là mã tôi gọi bên trên resume

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

FYI: Tôi đã cố gắng để áp dụng câu trả lời này đến trường hợp của tôi, nhưng tôi có thể 't: What can I do when the BufferQueue has been abandoned?

CẬP NHẬT

tôi vất vả đi một mình, nhưng tôi vẫn đang rơi. Vì vậy, tôi đăng toàn bộ mã để được trợ giúp

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

Nếu bề mặt màn hình sẽ biến mất khi chuyển sang hoạt động sau đó bạn sẽ cần phải gọi setDisplay()/setSurface() với bề mặt mới. – fadden

+0

Tôi không thể hiểu được. Tôi đặt 'mediaPlayer.setSurface (bề mặt);' ngay trước phần tìm kiếm nó vẫn không hoạt động. Thêm vào đó, tôi đã thử một vài thứ khác. – learner

+0

Bạn có vượt qua nó một Bề mặt mới từ TextureView mới không? – fadden

Trả lời

8

Tôi gặp vấn đề tương tự khi chuyển đổi giữa các hoạt động và cũng có MediaPlayer (1971): Lỗi (100,0). Giải quyết nó bằng cách thêm các dòng bên onSurfaceTextureDestroyed

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

Cảm ơn anh bạn, đã giải quyết nó cho tôi – josemigallas

0

Dường như có một lỗi trong mã của bạn: trong SurfaceTextureDestroyed() bạn chưa thiết lập lại bề mặt hoặc MediaPlayer. Khi tiếp tục, không phải mediaPlayer cũng không bề mặt rỗng, vì vậy trong resumeVideoUponReturningFromAnotherActivity() đặt bề mặt và bắt đầu cuộc gọi để chơi, nhưng bề mặt đã trở thành không hợp lệ vì SurfaceTextureDestroyed trước đó. Đó là lý do tại sao bạn gặp lỗi.

Để khắc phục, bạn nên đặt lại bề mặt trong chế độ gọi lại SurfaceTextureDestroyed. Khi tiếp tục, xây dựng lại bề mặt trong gọi lại SurfaceTextureAvailable, đặt nó vào mediaPlayer và bắt đầu cuộc gọi để chơi. Các mã có dạng như sau:

public void onResume() { 
    if (mSurface == null) { 
     mResumeRequested = true; 
     return; 
    } 
    mMediaPlayer.start(); 
} 

@Override 
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { 
    mSurface = new Surface(surface); 
    if (mMediaPlayer != null) { 
     mMediaPlayer.setSurface(mSurface); 
     if (mResumeRequested) { 
     mMediaPlayer.start(); 
     mResumeRequested = false; 
     } 
    } 
} 

@Override 
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 
    mSurface = null; 
    return false; 
} 

Và bạn không phải đặt lại trình phát đa phương tiện. Nếu bạn đặt lại, bạn phải tái khởi tạo lại và lưu trữ lại, gây chậm trễ, điều này gây hại cho trải nghiệm người dùng vì không tạm dừng/tiếp tục trì hoãn được mong muốn hơn.

0

Tôi tìm thấy setSurface(null) hữu ích.

Nếu bạn sử dụng một TextureView để hiển thị một cái gì đó, khi TextureView.SurfaceTextureListener callback onSurfaceTextureDestroyed được gọi, bạn phải ngừng sử dụng SurfaceTexture/new Surface(SurfaceTexture) binded bởi camera2, MediaCodec hoặc MediaPlayer.

Như thế này

@Override 
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 
    mediaPlayer.setDisplayer(null); 
    return false;//do not return true if you reuse it. 
} 
Các vấn đề liên quan