การแปลงสื่อเป็นรูปแบบที่เข้ากันได้

ใน Android 12 (API ระดับ 31) ขึ้นไป ระบบจะแปลงวิดีโอที่บันทึกในรูปแบบต่างๆ เช่น HEVC (H.265) เป็น AVC (H.264) โดยอัตโนมัติเมื่อแอปที่ไม่รองรับ HEVC เปิดวิดีโอ ฟีเจอร์นี้ช่วยให้แอปจับภาพวิดีโอใช้การเข้ารหัสที่ทันสมัยและประหยัดพื้นที่เก็บข้อมูลมากขึ้นสำหรับวิดีโอที่บันทึกไว้ในอุปกรณ์โดยไม่ลดทอนความเข้ากันได้กับแอปอื่นๆ

ระบบจะแปลงรหัสรูปแบบต่อไปนี้โดยอัตโนมัติสำหรับเนื้อหาที่สร้างในอุปกรณ์

รูปแบบสื่อ แอตทริบิวต์ XML ประเภท MIME ของ MediaFormat
HEVC (H.265) HEVC MediaFormat.MIMETYPE_VIDEO_HEVC
HDR10HDR10 MediaFeature.HdrType.HDR10
HDR10+ HDR10Plus MediaFeature.HdrType.HDR10_PLUS

Android ถือว่าแอปสามารถรองรับการเล่นสื่อทุกรูปแบบได้ ดังนั้นการแปลงรหัสสื่อที่เข้ากันได้จึงปิดอยู่โดยค่าเริ่มต้น

กรณีที่ควรใช้การแปลงรหัส

การแปลงรหัสเป็นกระบวนการที่ใช้การคำนวณสูงและทำให้เกิด ความล่าช้าอย่างมากเมื่อเปิดไฟล์วิดีโอ เช่น ไฟล์วิดีโอ HEVC ความยาว 1 นาทีจะใช้เวลาประมาณ 20 วินาทีในการแปลงรหัสเป็น AVC ในโทรศัพท์ Pixel 3 ด้วยเหตุนี้ คุณจึงควรแปลงรหัสไฟล์วิดีโอเมื่อส่งไฟล์ออกจาก อุปกรณ์เท่านั้น เช่น เมื่อแชร์ไฟล์วิดีโอกับผู้ใช้แอปเดียวกันหรือเซิร์ฟเวอร์ระบบคลาวด์ที่ไม่รองรับรูปแบบวิดีโอสมัยใหม่

อย่าทำการแปลงรหัสเมื่อเปิดไฟล์วิดีโอเพื่อเล่นบนอุปกรณ์หรือเพื่อสร้างภาพขนาดย่อ

การกำหนดค่าการแปลง

แอปสามารถควบคุมลักษณะการทำงานของการแปลงรหัสได้โดยการประกาศความสามารถของสื่อ คุณประกาศความสามารถเหล่านี้ได้ 2 วิธี ได้แก่ ในโค้ด หรือในทรัพยากร

ประกาศความสามารถในโค้ด

คุณสามารถประกาศความสามารถของสื่อในโค้ดได้โดยสร้างอินสแตนซ์ของออบเจ็กต์ ApplicationMediaCapabilities โดยใช้เครื่องมือสร้าง

Kotlin

val mediaCapabilities = ApplicationMediaCapabilities.Builder()
    .addSupportedVideoMimeType(MediaFormat.MIMETYPE_VIDEO_HEVC)
    .addUnsupportedHdrType(MediaFeature.HdrType.HDR10)
    .addUnsupportedHdrType(MediaFeature.HdrType.HDR10_PLUS)
    .build()

Java

ApplicationMediaCapabilities mediaCapabilities = new ApplicationMediaCapabilities.Builder()
        .addSupportedVideoMimeType(MediaFormat.MIMETYPE_VIDEO_HEVC)
        .addUnsupportedHdrType(MediaFeature.HdrType.HDR10)
        .addUnsupportedHdrType(MediaFeature.HdrType.HDR10_PLUS)
        .build();

ใช้ออบเจ็กต์นี้เมื่อเข้าถึงเนื้อหาสื่อผ่านเมธอดต่างๆ เช่น ContentResolver#openTypedAssetFileDescriptor()

Kotlin

val providerOptions = Bundle().apply {
    putParcelable(MediaStore.EXTRA_MEDIA_CAPABILITIES, mediaCapabilities)
}
contentResolver.openTypedAssetFileDescriptor(mediaUri, mediaMimeType, providerOptions)
    .use { fileDescriptor ->
        // Content will be transcoded based on values defined in the
        // ApplicationMediaCapabilities provided.
    }

Java

Bundle providerOptions = new Bundle();
providerOptions.putParcelable(MediaStore.EXTRA_MEDIA_CAPABILITIES, mediaCapabilities);
try (AssetFileDescriptor fileDescriptor =  contentResolver.openTypedAssetFileDescriptor(mediaUri, mediaMimeType, providerOptions)) {
    // Content will be transcoded based on values defined in the
    // ApplicationMediaCapabilities provided.
}

