Получите профиль видеопотока MPEG-4 программно на Android

Есть ли способ получить профиль-код видеофайлов MPEG-4 с помощью стандартного API Android?

Примеры кодов профиля: baseline , main , high и т. Д.

Я не хочу включать двоичный файл ffmpeg в приложение для Android, чтобы получить эту информацию.

Я нашел ссылку на список профилей в классе MediaCodecInfo.CodecProfileLevel . Может ли какой-либо орган подтвердить, является ли это тот, который я должен использовать?

Вот пример скриншота видеоинформации, взятой из приложения MX Player Пример данных с профилем видео


  • UPDATE # 1: Я посмотрел приложение MX Player, похоже, что они используют двоичный файл ffmpeg , поэтому я могу с уверенностью сказать, что они используют это для извлечения profile-code .
  • ОБНОВЛЕНИЕ № 2: Я также изучил API-интерфейсы ExoPlayer v1 , они также не имеют определенного API для получения этой информации.

Solutions Collecting From Web of "Получите профиль видеопотока MPEG-4 программно на Android"

Код профиля можно найти с помощью MediaExtractor

На основе документации API кажется, что код профиля кодирования доступен только с уровня API 24 (нуга) и выше.

Вот метод, который я написал для извлечения кода профиля, не стесняйтесь изменять его в соответствии с вашими потребностями.

 /** * 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; } 

И вот пример кода о том, как его использовать.

 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."); } 

Надеюсь, поможет. Если у вас есть другой способ, который поддерживает, по крайней мере, уровень API Jelly Bean 16 дайте мне знать.


Для справки, здесь приведен снимок MediaFormat видеодорожки, снятой с устройства Nougat 7.1.1 . (ПРИМЕЧАНИЕ. API более низкого уровня возвращает меньше атрибутов)

Карта медиафайлов MediaFormat - снимок

Другие ссылки:

  • Получить информацию о видеофайлах с настольного приложения – Как получить информацию о видео h264?