Trích xuất các mẫu được mã hoá

Lớp MediaExtractorCompat là một giải pháp thay thế tức thì cho lớp MediaExtractor của nền tảng và cung cấp các API cũng như chức năng giống hệt nhau. Nó tạo điều kiện trích xuất dữ liệu đa phương tiện đã tách kênh (thường được mã hoá) từ một nguồn dữ liệu.

Công cụ này tách một tệp vùng chứa (chẳng hạn như MP4 hoặc MKV) thành các track riêng lẻ, chẳng hạn như video, âm thanh và phụ đề. Sau đó, trình trích xuất sẽ đọc dữ liệu được mã hoá thô từ các bản nhạc này dưới dạng một chuỗi mẫu (ví dụ: một khung hình video nén hoặc khối âm thanh) trước khi chúng được gửi đến một bộ giải mã.

Các trường hợp sử dụng phổ biến bao gồm:

  • Chuyển mã hoặc Trộn lại: Đọc các mẫu được mã hoá từ một bản nhạc để thay đổi codec (chuyển mã) hoặc đóng gói lại các luồng vào một vùng chứa mới (trộn lại), chẳng hạn như chuyển đổi tệp MP4 thành MKV.
  • Trích xuất nội dung có chọn lọc: Tách và lưu một bản nhạc, chẳng hạn như trích xuất luồng âm thanh từ một tệp video.
  • Gỡ lỗi ở cấp độ thấp: Kiểm tra từng mẫu để gỡ lỗi về tình trạng hỏng tệp, vấn đề về dấu thời gian hoặc các vấn đề khác.
  • Tạo trình phát tuỳ chỉnh: Đối với các trường hợp sử dụng chuyên biệt, hãy tạo một trình phát tuỳ chỉnh có toàn quyền kiểm soát quy trình truyền thông.

Tổng quan

Mã mẫu sau đây cho biết cách sử dụng MediaExtractorCompat:

Kotlin

fun extractSamples(context: Context, mediaPath: String) {
    val extractor = MediaExtractorCompat(context)
    try {
        // 1. Setup the extractor
        extractor.setDataSource(mediaPath)

        // Find and select available tracks
        for (i in 0 until extractor.trackCount) {
            val format = extractor.getTrackFormat(i)
            extractor.selectTrack(i)
        }

        // 2. Process samples
        val buffer = ByteBuffer.allocate(10 * 1024 * 1024)
        while (true) {
            // Read an encoded sample into the buffer.
            val bytesRead = extractor.readSampleData(buffer, 0)
            if (bytesRead < 0) break

            // Access sample metadata
            val trackIndex = extractor.sampleTrackIndex
            val presentationTimeUs = extractor.sampleTime
            val sampleSize = extractor.sampleSize

            extractor.advance()
        }
    } catch (e: IOException) {
        throw RuntimeException(e)
    } finally {
        // 3. Release the extractor
        extractor.release()
    }
}

Java

public void extractSamples(Context context, String mediaPath) {
    MediaExtractorCompat extractor = new MediaExtractorCompat(context);
    try {
        // 1. Setup the extractor
        extractor.setDataSource(mediaPath);

        // Find and select available tracks
        for (int i = 0; i < extractor.getTrackCount(); i++) {
            MediaFormat format = extractor.getTrackFormat(i);
            extractor.selectTrack(i);
        }

        // 2. Process samples
        ByteBuffer buffer = ByteBuffer.allocate(10 * 1024 * 1024);
        while (true) {
            // Read an encoded sample into the buffer.
            int bytesRead = extractor.readSampleData(buffer, 0);
            if (bytesRead < 0) break;

            // Access sample metadata
            int trackIndex = extractor.getSampleTrackIndex();
            long presentationTimeUs = extractor.getSampleTime();
            long sampleSize = extractor.getSampleSize();

            extractor.advance();
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    } finally {
        // 3. Release the extractor
        extractor.release();
    }
}