วิธีนี้ช่วยให้ควบคุมเส้นทางโค้ดที่เฉพาะเจาะจงได้อย่างละเอียด เช่น การเรียกใช้การแปลงรหัสต่อเมื่อโอนไฟล์วิดีโอออกจากอุปกรณ์เท่านั้น ซึ่งมีความสำคัญเหนือกว่าวิธีที่อธิบายไว้ด้านล่าง

ประกาศความสามารถในทรัพยากร

การประกาศความสามารถในทรัพยากรช่วยให้ควบคุมการแปลงรหัสได้ครอบคลุม คุณควรใช้วิธีนี้ในบางกรณีเท่านั้น ตัวอย่างเช่น หากแอปของคุณ รับเฉพาะไฟล์วิดีโอจากแอปอื่นๆ (แทนที่จะเปิดไฟล์โดยตรง) และอัปโหลดไฟล์ไปยังเซิร์ฟเวอร์ที่ไม่รองรับวิดีโอโคเด็กรุ่นใหม่ (ดู สถานการณ์ตัวอย่างที่ 1 ด้านล่าง)

การใช้วิธีนี้เมื่อไม่จำเป็นอย่างยิ่งอาจทำให้เกิดการแปลงรหัสในสถานการณ์ที่ไม่คาดคิด เช่น เมื่อสร้างภาพปกวิดีโอ ซึ่งจะส่งผลให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่แย่ลง

หากต้องการใช้วิธีนี้ ให้สร้างไฟล์ทรัพยากร media_capabilities.xml ดังนี้

<?xml version="1.0" encoding="utf-8"?>
<media-capabilities xmlns:android="http://schemas.android.com/apk/res/android">
    <format android:name="HEVC" supported="true"/>
    <format android:name="HDR10" supported="false"/>
    <format android:name="HDR10Plus" supported="false"/>
</media-capabilities>

ในตัวอย่างนี้ วิดีโอ HDR ที่บันทึกในอุปกรณ์จะได้รับการแปลงรหัสเป็นวิดีโอ AVC SDR (Standard Dynamic Range) อย่างราบรื่น แต่จะไม่มีการแปลงรหัสวิดีโอ HEVC

ใช้แท็ก property ภายในแท็ก application เพื่อเพิ่มการอ้างอิงไปยังไฟล์ความสามารถของสื่อ เพิ่มพร็อพเพอร์ตี้ต่อไปนี้ลงในไฟล์ AndroidManifest.xml

<property
    android:name="android.media.PROPERTY_MEDIA_CAPABILITIES"
    android:resource="@xml/media_capabilities" />

ใช้ความสามารถด้านสื่อของแอปอื่นเพื่อเปิดไฟล์วิดีโอ

หากแอปแชร์ไฟล์วิดีโอกับแอปอื่น คุณอาจต้องแปลงรหัสไฟล์วิดีโอก่อนที่แอปที่รับจะเปิดได้

คุณจัดการกรณีนี้ได้โดยเปิดไฟล์วิดีโอโดยใช้ openTypedAssetFileDescriptor และระบุ UID ของแอปที่รับ ซึ่งรับได้โดยใช้ Binder.getCallingUid จากนั้นแพลตฟอร์มจะใช้ความสามารถด้านสื่อของแอปที่รับเพื่อพิจารณา ว่าควรแปลงรหัสไฟล์วิดีโอหรือไม่

Kotlin

val providerOptions = Bundle().apply {
    putParcelable(MediaStore.EXTRA_MEDIA_CAPABILITIES_UID, Binder.getCallingUid())
}
contentResolver.openTypedAssetFileDescriptor(mediaUri, mediaMimeType, providerOptions)
    .use { fileDescriptor ->
        // Content will be transcoded based on the media capabilities of the
        // calling app.
    }

Java

Bundle providerOptions = new Bundle();
providerOptions.putParcelable(MediaStore.EXTRA_MEDIA_CAPABILITIES_UID, Binder.getCallingUid());
try (AssetFileDescriptor fileDescriptor =  contentResolver.openTypedAssetFileDescriptor(mediaUri, mediaMimeType, providerOptions)) {
    // Content will be transcoded based on the media capabilities of the
    // calling app.
}

ตัวอย่างสถานการณ์

แผนภาพต่อไปนี้แสดงกรณีการใช้งานที่พบบ่อย 2 กรณี ในทั้ง 2 กรณี วิดีโอต้นฉบับจะจัดเก็บในรูปแบบ HEVC และแอปแชร์วิดีโอจะไม่รองรับ HEVC

ตัวอย่างที่ 1 แอปจับภาพวิดีโอเป็นผู้เริ่มการแปลงรหัส ตัวอย่างที่ 1 แอปแชร์วิดีโอประกาศว่าไม่รองรับ HEVC ในไฟล์ทรัพยากรความสามารถของสื่อ จากนั้นจะขอวิดีโอจากแอปจับภาพวิดีโอ โดยแอปจับภาพวิดีโอจะจัดการคำขอและเปิดไฟล์โดยใช้ openTypedAssetFileDescriptor ซึ่งระบุ UID ของแอปแชร์ ซึ่งจะเป็นการเริ่มกระบวนการแปลงรหัส เมื่อได้รับวิดีโอที่แปลงรหัสแล้ว ระบบจะส่งวิดีโอไปยังแอปแชร์ ซึ่งจะอัปโหลดวิดีโอไปยังเซิร์ฟเวอร์ในระบบคลาวด์

