แยกตัวอย่างที่เข้ารหัส

คลาส MediaExtractorCompat เป็นคลาสที่ใช้แทนคลาส MediaExtractor ของแพลตฟอร์มได้โดยตรง และมี API และฟังก์ชันการทำงานที่เหมือนกัน ซึ่งช่วยให้ดึงข้อมูลสื่อที่แยกแล้วและมักจะเข้ารหัสจากแหล่งข้อมูลได้

โดยจะแยกไฟล์คอนเทนเนอร์ (เช่น MP4 หรือ MKV) ออกเป็นแทร็กแต่ละรายการ เช่น วิดีโอ เสียง และคำบรรยายแทนเสียง จากนั้นตัวแยกจะอ่านข้อมูลที่เข้ารหัสดิบจากแทร็กเหล่านี้เป็นลำดับของตัวอย่าง (เช่น เฟรมวิดีโอที่บีบอัดเดียวหรือบล็อกเสียง) ก่อนที่จะส่งไปยังตัวถอดรหัส

Use Case ที่พบบ่อยมีดังนี้

  • การแปลงรหัสหรือการมัลติเพล็กซ์ใหม่: การอ่านตัวอย่างที่เข้ารหัสจากแทร็กเพื่อเปลี่ยนตัวแปลงรหัส (การแปลงรหัส) หรือจัดแพ็กเกจสตรีมใหม่ลงในคอนเทนเนอร์ใหม่ (การมัลติเพล็กซ์ใหม่) เช่น การแปลงไฟล์ 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) {
    handleFailure(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) {
    handleFailure(e);
  } finally {
    // 3. Release the extractor
    extractor.release();
  }
}