חילוץ דוגמאות מקודדות

המחלקות MediaExtractorCompat הן תחליף מוכן לשימוש למחלקות MediaExtractor של הפלטפורמה, והן מספקות ממשקי API ופונקציונליות זהים. הוא מאפשר חילוץ של נתוני מדיה שעברו דה-מולטיפלקס, בדרך כלל מוצפנים, ממקור נתונים.

הוא מפריד קובץ מאגר (כמו MP4 או MKV) לרצועות נפרדות, כמו וידאו, אודיו וכתוביות. לאחר מכן, כלי החילוץ קורא את הנתונים המקודדים הגולמיים מהרצועות האלה כרצף של דגימות (לדוגמה, פריים דחוס יחיד של סרטון או בלוק של אודיו) לפני שהם נשלחים למפענח.

תרחישים נפוצים לדוגמה:

  • טרנסקוד או רימקס: קריאת דוגמאות מקודדות מטראק כדי לשנות את הקודק (טרנסקוד) או לארוז מחדש את הסטרימינג למאגר חדש (רימקס), למשל המרה של קובץ MP4 ל-MKV.
  • חילוץ סלקטיבי של תוכן: בידוד ושמירה של טראק יחיד, כמו חילוץ של אודיו מקובץ וידאו.
  • ניפוי באגים ברמה נמוכה: בדיקת דוגמאות ספציפיות כדי לנפות באגים בקובץ, בעיות בחותמת הזמן או בעיות אחרות.
  • יצירת נגנים בהתאמה אישית: לתרחישי שימוש נישתיים, אפשר ליצור נגן בהתאמה אישית עם שליטה מלאה בצינור המדיה.

סקירה כללית

בדוגמת הקוד הבאה אפשר לראות איך משתמשים בפרמטר 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();
    }
}