Error de MediaPlayer / VideoView de Android (1, -2147483648)

He estado teniendo una experiencia inconsistente con la fijación de un vídeo de VideoView de una trayectoria del archivo.

VideoView myVideoView = findViewById(R.id.videoView); ... myVideoView.setVideoPath(videoFilename); ... myVideoView.start(); 

VideoFilename es la ruta absoluta de un video en el directorio de mi caché:

 String videoFilename = new File(context.getCacheDir(), "myawesomevideo.mp4").getAbsolutePath(); 

En Android SDK> = 16 (Jelly Bean), esto funciona muy bien y mi vídeo impresionante juega. En Android 4.0.4 (SDK = 15), MediaPlayer se rompe cuando se llama a myVideoView.start ().

El error es el siempre inútil:

 error (1, -2147483648) 

¿Que me estoy perdiendo aqui? Cargando un archivo directamente desde mis recursos de paquete (res / raw) o el Internet ( http://something.com/myawesomeinternetvideo.mp4 ), pero no puedo entender cómo leer los archivos de mi directorio de caché!

Como resultado, el error -2147483648 indica un error desconocido. Esto podría tener algo que ver con la codificación de vídeo, pero también vale la pena comprobar que la ruta del archivo existe y que el VideoView tiene permiso para leerlo .

Mi problema era que estaba escribiendo mis archivos con Context.MODE_PRIVATE (el valor predeterminado).

 openFileOutput(filename, Context.MODE_PRIVATE); 

Esto indica que sólo su aplicación puede acceder al archivo. No sé específicamente cómo o por qué, pero en Jelly Bean y arriba, parece que la vista de video tiene acceso al archivo que especificas como si fuera tu aplicación, pero antes de Jelly Bean, la vista de video intenta abrir el archivo. Archivo en su propio contexto (no en su aplicación). Dado que el modo es privado, falla.

Una solución es escribir su archivo con Context.MODE_WORLD_READABLE , que ahora está obsoleto. Esto indica que cualquiera puede abrir el archivo en esa ruta. Esto es obviamente inseguro y desalentado.

Terminé creando un proveedor de contenido y mi propio URI para manejar este caso. Específicamente:

AndroidManfest.xml :

 ... <provider android:name="com.myexampleapp.video.VideoProvider" android:authorities="com.myexampleapp.video.VideoProvider.files" android:exported="false" /> </application> </manifest> 

VideoProvider.java :

 package com.myexampleapp.video; import java.io.File; import java.io.FileNotFoundException; import android.content.ContentProvider; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.ParcelFileDescriptor; public class VideoProvider extends ContentProvider { public static final Uri CONTENT_URI_BASE = Uri.parse("content://com.myexampleapp.video.VideoProvider.files.files/"); private static final String VIDEO_MIME_TYPE = "video/mp4"; @Override public boolean onCreate() { return true; } @Override public String getType(final Uri uri) { return VIDEO_MIME_TYPE; } @Override public ParcelFileDescriptor openFile(final Uri uri, final String mode) throws FileNotFoundException { File f = new File(uri.getPath()); if (f.exists()) return (ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY)); throw new FileNotFoundException(uri.getPath()); } @Override public int delete(final Uri uri, final String selection, final String[] selectionArgs) { throw new UnsupportedOperationException(); } @Override public Uri insert(final Uri uri, final ContentValues values) { throw new UnsupportedOperationException(); } @Override public Cursor query(final Uri uri, final String[] projection, final String selection, final String[] selectionArgs, final String sortOrder) { throw new UnsupportedOperationException(); } @Override public int update(final Uri uri, final ContentValues values, final String selection, final String[] selectionArgs) { throw new UnsupportedOperationException(); } } 

Y luego, donde accedo a mis archivos de video:

 VideoView myVideoView = findViewById(R.id.videoView); ... myVideoView.setVideoURI( Uri.parse( CachedActionProvider.CONTENT_URI_BASE + Uri.encode(videoFilename))); ... myVideoView.start(); 

Esta es una manera muy larga de decirle al VideoView que le pida a su ContentProvider el descriptor del archivo a los datos. Los descriptores de archivo no están permitidos, por lo que se abre el archivo utilizando los permisos de la aplicación y se entrega a la VideoView en lugar de pedir a la VideoView para abrir el archivo con sus propios permisos.

Esto soluciona mi problema y espero que el suyo, también!

También tuve este problema al cargar un archivo de vídeo desde el directorio de caché. El problema parecía ocurrir en Nexus-dispositivos solamente pero no puedo probarlo en muchos dispositivos.

Intenté escribir el archivo con Context.MODE_WORLD_READABLE pero esa corrección no funcionó para mí. El VideoProvider.java tampoco lo arregló.

Así que encontré otra solución que funcionó para mí. Creé un tempFile en mi actividad y le di a VideoView el camino de absolut a él.

Tal vez mi código puede ayudar a alguien 🙂

  private MediaController mController; private VideoView mVideoView; private File mTmpFile = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_video); init(); } private void init() { mProgressDialog = new ProgressDialog(this); mVideoView = (VideoView) findViewById(R.id.surface_video); mVideoView.requestFocus(); mController = new MediaController(this); mVideoView.setMediaController(mController); mVideoView.setOnPreparedListener(this); mVideoView.setOnCompletionListener(this); mVideoView.setOnErrorListener(this); String url = getIntent().getExtras().getString(MainActivity.VIDEO_URL_EXTRA_KEY); if (VideoLoaderTask.hasVideo(this, url)) { url = getCacheDir().toString().concat("/" + VideoLoaderTask.VIDEO_DIR + "/").concat(url); copyToTmpFile(url); mVideoView.setVideoPath(mTmpFile.getAbsolutePath()); } else { mVideoView.setVideoURI(Uri.parse(url)); } mProgressDialog.show(); mVideoView.start(); } @Override public void onDestroy() { if (mTmpFile != null) { mTmpFile.delete(); } super.onDestroy(); } private void copyToTmpFile(String url) { File f = new File(url); try { mTmpFile = File.createTempFile("video", null); mTmpFile.deleteOnExit(); FileInputStream is = new FileInputStream(f); int size = is.available(); byte[] buffer = new byte[size]; is.read(buffer); is.close(); FileOutputStream fos = new FileOutputStream(mTmpFile); fos.write(buffer); fos.close(); } catch (Exception e) { mVideoView.setVideoURI(Uri.parse(url)); } } 
  • ¿Cuál es la diferencia entre MediaPlayer y VideoView en Android
  • Reproducir archivo de vídeo desde el almacenamiento interno android mediante VideoView
  • reproducir streaming en VideoView, convertir url a rtsp
  • Obtener el camino real para Uri Android
  • Android VideoView Detección de ancho de banda
  • VideoView en un fondo de pantalla en vivo?
  • Juega RTP stream withouth RTSP en Android VideoView
  • ¿Por qué el tamaño de la vista de video cambió automáticamente dependiendo del tamaño del video?
  • Transmisión de video en vivo entre dos teléfonos Android
  • ¿Hay una manera de hacer una barra de progreso de VideoView personalizada sin la construcción de un MediaPlayer desde cero?
  • Evite la corrupción de Android VideoView al girar de nuevo al retrato
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.