המרת קידוד תואמת של מדיה

ב-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 באורך דקה לוקח כ-20 שניות לפני המרת הקידוד ל-AVC בטלפון Pixel 3. לכן, יש להמיר קידוד של קובץ וידאו רק כאשר אתם שולחים אותו במכשיר. לדוגמה, כשמשתפים קובץ וידאו עם משתמשים אחרים באותו אתר אפליקציה, או שרת ענן שלא תומך בווידאו מודרני פורמטים.

אין להמיר את הקידוד כשפותחים קובצי וידאו להפעלה במכשיר או ליצירת תמונות ממוזערות.

הגדרה של המרת קידוד

אפליקציות יכולות לשלוט בהתנהגות הקידוד שלהן על ידי הצהרה על המדיה שלהן יכולות. יש שתי דרכים להצהיר על היכולות האלה: בקוד, או במשאב.

הצהרה על יכולות בקוד

אפשר להצהיר על יכולות מדיה בקוד על ידי בניית מופע של אובייקט 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 (טווח דינמי סטנדרטי) ואילו סרטוני 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.
}

תרחישים לדוגמה

התרשימים הבאים מדגימים את שני תרחישי השימוש הנפוצים. בשני המקרים הסרטון המקורי שמור בפורמט HEVC ואפליקציית שיתוף הסרטון לא תומכים ב-HEVC.

דוגמה 1. המרת הקידוד מתחילה על ידי אפליקציית צילום וידאו. דוגמה 1 אפליקציית שיתוף הסרטונים מצהירה שהיא לא תומכת ב-HEVC במדיה שלה קובץ משאב של יכולות. לאחר מכן הוא מבקש סרטון מאפליקציית צילום הווידאו. צילום הסרטון האפליקציה מטפלת בבקשה ופותח את הקובץ באמצעות openTypedAssetFileDescriptor, שמציין את ה-UID של האפליקציה המשותפת. תתחיל תהליך המרת הקידוד. כשמתקבל הסרטון שהקידוד שלו הומר, הוא מסופק לאפליקציית השיתוף, ומעלה אותו לשרת בענן.

דוגמה 2. המרת הקידוד מתחילה על ידי אפליקציית שיתוף הסרטונים. דוגמה 2 אפליקציית צילום הווידאו משתפת סרטון עם האפליקציה לשיתוף סרטונים באמצעות URI של MediaStore. אפליקציית שיתוף הסרטונים פותחת את קובץ הסרטון באמצעות openTypedAssetFileDescriptor, ומציינת שהוא לא תומך ב-HEVC ביכולות המדיה שלה. הזה מתחיל תהליך המרת הקידוד, וכשהקובץ מסתיים, מועלה שרת בענן.

פורמטים לא מוצהרים

המרת קידוד של מדיה תואמת מופעלת בכל הפורמטים שהוצהרו. היא מושבתת בכל הפורמטים שהוצהרו כנתמכים. עבור בפורמטים אחרים שלא הוצהרו, הפלטפורמה מחליטה אם להמיר את הקידוד או לא. ב-Android 12 המרת קידוד מושבתת בכל הפורמטים הלא מוצהרים. ההתנהגות הזו עשויה להשתנות בפורמטים חדשים העתידי.

אפשרויות למפתחים

אפשר להשתמש באפשרויות הפיתוח הבאות כדי לשנות את ברירת המחדל של Android ההתנהגות של המרת הקידוד:

  • ביטול ברירות המחדל של המרת קידוד ההגדרה הזו קובעת אם הפלטפורמה שולטת בהמרת הקידוד האוטומטית. במקרה של שינוי מברירת המחדל מופעלת, המערכת תתעלם מברירות המחדל של הפלטפורמה וההפעלה של המרת קידוד שולטת בהמרת הקידוד האוטומטית. האפשרות הזו מושבתת על ידי כברירת מחדל.

  • הפעלת המרת קידוד ההגדרה הזו מציינת אם תוכן לא מוצהר המרת הקידוד מתבצעת באופן אוטומטי. היא מופעלת כברירת מחדל, אבל יש השפעה אם מופעלת גם האפשרות ביטול ברירות מחדל של המרת קידוד.

  • בהנחה שאפליקציות תומכות בפורמטים מודרניים ההגדרה הזו קובעת מה קורה האפליקציה תנסה להפעיל פורמט לא מוצהר. הדבר קורה כאשר המניפסט לא מצהירים אם האפליקציה תומכת בפורמט מסוים, או לא הוסיף את האפליקציה לרשימת הכוח של המרת הקידוד בצד השרת. כאשר ההגדרה מופעלת, האפליקציה לא מבצעת המרת קידוד. כשהיא מושבתת, האפליקציה להמיר את הקידוד. האפשרות הזו מופעלת כברירת מחדל.

  • הצגת התראות לגבי המרת קידוד כשהאפשרות הזו מופעלת, האפליקציה מציגה התראה על התקדמות המרת הקידוד כאשר המרת קידוד מופעלת על ידי קריאת קובץ המדיה אינו נתמך. האפשרות הזו מופעלת כברירת מחדל.

  • השבתת המטמון של המרת הקידוד אם ההגדרה מופעלת, אפליקציות שדורשות המרת קידוד לא משתמשים במטמון להמרת הקידוד. זה יכול להיות שימושי במהלך הפיתוח, הפעלה של המרת קידוד בקובץ מדיה שלא נתמך, אבל עלולה לגרום לפגיעה במכשיר או של ביצועים. האפשרות הזו מושבתת כברירת מחדל.