ב-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 עובר קודינג מחדש ל-AVC בטלפון Pixel 3 תוך כ-20 שניות. לכן, כדאי לבצע המרה של קובץ וידאו רק כששולחים אותו מהמכשיר. לדוגמה, כשמשתפים קובץ וידאו עם משתמשים אחרים באותה אפליקציה, או עם שרת בענן שלא תומך בפורמטים מודרניים של וידאו.
אין לבצע המרה (טרנסקוד) כשיוצרים קובצי וידאו להפעלה במכשיר או כשיוצרים תמונות ממוזערות.
הגדרת המרת קידוד
אפליקציות יכולות לשלוט בהתנהגות שלהן בנושא המרת קוד על ידי הצהרה על יכולות המדיה שלהן. יש שתי דרכים להצהיר על היכולות האלה: בקוד או במשאב.
הצהרת יכולות בקוד
כדי להצהיר על יכולות מדיה בקוד, יוצרים מופע של אובייקט 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 (טווח דינמי סטנדרטי), אבל סרטוני HEVC לא עוברים המרה.
משתמשים בתג property
בתוך התג application
כדי להוסיף הפניה לקובץ של יכולות המדיה. מוסיפים את המאפיינים הבאים לקובץ AndroidManifest.xml
:
<property
android:name="android.media.PROPERTY_MEDIA_CAPABILITIES"
android:resource="@xml/media_capabilities" />
שימוש ביכולות המדיה של אפליקציה אחרת כדי לפתוח קובץ וידאו
אם האפליקציה שלכם משתפת קובץ וידאו עם אפליקציה אחרת, יכול להיות שתצטרכו לבצע המרה של קובץ הווידאו כדי שהאפליקציה המקבלת תוכל לפתוח אותו.
כדי לטפל במקרה כזה, פותחים קובץ וידאו באמצעות openTypedAssetFileDescriptor
ומציינים את ה-UID של האפליקציה המקבלת. אפשר לקבל את ה-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. ההמרה מקוד מופעל על ידי אפליקציית הצילום.
באפליקציית שיתוף הסרטונים מצוין בקובץ המשאב של יכולות המדיה שהיא לא תומכת ב-HEVC. לאחר מכן, היא מבקשת סרטון מאפליקציית הצילום. אפליקציית הצילום מטפלת בבקשה ופותחת את הקובץ באמצעות openTypedAssetFileDescriptor
, ומציינת את ה-UID של אפליקציית השיתוף. הפעולה הזו מפעילה את תהליך ההמרה.
כשהסרטון המקודד מתקבל, הוא מסופק לאפליקציית השיתוף, שמעלה אותו לשרת בענן.
דוגמה 2. ההמרה מקוד מתחילה באפליקציית שיתוף הסרטונים.
אפליקציית הצילום משתפת סרטון עם אפליקציית שיתוף הסרטונים באמצעות
MediaStore
URI. אפליקציית שיתוף הסרטונים פותחת את קובץ הווידאו באמצעות openTypedAssetFileDescriptor
, ומציינת שהיא לא תומכת ב-HEVC ביכולות המדיה שלה. הפעולה הזו מפעילה את תהליך ההמרה, ולאחר שהוא מסתיים הקובץ מועלה לשרת בענן.
פורמטים לא מוצהרים
המרת מדיה תואמת מופעלת לכל הפורמטים שלא הוגדרו כנתמכים, ומושבתת לכל הפורמטים שהוגדרו כנתמכים. בפורמטים אחרים שלא הוגדרו, הפלטפורמה מחליטה אם לבצע המרה או לא. ב-Android 12, ההמרה מקודק מושבתת לכל הפורמטים שלא צוינו. יכול להיות שההתנהגות הזו תשתנה בעתיד לגבי פורמטים חדשים.
אפשרויות למפתחים
אפשר להשתמש באפשרויות הבאות למפתחים כדי לשנות את התנהגות ברירת המחדל של Android בנושא המרה:
ביטול ברירות המחדל של המרת קידוד ההגדרה הזו קובעת אם הפלטפורמה תשלוט בהמרת הקידוד האוטומטית או לא. כשהאפשרות 'ביטול ברירות המחדל' מופעלת, המערכת מתעלמת מברירת המחדל של הפלטפורמה וההגדרה enable transcoding קובעת אם תתבצע המרת קידוד אוטומטית. האפשרות הזו מושבתת כברירת מחדל.
Enable transcoding (הפעלת המרת קידוד): ההגדרה הזו קובעת אם תבצע המרת קידוד אוטומטית של פורמטים לא מוצהרים. ההגדרה הזו מופעלת כברירת מחדל, אבל היא משפיעה רק אם ההגדרה שינוי ברירת המחדל של ההמרה מופעלת גם כן.
הנחת העבודה היא שאפליקציות תומכות בפורמטים מודרניים ההגדרה הזו קובעת מה יקרה כשהאפליקציה תנסה להפעיל פורמט לא מוגדר. המצב הזה מתרחש אם המניפסט לא מציין אם האפליקציה תומכת בפורמט מסוים או לא, או אם Google לא הוסיפה את האפליקציה לרשימת ההמרות הכפויות בצד השרת. כשההגדרה מופעלת, האפליקציה לא מבצעת המרה, וכשהיא מושבתת, האפליקציה מבצעת המרה. האפשרות הזו מופעלת כברירת מחדל.
הצגת התראות לגבי המרת קידוד כשהאפשרות הזו מופעלת, האפליקציה מציגה התראה על התקדמות ההמרה כשהיא מופעלת על ידי קריאת קובץ מדיה שאינו נתמך. האפשרות הזו מופעלת כברירת מחדל.
השבתת השמירה של המרת הקידוד במטמון אם ההגדרה הזו מופעלת, אפליקציות שדורשות המרת קידוד לא משתמשות במטמון של המרת הקידוד. האפשרות הזו יכולה לעזור במהלך הפיתוח כדי להפעיל בקלות המרה של קובץ מדיה שלא נתמך, אבל היא עלולה לגרום לביצועים נמוכים במכשיר. האפשרות הזו מושבתת כברירת מחדל.