wake-up-neo.com

BufferQueue wurde abgebrochen: Beim Abspielen von Videos mit TextureView

Jedes Mal, wenn ich meine Aktivität (tatsächlich Fragment) pausiere, um zu einer anderen App zu wechseln, versuche ich bei der Rückkehr mit onResume, die Wiedergabe des Videos fortzusetzen, aber es wird nicht abgespielt: Ich erhalte einen leeren Bildschirm. Nach Ermittlungen sehe ich Folgendes im Logcat

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 im Lebenslauf aufrufe

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

Zu Ihrer Information: Ich habe versucht, diese Antwort auf meinen Fall anzuwenden, aber ich kann nicht: Was kann ich tun, wenn die BufferQueue abgebrochen wurde?

UPDATE

Ich hatte Mühe, es alleine zu schaffen, aber ich stürze immer noch ab. Also poste ich den gesamten Code zur 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();

    
    }
8
learner

Ich hatte das gleiche Problem beim Wechsel zwischen Aktivitäten und hatte auch MediaPlayer (1971): Fehler (100,0). Gelöst durch Hinzufügen dieser Zeilen in onSurfaceTextureDestroyed

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

Es scheint, dass Ihr Code einen Fehler enthält: In SurfaceTextureDestroyed () haben Sie weder Surface noch MediaPlayer zurückgesetzt. Wenn resume, weder mediaPlayer noch surface den Wert null haben, legen Sie in resumeVideoUponReturningFromAnotherActivity () fest, dass die Oberfläche und der Aufruf abgespielt werden sollen. Die Oberfläche wird jedoch aufgrund der vorherigen Funktion SurfaceTextureDestroyed bereits ungültig. Deshalb bekommst du Fehler.

Um das Problem zu beheben, sollten Sie Surface in Callback SurfaceTextureDestroyed zurücksetzen. Wenn Sie fortfahren, erstellen Sie die Oberfläche in Callback SurfaceTextureAvailable neu, setzen Sie sie auf MediaPlayer und rufen Sie auf, um die Wiedergabe zu starten. Die Codes lauten wie folgt:

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

Und Sie müssen den Media Player überhaupt nicht zurücksetzen. Wenn Sie zurücksetzen, müssen Sie es erneut instanziieren und puffern, was zu Verzögerungen führt. Dies schadet der Benutzererfahrung, da keine Verzögerungspause/-wiederaufnahme mehr erwünscht ist.

0
alexhilton

Ich finde setSurface(null) ist nützlich.

Wenn Sie eine TextureView verwenden, um etwas anzuzeigen, müssen Sie beim Aufrufen von TextureView.SurfaceTextureListener callback onSurfaceTextureDestroyed die Verwendung von SurfaceTexture/new Surface(SurfaceTexture) beenden, die durch camera2, MediaCodec oder MediaPlayer gebunden ist.

So was

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