ใน Android 12 (ระดับ API 31) ขึ้นไป ระบบจะแปลงวิดีโอที่บันทึกในรูปแบบต่างๆ เช่น HEVC (H.265) เป็น AVC (H.264) โดยอัตโนมัติเมื่อแอปที่เปิดวิดีโอไม่รองรับ HEVC ฟีเจอร์นี้ช่วยให้แอปบันทึกวิดีโอใช้การเข้ารหัสที่ทันสมัยและประหยัดพื้นที่เก็บข้อมูลมากขึ้นสำหรับวิดีโอที่บันทึกในอุปกรณ์ได้โดยไม่ทำให้แอปอื่นๆ ใช้งานร่วมกันไม่ได้
ระบบจะแปลงรูปแบบต่อไปนี้โดยอัตโนมัติสำหรับเนื้อหาที่สร้างในอุปกรณ์
| รูปแบบสื่อ | แอตทริบิวต์ XML | ประเภท MIME ของ MediaFormat |
|---|---|---|
| HEVC (H.265) | HEVC | MediaFormat.MIMETYPE_VIDEO_HEVC |
| HDR10 | HDR10 | MediaFeature.HdrType.HDR10 |
| HDR10+ | HDR10Plus | MediaFeature.HdrType.HDR10_PLUS |
Android สันนิษฐานว่าแอปสามารถรองรับการเล่นสื่อทุกรูปแบบ ดังนั้นการแปลงสื่อเป็นรูปแบบที่เข้ากันได้จึงปิดอยู่โดยค่าเริ่มต้น
กรณีที่ควรใช้การแปลง
การแปลงเป็นกระบวนการที่ต้องใช้การคำนวณสูงและทำให้เกิดความล่าช้าอย่างมากเมื่อเปิดไฟล์วิดีโอ เช่น ไฟล์วิดีโอ HEVC ความยาว 1 นาทีต้องใช้เวลาประมาณ 20 วินาทีในการแปลงเป็น AVC ในโทรศัพท์ Pixel 3 ด้วยเหตุนี้ คุณจึงควรแปลงไฟล์วิดีโอเฉพาะเมื่อส่งไฟล์ออกจากอุปกรณ์ เช่น เมื่อแชร์ไฟล์วิดีโอกับผู้ใช้แอปเดียวกันหรือเซิร์ฟเวอร์ระบบคลาวด์ที่ไม่รองรับรูปแบบวิดีโอที่ทันสมัย
อย่าแปลงเมื่อเปิดไฟล์วิดีโอเพื่อเล่นในอุปกรณ์หรือเพื่อสร้างภาพขนาดย่อ
การกำหนดค่าการแปลง
แอปสามารถควบคุมลักษณะการทำงานของการแปลงได้โดยประกาศความสามารถด้านสื่อ โดยประกาศความสามารถเหล่านี้ได้ 2 วิธี ได้แก่ ในโค้ดหรือในทรัพยากร
ประกาศความสามารถในโค้ด
คุณประกาศความสามารถด้านสื่อในโค้ดได้โดยสร้างอินสแตนซ์ของออบเจ็กต์ ApplicationMediaCapabilities โดยใช้ Builder ดังนี้
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 แอปบันทึกวิดีโอเริ่มการแปลง
แอปแชร์วิดีโอประกาศว่าไม่รองรับ HEVC ในไฟล์ทรัพยากรความสามารถด้านสื่อ
จากนั้นแอปจะขอวิดีโอจากแอปบันทึกวิดีโอ แอปบันทึกวิดีโอ
จะจัดการคำขอและเปิดไฟล์โดยใช้
openTypedAssetFileDescriptor พร้อมระบุ UID ของแอปแชร์ ซึ่งจะเริ่มกระบวนการแปลง
เมื่อได้รับวิดีโอที่แปลงแล้ว ระบบจะส่งวิดีโอดังกล่าวไปยังแอปแชร์ ซึ่งจะอัปโหลดวิดีโอไปยังเซิร์ฟเวอร์ในระบบคลาวด์
ตัวอย่างที่ 2 แอปแชร์วิดีโอเริ่มการแปลง
แอปบันทึกวิดีโอแชร์วิดีโอกับแอปแชร์วิดีโอโดยใช้
MediaStore URI แอปแชร์วิดีโอจะเปิดไฟล์วิดีโอโดยใช้ openTypedAssetFileDescriptor พร้อมระบุว่าไม่รองรับ HEVC ในความสามารถด้านสื่อ ซึ่งจะเริ่มกระบวนการแปลง และเมื่อเสร็จสมบูรณ์แล้ว ระบบจะอัปโหลดไฟล์ไปยังเซิร์ฟเวอร์ในระบบคลาวด์
รูปแบบที่ไม่ได้ประกาศ
ระบบจะเปิดใช้การแปลงสื่อเป็นรูปแบบที่เข้ากันได้สำหรับรูปแบบทั้งหมดที่ประกาศว่าไม่รองรับ และปิดใช้สำหรับรูปแบบทั้งหมดที่ประกาศว่ารองรับ สำหรับรูปแบบอื่นๆ ที่ไม่ได้ประกาศ แพลตฟอร์มจะเป็นผู้พิจารณาว่าจะแปลงหรือไม่ ใน Android 12 ระบบจะปิดใช้การแปลงสำหรับรูปแบบที่ไม่ได้ประกาศทั้งหมด ลักษณะการทำงานนี้อาจเปลี่ยนแปลงสำหรับรูปแบบใหม่ในอนาคต
ตัวเลือกสำหรับนักพัฒนาแอป
คุณสามารถใช้ตัวเลือกสำหรับนักพัฒนาแอปต่อไปนี้เพื่อลบล้างลักษณะการทำงานเริ่มต้นของการแปลงของ Android
ลบล้างค่าเริ่มต้นของการแปลง การตั้งค่านี้จะกำหนดว่าแพลตฟอร์มจะควบคุมการแปลงอัตโนมัติหรือไม่ เมื่อเปิดใช้การลบล้าง ระบบจะละเว้นค่าเริ่มต้นของแพลตฟอร์ม และการตั้งค่าเปิดใช้การแปลง จะควบคุมการแปลงอัตโนมัติ ตัวเลือกนี้ปิดอยู่โดยค่าเริ่มต้น
เปิดใช้การแปลง การตั้งค่านี้จะระบุว่าจะแปลงรูปแบบที่ไม่ได้ประกาศโดยอัตโนมัติหรือไม่ โดยเปิดใช้โดยค่าเริ่มต้น แต่จะมีผลก็ต่อเมื่อเปิดใช้ลบล้างค่าเริ่มต้นของการแปลง ด้วย
สันนิษฐานว่าแอปต่างๆ รองรับรูปแบบที่ทันสมัย การตั้งค่านี้จะควบคุมสิ่งที่เกิดขึ้นเมื่อแอปพยายามเล่นรูปแบบที่ไม่ได้ประกาศ ซึ่งจะเกิดขึ้นเมื่อไฟล์ Manifest ไม่ได้ประกาศว่าแอปรองรับรูปแบบใดรูปแบบหนึ่งหรือไม่ หรือ Google ยังไม่ได้เพิ่มแอปในรายการบังคับแปลงฝั่งเซิร์ฟเวอร์ เมื่อเปิดใช้การตั้งค่านี้ แอปจะไม่แปลง แต่เมื่อปิดใช้ แอปจะแปลง ตัวเลือกนี้เปิดอยู่โดยค่าเริ่มต้น
แสดงการแจ้งเตือนการแปลง เมื่อเปิดใช้ แอปจะแสดงการแจ้งเตือนความคืบหน้าของการแปลงเมื่อมีการอ่านไฟล์สื่อที่ไม่รองรับ ตัวเลือกนี้เปิดอยู่โดยค่าเริ่มต้น
ปิดใช้แคชสำหรับการแปลง หากเปิดใช้ แอปที่ต้องมีการแปลงจะไม่ใช้แคชสำหรับการแปลง ซึ่งอาจเป็นประโยชน์ในระหว่างการพัฒนาเพื่อเรียกใช้การแปลงในไฟล์สื่อที่ไม่รองรับได้อย่างง่ายดาย แต่ก็อาจทำให้ประสิทธิภาพของอุปกรณ์ลดลง ตัวเลือกนี้ปิดอยู่โดยค่าเริ่มต้น