BufferQueue a été abandonné. Lors de la lecture de vidéo avec TextureView
Chaque fois que je fais une pause de mon activité (en fait Fragment) pour aller à une autre application, lors de son retour avec onResume j'essaie de reprendre la vidéo de la lecture, mais il ne joue pas: j'obtiens un écran vide. Après enquête, je les éléments suivants dans le 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
Voici le code que j'ai appeler à l'intérieur de reprise
player.seekTo(mVideoSeekPosition);
player.start();
Pour info: j'ai essayé d'appliquer cette réponse à mon cas, mais je ne peux pas: Que puis-je faire lorsque le BufferQueue a été abandonné?
Mise à JOUR
J'ai eu du mal à s'en sortir seul, mais je suis toujours de s'écraser. Donc je vous poste le code complet pour aider
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();
}
Si la surface d'affichage est d'aller loin lors de la commutation d'activités, alors vous aurez besoin d'appeler setDisplay() / setSurface() avec la nouvelle Surface.
Je ne peux pas le comprendre. J'ai mis
Avez-vous passer une nouvelle Surface à partir de la nouvelle TextureView?
Je ne peux pas le comprendre. J'ai mis
mediaPlayer.setSurface(surface);
juste avant la partie chercher il ne fonctionne toujours pas. De Plus j'ai essayé quelques autres trucs.Avez-vous passer une nouvelle Surface à partir de la nouvelle TextureView?
OriginalL'auteur learner | 2015-10-22
Vous devez vous connecter pour publier un commentaire.
J'ai eu le même problème lors de la commutation entre les activités et a également eu MediaPlayer(1971): Erreur (100,0). Résolu par l'ajout de ces lignes à l'intérieur de onSurfaceTextureDestroyed
OriginalL'auteur Joks
Il semble y avoir un bug dans votre code:
dans SurfaceTextureDestroyed() vous n'avez pas réinitialiser surface ou mediaPlayer. Lors de la reprise, ni mediaPlayer ni de surface est nulle, donc dans resumeVideoUponReturningFromAnotheractivity() définie de la surface et de l'appel de commencer à jouer, mais la surface déjà devenu invalide en raison d'une précédente SurfaceTextureDestroyed. C'est pourquoi vous obtenez l'erreur.
Pour résoudre ce problème, vous devez réinitialiser la surface dans le rappel SurfaceTextureDestroyed. Lors de la reprendre, de reconstruire la surface dans le rappel SurfaceTextureAvailable, il mediaPlayer et appel de commencer à jouer. Les codes aller comme ceci:
Et vous n'avez pas à réinitialiser media player. Si vous réinitialisation, vous devez ré-instancier et de re-mise en mémoire tampon, ce qui entraîne des retards, cette nuit à l'expérience utilisateur, car pas de retarder mettre en pause/reprendre est plus désiré.
OriginalL'auteur alexhilton
Je trouve
setSurface(null)
est utile.Si vous utilisez un TextureView pour afficher quelque chose, quand
TextureView.SurfaceTextureListener
rappelonSurfaceTextureDestroyed
a été appelé, vous devez cesser d'utiliserSurfaceTexture/new Surface(SurfaceTexture)
lié parcamera2
,MediaCodec
ouMediaPlayer
.Comme ce
OriginalL'auteur miao