ตัวอย่างที่ 2 แอปแชร์วิดีโอจะเป็นผู้เริ่มการแปลงรหัส ตัวอย่างที่ 2 แอปจับภาพวิดีโอจะแชร์วิดีโอกับแอปแชร์วิดีโอโดยใช้ MediaStore URI แอปแชร์วิดีโอจะเปิดไฟล์วิดีโอโดยใช้ openTypedAssetFileDescriptor ซึ่งระบุว่าไม่รองรับ HEVC ในความสามารถด้านสื่อ การดำเนินการนี้จะเริ่มกระบวนการแปลงรหัส และเมื่อเสร็จสมบูรณ์แล้ว ระบบจะอัปโหลดไฟล์ไปยังเซิร์ฟเวอร์ในระบบคลาวด์

รูปแบบที่ไม่ได้ประกาศ

ระบบจะเปิดใช้การแปลงรหัสสื่อที่เข้ากันได้สำหรับรูปแบบทั้งหมดที่ประกาศว่าไม่รองรับ และจะปิดใช้สำหรับรูปแบบทั้งหมดที่ประกาศว่ารองรับ สำหรับ รูปแบบอื่นๆ ที่ไม่ได้ประกาศ แพลตฟอร์มจะเป็นผู้พิจารณาว่าจะแปลงรหัส หรือไม่ ใน Android 12 ระบบจะปิดใช้การแปลงรหัส สำหรับรูปแบบที่ไม่ได้ประกาศทั้งหมด ลักษณะการทำงานนี้อาจเปลี่ยนแปลงสำหรับรูปแบบใหม่ใน อนาคต

ตัวเลือกสำหรับนักพัฒนาแอป

คุณสามารถใช้ตัวเลือกสำหรับนักพัฒนาแอปต่อไปนี้เพื่อลบล้างลักษณะการทำงานเริ่มต้นของการแปลงรหัส ของ Android

  • ลบล้างค่าเริ่มต้นของการแปลง การตั้งค่านี้จะกำหนดว่าแพลตฟอร์มควบคุมการแปลงอัตโนมัติหรือไม่ เมื่อเปิดใช้การลบล้าง ระบบจะไม่สนใจค่าเริ่มต้นของแพลตฟอร์ม และการตั้งค่าเปิดใช้ การแปลงรหัสจะควบคุมการแปลงรหัสอัตโนมัติ ตัวเลือกนี้จะปิดไว้โดยค่าเริ่มต้น

  • เปิดใช้การแปลงรหัส การตั้งค่านี้ระบุว่าควรแปลงรหัสรูปแบบที่ไม่ได้ประกาศโดยอัตโนมัติหรือไม่ โดยจะเปิดใช้โดยค่าเริ่มต้น แต่จะมีผลก็ต่อเมื่อเปิดใช้ลบล้างค่าเริ่มต้นของการแปลงรหัสด้วย

  • ถือว่าแอปรองรับรูปแบบสมัยใหม่ การตั้งค่านี้จะควบคุมสิ่งที่จะเกิดขึ้นเมื่อ แอปพยายามเล่นรูปแบบที่ไม่ได้ประกาศ กรณีนี้เกิดขึ้นเมื่อไฟล์ Manifest ไม่ได้ประกาศว่าแอป รองรับรูปแบบใดรูปแบบหนึ่งหรือไม่ หรือ Google ยังไม่ได้เพิ่มแอปไปยังรายการบังคับการแปลงรหัสฝั่งเซิร์ฟเวอร์ เมื่อเปิดใช้การตั้งค่า แอปจะไม่แปลงรหัส แต่เมื่อปิดใช้ แอปจะ แปลงรหัส ตัวเลือกนี้จะเปิดใช้อยู่โดยค่าเริ่มต้น

  • แสดงการแจ้งเตือนการแปลง เมื่อเปิดใช้ แอปจะแสดง การแจ้งเตือนความคืบหน้าของการแปลงเมื่อการแปลงเกิดขึ้นจากการอ่าน ไฟล์สื่อที่ไม่รองรับ ตัวเลือกนี้จะเปิดใช้อยู่โดยค่าเริ่มต้น

  • ปิดใช้แคชสำหรับการแปลง หากเปิดใช้ แอปที่ต้องมีการแปลงจะไม่ใช้แคชสำหรับการแปลง ซึ่งอาจมีประโยชน์ในระหว่างการพัฒนาเพื่อเรียกใช้การแปลงรหัสในไฟล์สื่อที่ไม่รองรับได้อย่างง่ายดาย แต่ก็อาจทําให้อุปกรณ์ทํางานได้ไม่ดี ตัวเลือกนี้จะปิดไว้โดยค่าเริ่มต้น