La superficie se ha liberado cuando intento setDisplay to MediaPlayer

Mi archivo xml:

<SurfaceView android:id="@+id/surfaceView" android:layout_marginTop="50dp" android:layout_width="fill_parent" android:layout_height="300dp" /> 

Mi función de setDisplay:

 public void playVideo() { MediaPlayer mp = new MediaPlayer(); SurfaceView sv = (SurfaceView) this.findViewById(R.id.surfaceView); try { mp.setDataSource("sdcard/test/a.3gp"); SurfaceHolder sh = sv.getHolder(); mp.setDisplay(sh);***----the exception occured here*** mp.prepare(); mp.start(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } 

El registro como abajo:

 04-24 22:19:33.645: W/System.err(16106): java.lang.IllegalArgumentException: The surface has been released 04-24 22:19:33.645: W/System.err(16106): at android.media.MediaPlayer._setVideoSurface(Native Method) 04-24 22:19:33.645: W/System.err(16106): at android.media.MediaPlayer.setDisplay(MediaPlayer.java:698) 

He encontrado algunas preguntas similares aquí, pero todas esas no son traje para mí. Esperando sus respuestas. Muchas gracias.

5 Solutions collect form web for “La superficie se ha liberado cuando intento setDisplay to MediaPlayer”

La Superficie puede ser destruida. Es por eso que usted necesita para añadir a la public void surfaceDestroyed(SurfaceHolder holder) un public void surfaceDestroyed(SurfaceHolder holder) a la aplicación de su SurfaceView de esta manera:

  @Override public void surfaceDestroyed(SurfaceHolder holder) { synchronized (this) { hasActiveHolder = false; synchronized(this) { this.notifyAll(); } } } 

También debe agregar una función que maneje la creación de superficie:

 @Override public void surfaceCreated(SurfaceHolder holder) { synchronized (this) { hasActiveHolder = true; this.notifyAll() } } 

Y modifique su propia función de esta manera:

  mp.setDataSource("sdcard/test/a.3gp"); SurfaceHolder sh = sv.getHolder(); synchronized (this) { while (!hasActiveHolder) { try { this.wait(); } catch (InterruptedException e) { //Print something } } mp.setDisplay(sh); mp.prepare(); } 

Tienes otra opción que es la forma en que Google sugiere que uses SurfaceView: en un hilo separado.

Es algo relacionado con la secuencia de ejecución, ya que la superficie tiene que ser creada primero antes de configurar la visualización para el MediaPlayer, so you have to override the callback method surfaceCreated` a lo siguiente:

 @Override public void surfaceCreated(SurfaceHolder holder) { mp.setDisplay(sh); // now "mp" is defined as a class variable } 

Y ahora no hay necesidad de setDisplay dentro de su método de juego:

 private MediaPlayer mp; // to use it inside surfaceCreated callback method public void playVideo() { mp = new MediaPlayer(); SurfaceView sv = (SurfaceView) this.findViewById(R.id.surfaceView); try { mp.setDataSource("sdcard/test/a.3gp"); SurfaceHolder sh = sv.getHolder(); mp.prepare(); mp.start(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } 

La forma más sencilla es simplemente llamar a setDisplay en surfaceCreated :

 @Override public void surfaceCreated(SurfaceHolder holder) { mp.setDisplay(holder) } 

Y no se olvide de desatar la superficie:

 @Override public void surfaceDestroyed(SurfaceHolder holder) { mp.setDisplay(null); } 

Nota: el reproductor multimedia debe inicializarse en alguna parte antes, por ejemplo en onCreate .

Para aquellos que siguen teniendo problemas, intente implementar SurfaceHolder.Callback en su activity / fragment / etc y en el método onCreate / onCreateView , llame al método addCallback (SurfaceHolder.Callback callback) , usando su activity / fragment / etc como el parámetro callback.

Hacer uso de SurfaceHolder.Callback como a continuación

 SurfaceView mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView); SurfaceHolder holder = mSurfaceView.getHolder(); final MediaPlayer player = new MediaPlayer(); holder.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { player.setDisplay(holder); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { } }); String UrlPath="android.resource://"+getActivity().getPackageName()+"/"+R.raw.your_file_name_without_extension; try { player.setDataSource(getActivity(),Uri.parse(UrlPath)); player.prepareAsync(); } catch (IOException e) { e.printStackTrace(); } player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mp.start(); } }); 
  • Cómo obtener la duración de Audio Stream y continuar la transmisión de audio desde cualquier punto
  • Recepción de flujo de vídeo desde una cámara IP en android
  • Error de reproductor multimedia Android (1, -1004) mientras reproduce un flujo desde un sitio web externo
  • Reproducir audio utilizando datos de base64 en html5
  • Android: MediaPlayer finalizado sin ser lanzado
  • Android muestra flujo de vídeo en MediaPlayer y codifica con MediaCodec
  • Efecto de audio Android en el archivo wav y guárdelo
  • Android: ¿Cualquier forma de reducir el retardo de los medios / latencia en VideoView / MediaPlayer?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.