11

Có cách nào để tải các video clip MPEG-4 của profile-code bằng API Android chuẩn không?Tải cấu hình luồng video MPEG-4 theo cách lập trình trên Android

Mã cấu hình mẫu là: baseline, main, high v.v.

Tôi không muốn bao gồm ffmpeg nhị phân trong ứng dụng android chỉ để nhận thông tin này.

Tôi đã tìm thấy tham chiếu danh sách hồ sơ trong lớp học MediaCodecInfo.CodecProfileLevel. Bất kỳ cơ thể nào có thể xác nhận nếu đây là cái tôi nên sử dụng?

Dưới đây là một ví dụ ảnh chụp màn hình thông tin phim được lấy từ MX chơi ứng dụng Sample data with video profile


  • CẬP NHẬT # 1: Tôi nhìn vào ứng dụng MX Player, trông giống như họ sử dụng ffmpeg nhị phân, vì vậy tôi một cách an toàn có thể nói rằng họ sử dụng để trích xuất profile-code.
  • CẬP NHẬT # 2: Tôi cũng đã xem xét các API ExoPlayer v1, chúng cũng dường như không có API cụ thể để nhận thông tin này.

Trả lời

1

hồ sơ mã có thể được tìm thấy bằng MediaExtractor

Dựa trên API documentation dường như mã hóa hồ sơ mã chỉ có sẵn từ cấp API 24 (Nougat) trở lên.

Đây là phương pháp tôi đã viết để trích xuất mã tiểu sử, vui lòng sửa đổi để đáp ứng nhu cầu của bạn.

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

Và đây là mã mẫu về cách sử dụng.

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

} 

Hy vọng điều đó sẽ hữu ích. Nếu bạn có cách khác hỗ trợ ít nhất Jelly Bean Cấp API 16 hãy cho tôi biết.


Để tham khảo, đây là một bản chụp của MediaFormat của một ca khúc đoạn video lấy từ Nougat7.1.1 thiết bị. (Chú ý: Hạ mức API sẽ trả lại thuộc tính ít)

MediaFormat Hash Map - Snapshot

tài liệu tham khảo khác:

Các vấn đề liên quan