تراتبدیل رسانه سازگار

در Android 12 (سطح API‏ ۳۱) و بالاتر، وقتی ویدیوها با برنامه‌ای باز می‌شوند که از HEVC پشتیبانی نمی‌کند، سیستم می‌تواند به‌طور خودکار ویدیوهای ضبط‌شده در قالب‌هایی مانند HEVC (H.265)‎ را به AVC (H.264)‎ تبدیل کند. این ویژگی به برنامه‌های ضبط ویدیو امکان می‌دهد از کدبندی مدرن‌تر و با مصرف فضای ذخیره‌سازی کمتر برای ویدیوهای ضبط‌شده در دستگاه استفاده کنند، بدون اینکه سازگاری با برنامه‌های دیگر را ازدست بدهند.

قالب‌های زیر را می‌توان به‌طور خودکار برای محتوایی که در دستگاه ایجاد شده است تراتبدیل کرد:

قالب رسانه مشخصه XML نوع رسانه MediaFormat
HEVC (H.265) HEVC MediaFormat.MIMETYPE_VIDEO_HEVC
HDR10HDR10 MediaFeature.HdrType.HDR10
HDR10+‎ HDR10Plus MediaFeature.HdrType.HDR10_PLUS

Android فرض می‌کند که برنامه‌ها می‌توانند از بازپخش همه قالب‌های رسانه پشتیبانی کنند، بنابراین تراتبدیل رسانه سازگار به‌طور پیش‌فرض خاموش است.

زمان استفاده از تراتبدیل

تراتبدیل عملیاتی با هزینه محاسباتی بالا است و هنگام باز کردن فایل ویدیویی، تأخیر قابل‌توجهی ایجاد می‌کند. برای مثال، تراتبدیل یک فایل ویدیویی HEVC یک دقیقه‌ای به AVC در تلفن Pixel 3 تقریباً ۲۰ ثانیه طول می‌کشد. به همین دلیل، فقط زمانی باید فایل ویدیویی را تراتبدیل کنید که آن را از دستگاه ارسال می‌کنید. برای مثال، هنگام هم‌رسانی فایل ویدیویی با دیگر کاربران همان برنامه، یا سرور ابری که از قالب‌های ویدیویی مدرن پشتیبانی نمی‌کند.

هنگام باز کردن فایل‌های ویدیویی برای بازپخش در دستگاه یا برای ایجاد تصاویر کوچک، تراتبدیل نکنید.

پیکربندی تراتبدیل

برنامه‌ها می‌توانند با اعلام قابلیت‌های رسانه‌ای خود، رفتار تراتبدیلشان را کنترل کنند. دو روش برای اعلام این قابلیت‌ها وجود دارد: در کد، یا در منبع.

اعلام کردن قابلیت‌ها در کد

می‌توانید قابلیت‌های رسانه را در کد با ساختن نمونه‌ای از یک شیء ApplicationMediaCapabilities بااستفاده از سازنده اعلام کنید:

کاتلین

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

جاوا

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

هنگام دسترسی به محتوای رسانه ازطریق روش‌هایی مانند ContentResolver#openTypedAssetFileDescriptor()، از این شیء استفاده کنید:

کاتلین

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.
    }

جاوا

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.
}

این روش امکان کنترل دقیق مسیرهای کد خاص را فراهم می‌کند، مثلاً فراخوانی تراتبدیل فقط هنگام انتقال فایل ویدیویی به خارج از دستگاه. این روش بر روشی که در زیر شرح داده شده است اولویت دارد.

اعلام قابلیت‌ها در منبع

اعلام قابلیت‌ها در یک منبع امکان کنترل کلی بر تراتبدیل را فراهم می‌کند. این روش فقط باید در موارد بسیار خاص استفاده شود. برای مثال، اگر برنامه شما فقط فایل‌های ویدیویی را از برنامه‌های دیگر دریافت می‌کند (به‌جای اینکه آن‌ها را مستقیماً باز کند) و آن‌ها را در سروری بارگذاری می‌کند که از کدک‌های ویدیویی مدرن پشتیبانی نمی‌کند (به سناریو نمونه ۱ در زیر مراجعه کنید).

استفاده از این روش در مواقعی که کاملاً ضروری نیست ممکن است باعث فراخوانی تراتبدیل در سناریوهای ناخواسته شود، مثلاً هنگام ایجاد ریزعکس برای ویدیوها، که منجر به تجربه کاربری ضعیف می‌شود.

برای استفاده از این روش، فایل منبع 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 و مشخص کردن شناسه کاربری برنامه گیرنده که بااستفاده از Binder.getCallingUid قابل دریافت است مدیریت کنید. سپس پلاتفرم از قابلیت‌های رسانه‌ای برنامه گیرنده استفاده می‌کند تا تعیین کند آیا فایل ویدیویی باید تراتبدیل شود یا نه.

کاتلین

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.
    }

جاوا

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 پشتیبانی نمی‌کند.

