BufferQueue aufgegeben wurde: Bei der Wiedergabe von video mit TextureView
Jedes mal, wenn ich pause meine Tätigkeit (tatsächlich Fragment) gehen Sie zu einer anderen app, nach der Rückkehr mit onResume ich versuchen, wieder die video-Wiedergabe, aber es nicht zu spielen: ich bekomme einen leeren Bildschirm. Bei der Untersuchung 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 anrufen innen bei der Wiederaufnahme der
player.seekTo(mVideoSeekPosition);
player.start();
FYI: ich habe versucht, diese Antworten zu meinem Fall, aber ich kann nicht: Was kann ich tun, wenn die BufferQueue aufgegeben wurde?
UPDATE
Ich mühte mich, es alleine zu machen, aber ich bin immer noch abstürzt. Also ich bin Entsendung der ganze code für die 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();
}
- Wenn die display-Oberfläche ist Weg, beim Wechsel von Aktivitäten, dann brauchen Sie nennen setDisplay() / setSurface() mit der neuen Oberfläche.
- Ich kann ' T es herausfinden. Ich legte
mediaPlayer.setSurface(surface);
Recht vor, die suchen Teil es funktioniert immer noch nicht. Plus ich habe versucht ein paar andere Sachen. - Hast du es passieren, eine neue Oberfläche aus der neuen TextureView?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich hatte das gleiche problem beim wechseln zwischen Aktivitäten und hatte auch MediaPlayer(1971): Fehler (100,0). Gelöst wird es durch das hinzufügen dieser Zeilen in onSurfaceTextureDestroyed
Scheint es einen bug in deinem code:
in SurfaceTextureDestroyed() du hast nicht zurückgesetzt Oberfläche oder mediaPlayer. Wenn Sie fortsetzen, weder mediaPlayer noch Oberfläche null ist, also in resumeVideoUponReturningFromAnotheractivity() legen Sie die Oberfläche und rufen Sie zu spielen beginnen, aber die Oberfläche, die bereits ungültig geworden sind, weil der Vorherige SurfaceTextureDestroyed. Das ist, warum Sie die Fehlermeldung.
Um es zu beheben, sollten Sie die reset-Oberfläche Rückruf SurfaceTextureDestroyed. Beim fortsetzen der rebuild-Oberfläche Rückruf SurfaceTextureAvailable, legen Sie es auf mediaPlayer und rufen Sie zu spielen beginnen. Die codes gehen so:
Ist und Sie nicht zurücksetzen, media-player überhaupt. Wenn Sie zurücksetzen, müssen Sie re-instanziieren und re-Pufferung, die Verzögerung verursacht, dies schadet dem user-experience, da keine Verzögerung "pause/fortsetzen" wird mehr gewünscht.
Finde ich
setSurface(null)
nützlich ist.Wenn Sie eine TextureView etwas darstellen, wenn
TextureView.SurfaceTextureListener
RückrufonSurfaceTextureDestroyed
genannt wurde, Sie stoppen müssen, verwenden SieSurfaceTexture/new Surface(SurfaceTexture)
gebunden durchcamera2
,MediaCodec
oderMediaPlayer
.Wie diese