11

표준 Android API를 사용하여 MPEG-4 비디오 파일의 profile-code을 가져 오는 방법이 있습니까?Android에서 프로그래밍 방식으로 MPEG-4 비디오 스트림 프로필 가져 오기

샘플 프로파일 코드는 baseline, main, high 등입니다.

이 정보를 얻으려면 Android 앱에 ffmpeg 바이너리를 포함하고 싶지 않습니다.

MediaCodecInfo.CodecProfileLevel 클래스의 프로필 목록 참조를 찾았습니다. 이것이 내가 사용해야하는 것이라면 어떤 몸이라도 확인할 수 있습니까? 여기

MX 플레이어 응용 프로그램 Sample data with video profile


  • UPDATE # 1에서 촬영 한 영상 정보의 예 스크린 샷입니다 : 내가 MX 플레이어 응용 프로그램에보고 그들이 ffmpeg 바이너리 사용과 같은, 그래서 그들이 profile-code을 추출하는 데 사용한다고 안전하게 말할 수 있습니다.
  • 업데이트 # 2 : 또한 ExoPlayer v1 개의 API를 살펴본 결과이 API는 특정 API가없는 것으로 보입니다.

답변

1

프로필 코드 MediaExtractor

API documentation 기준이 인코딩 프로필 코드가 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 레벨 16 알려 주시기 바랍니다. 참고로


여기 누가7.1.1 기기에서 촬영 한 비디오 트랙 MediaFormat의 스냅 샷이다. :

MediaFormat Hash Map - Snapshot

기타 참조 (참고 낮은 수준의 API가 적은 특성을 반환합니다) :