نمونه ۱. تراتبدیل توسط برنامه ضبط ویدیو آغاز می‌شود. مثال ۱ برنامه هم‌رسانی ویدیو اعلام می‌کند که از HEVC در فایل منبع قابلیت‌های رسانه‌ای خود پشتیبانی نمی‌کند. سپس ویدیویی را از برنامه ضبط ویدیو درخواست می‌کند. برنامه ضبط ویدیو درخواست را مدیریت می‌کند و فایل را بااستفاده از openTypedAssetFileDescriptor باز می‌کند و شناسه کاربری برنامه هم‌رسانی را مشخص می‌کند. با این کار فرایند تراتبدیل آغاز می‌شود. وقتی ویدیو تراتبدیل‌شده دریافت می‌شود، به برنامه هم‌رسانی ارائه می‌شود و برنامه آن را در سروری در فضای ابری بارگذاری می‌کند.

نمونه ۲. تراتبدیل توسط برنامه هم‌رسانی ویدیو آغاز می‌شود. مثال ۲ برنامه ضبط ویدیو بااستفاده از MediaStore URI، ویدیویی را با برنامه هم‌رسانی ویدیو هم‌رسانی می‌کند. برنامه هم‌رسانی ویدیو فایل ویدیو را بااستفاده از openTypedAssetFileDescriptor باز می‌کند و مشخص می‌کند که از HEVC در قابلیت‌های رسانه‌ای خود پشتیبانی نمی‌کند. این کار فرایند تراتبدیل را آغاز می‌کند و پس‌از تکمیل، فایل در سروری در فضای ابری بارگذاری می‌شود.

قالب‌های اعلام‌نشده

تراتبدیل رسانه سازگار برای همه قالب‌هایی که اعلام شده است پشتیبانی نمی‌شوند فعال است و برای همه قالب‌هایی که اعلام شده است پشتیبانی می‌شوند غیرفعال است. برای قالب‌های دیگری که اعلام نشده‌اند، پلتفرم تصمیم می‌گیرد که تراتبدیل انجام شود یا نه. در Android 12، تراتبدیل برای همه قالب‌های اعلام‌نشده غیرفعال است. این رفتار ممکن است برای قالب‌های جدید در آینده تغییر کند.

گزینه‌های توسعه‌دهندگان

می‌توانید از گزینه‌های توسعه‌دهنده زیر برای لغو کردن رفتار تراتبدیل پیش‌فرض Android استفاده کنید:

  • لغو پیش‌فرض‌های تراتبدیل این تنظیم تعیین می‌کند که آیا پلاتفرم تراتبدیل خودکار را کنترل می‌کند یا نه. وقتی لغو کردن فعال باشد، پیش‌فرض‌های پلاتفرم نادیده گرفته می‌شود و تنظیم فعال کردن تراتبدیل تراتبدیل خودکار را کنترل می‌کند. این گزینه به‌طور پیش‌فرض غیرفعال است.

  • فعال کردن تراتبدیل این تنظیم مشخص می‌کند که آیا قالب‌های اعلام‌نشده به‌طور خودکار تراتبدیل شوند یا نه. این گزینه به‌طور پیش‌فرض فعال است، اما فقط درصورتی تأثیر دارد که لغو پیش‌فرض‌های تراتبدیل نیز فعال باشد.

  • فرض کنید برنامه‌ها از قالب‌های مدرن پشتیبانی می‌کنند این تنظیمات کنترل می‌کند که وقتی برنامه سعی می‌کند قالب اعلام‌نشده‌ای را پخش کند چه اتفاقی می‌افتد. این اتفاق زمانی می‌افتد که مانیفست اعلام نمی‌کند که برنامه از قالب خاصی پشتیبانی می‌کند یا نه، یا Google برنامه را به فهرست تراتبدیل اجباری سمت سرور اضافه نکرده است. وقتی تنظیم فعال باشد، برنامه تراتبدیل نمی‌کند، وقتی غیرفعال باشد، برنامه تراتبدیل می‌کند. این گزینه به‌طور پیش‌فرض فعال است.

  • نمایش اعلان‌های تراتبدیل وقتی فعال باشد، برنامه اعلان پیشرفت تراتبدیل را هنگام شروع تراتبدیل به‌دلیل خواندن فایل رسانه‌ای پشتیبانی‌نشده نمایش می‌دهد. این گزینه به‌طور پیش‌فرض فعال است.

  • غیرفعال کردن حافظه پنهان تراتبدیل اگر فعال باشد، برنامه‌هایی که به تراتبدیل نیاز دارند از حافظه پنهان تراتبدیل استفاده نمی‌کنند. این کار می‌تواند درطول توسعه مفید باشد تا به‌راحتی تراتبدیل را در فایل رسانه‌ای پشتیبانی‌نشده راه‌اندازی کنید، اما می‌تواند باعث عملکرد ضعیف دستگاه شود. این گزینه به‌طور پیش‌فرض غیرفعال است.