Obtenga el perfil de la secuencia de vídeo MPEG-4 mediante programación en Android

¿Hay alguna manera de obtener el código de perfil de MPEG-4 video fils usando la API estándar de Android?

Los códigos de perfil de ejemplo son: baseline , main , high y así sucesivamente.

No quiero incluir ffmpeg binario en la aplicación de Android sólo para obtener esta información.

Encontré la referencia de la lista de perfiles en la clase MediaCodecInfo.CodecProfileLevel . ¿Puede cualquier organismo confirmar si este es el que debería usar?

Aquí hay un ejemplo de captura de pantalla de información de video tomada desde la aplicación MX Player Muestra de datos con el perfil de vídeo


  • UPDATE # 1: Miré en la aplicación MX Player, parece que utilizan ffmpeg binario, así que puedo decir con seguridad que utilizan para extraer el profile-code .
  • UPDATE # 2: También miré en ExoPlayer v1 API, también no parece tener API específica para obtener esta información.

El código de perfil se puede encontrar usando MediaExtractor

Según la documentación de la API , parece que el código de perfil de codificación sólo está disponible desde el nivel 24 de API (Nougat) y hacia arriba.

Aquí está el método que escribí para extraer el código de perfil, no dude en modificar para satisfacer su necesidad.

 /** * Get video profile-code from video file. * * @param videoFilePath Path of the video file. * @return One of predefined AVC profiles from {@link MediaCodecInfo.CodecProfileLevel} when found, or {@code -1} if * Android API level does not support extracting profile data. */ @TargetApi(21) public int getVideoEncodingProfile(final String videoFilePath) { int videoProfileCode = -1; File inputFile = new File(videoFilePath); if (!inputFile.canRead()) { throw new RuntimeException("Unable to read " + inputFile); } MediaExtractor mediaExtractor = new MediaExtractor(); // Initialize MediaExtractor and configure/extract video information try { mediaExtractor.setDataSource(inputFile.toString()); } catch (IOException e) { Log.e(TAG, "Unable to set MediaExtractor source.", e); throw new RuntimeException("Unable to set source."); } MediaFormat videoMediaFormat = findVideoMediaFormat(mediaExtractor); // MediaCodecInfo.CodecProfileLevel of the video track if (videoMediaFormat != null && videoMediaFormat.containsKey(MediaFormat.KEY_PROFILE)) { videoProfileCode = videoMediaFormat.getInteger(MediaFormat.KEY_PROFILE); } else { // Current API level does not support encoding profile information. Log.w(TAG, "Video profile code is not supported by current API level."); } mediaExtractor.release(); mediaExtractor = null; return videoProfileCode; } /** * Find video MediaFormat from MediaExtractor. * * @param mediaExtractor The MediaExtractor which is used to find video track. * @return MediaFormat for video track, or {@code null} when video track is not found. */ private MediaFormat findVideoMediaFormat(final MediaExtractor mediaExtractor) { MediaFormat videoTrackMediaFormat = null; int totalTracks = mediaExtractor.getTrackCount(); for (int i = 0; i < totalTracks; i++) { MediaFormat trackFormat = mediaExtractor.getTrackFormat(i); if ((trackFormat.containsKey(MediaFormat.KEY_MIME) && trackFormat.getString(MediaFormat.KEY_MIME).contains("video")) || (trackFormat.containsKey(MediaFormat.KEY_WIDTH) && trackFormat.containsKey(MediaFormat.KEY_HEIGHT)) ) { videoTrackMediaFormat = trackFormat; break; } } return videoTrackMediaFormat; } 

Y aquí está un ejemplo de código sobre cómo usarlo.

 String TAG = "DEBUG"; // Define your tag int profileCode = getVideoEncodingProfile(videoInfo.getLocalVideoPath()); switch (profileCode) { case MediaCodecInfo.CodecProfileLevel.AVCProfileBaseline: Log.d(TAG, "getVideoEncodingProfile() returned AVCProfileBaseline"); break; case MediaCodecInfo.CodecProfileLevel.AVCProfileMain: Log.d(TAG, "getVideoEncodingProfile() returned AVCProfileMain"); break; case MediaCodecInfo.CodecProfileLevel.AVCProfileExtended: Log.d(TAG, "getVideoEncodingProfile() returned AVCProfileExtended"); break; case MediaCodecInfo.CodecProfileLevel.AVCProfileHigh: Log.d(TAG, "getVideoEncodingProfile() returned AVCProfileHigh"); break; case MediaCodecInfo.CodecProfileLevel.AVCProfileHigh10: Log.d(TAG, "getVideoEncodingProfile() returned AVCProfileHigh10"); break; case MediaCodecInfo.CodecProfileLevel.AVCProfileHigh422: Log.d(TAG, "getVideoEncodingProfile() returned AVCProfileHigh422"); break; case MediaCodecInfo.CodecProfileLevel.AVCProfileHigh444: Log.d(TAG, "getVideoEncodingProfile() returned AVCProfileHigh444"); break; default: Log.d(TAG, "getVideoEncodingProfile() returned unsupported profile code or code not found."); } 

Espero eso ayude. Si tienes otra forma que soporte al menos Jelly Bean API nivel 16 déjame saber.


Para referencia, aquí hay una instantánea de MediaFormat de una pista de vídeo tomada desde el dispositivo Nougat 7.1.1 . (NOTA: API de nivel inferior devolverá menos atributos)

Mapa de Hash de MediaFormat - Instantánea

Otras referencias:

  • Obtener información de archivo de vídeo desde la aplicación de escritorio – ¿Cómo obtener información de vídeo h264?
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.