Su Android 12 (livello API 31) e versioni successive, il sistema può convertire automaticamente i video registrati in formati come HEVC (H.265) in AVC (H.264) quando i video vengono aperti da un'app che non supporta HEVC. Questa funzionalità consente alle app di acquisizione video di utilizzare una codifica più moderna ed efficiente in termini di spazio di archiviazione per i video registrati sul dispositivo senza sacrificare la compatibilità con altre app.
I seguenti formati possono essere transcodificati automaticamente per i contenuti creati sul dispositivo:
Formato multimediale | Attributo XML | Tipo MIME MediaFormat |
---|---|---|
HEVC (H.265) | HEVC | MediaFormat.MIMETYPE_VIDEO_HEVC |
HDR10 | HDR10 | MediaFeature.HdrType.HDR10 |
HDR10+ | HDR10+ | MediaFeature.HdrType.HDR10_PLUS |
Android presuppone che le app possano supportare la riproduzione di tutti i formati multimediali, pertanto la transcodifica multimediale compatibile è disattivata per impostazione predefinita.
Quando utilizzare la transcodifica
La transcodifica è un'operazione costosa dal punto di vista computazionale e aggiunge un ritardo significativo all'apertura di un file video. Ad esempio, un file video HEVC di un minuto richiede circa 20 secondi per la transcodifica in AVC su uno smartphone Pixel 3. Per questo motivo, devi transcodificare un file video solo quando lo invii dal dispositivo. Ad esempio, quando condividi un file video con altri utenti della stessa app o con un server cloud che non supporta i formati video moderni.
Non eseguire la transcodifica quando apri file video per la riproduzione sul dispositivo o per creare immagini in miniatura.
Configurazione della transcodifica
Le app possono controllare il proprio comportamento di transcodifica dichiarando le proprie funzionalità multimediali. Esistono due modi per dichiarare queste funzionalità: nel codice o in una risorsa.
Dichiarare le funzionalità nel codice
Puoi dichiarare le funzionalità multimediali nel codice creando un'istanza di un oggetto
ApplicationMediaCapabilities
utilizzando un 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();
Utilizza questo oggetto quando accedi ai contenuti multimediali tramite metodi come
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. }
Questo metodo consente un controllo granulare per percorsi di codice specifici, ad esempio l'invocazione della transcodifica solo quando si trasferisce un file video dal dispositivo. Ha la precedenza sul metodo descritto di seguito.
Dichiarare le funzionalità in una risorsa
La dichiarazione delle funzionalità in una risorsa consente il controllo generale della transcodifica. Questo metodo deve essere utilizzato solo in casi molto specifici. Ad esempio, se la tua app riceve solo file video da altre app (anziché aprirli direttamente) e li carica su un server che non supporta i codec video moderni (vedi lo scenario di esempio 1 di seguito).
L'utilizzo di questo metodo quando non è assolutamente necessario potrebbe attivare la transcodifica in scenari non previsti, ad esempio durante la creazione delle miniature dei video, con conseguente peggioramento dell'esperienza utente.
Per utilizzare questo metodo, crea un file di risorse 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>
In questo esempio, i video HDR registrati sul dispositivo vengono transcodificati senza problemi in video AVC SDR (standard dynamic range), mentre i video HEVC non vengono transcodificati.
Utilizza un tag property
all'interno del tag application
per aggiungere un riferimento al file delle funzionalità multimediali. Aggiungi queste proprietà al tuo file AndroidManifest.xml
:
<property
android:name="android.media.PROPERTY_MEDIA_CAPABILITIES"
android:resource="@xml/media_capabilities" />
Utilizzo delle funzionalità multimediali di un'altra app per aprire un file video
Se la tua app condivide un file video con un'altra app, potrebbe essere necessario eseguire la transcodifica del file video prima che l'app ricevente possa aprirlo.
Puoi gestire questo caso aprendo un file video utilizzando openTypedAssetFileDescriptor
e specificando l'UID dell'app ricevente, che può essere ottenuto utilizzando Binder.getCallingUid
.
La piattaforma utilizza quindi le funzionalità multimediali dell'app di ricezione per determinare
se il file video deve essere transcodificato.
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. }
Scenari di esempio
I seguenti diagrammi mostrano i due casi d'uso comuni. In entrambi i casi, il video originale viene memorizzato in formato HEVC e l'app di condivisione video non supporta HEVC.
Esempio 1. La transcodifica viene avviata dall'app di acquisizione video.
L'app di condivisione video dichiara di non supportare HEVC nel file di risorse delle funzionalità multimediali. Quindi, richiede un video all'app di acquisizione video. L'app di acquisizione video
gestisce la richiesta e apre il file utilizzando
openTypedAssetFileDescriptor
, specificando l'UID dell'app di condivisione. In questo modo viene avviato il processo di transcodifica.
Quando il video transcodificato viene ricevuto, viene fornito all'app di condivisione, che lo carica su un server nel cloud.
Esempio 2. La transcodifica viene avviata dall'app di condivisione video.
L'app di acquisizione video condivide un video con l'app di condivisione video utilizzando un URI
MediaStore
. L'app di condivisione video apre il file video utilizzando openTypedAssetFileDescriptor
, specificando che non supporta HEVC nelle sue funzionalità multimediali. Inizia
il processo di transcodifica e, una volta completato, il file viene caricato su
un server nel cloud.
Formati non dichiarati
La transcodifica dei contenuti multimediali compatibili è abilitata per tutti i formati dichiarati non supportati ed è disabilitata per tutti i formati dichiarati supportati. Per gli altri formati non dichiarati, la piattaforma decide se eseguire la transcodifica o meno. In Android 12 la transcodifica è disattivata per tutti i formati non dichiarati. Questo comportamento potrebbe cambiare per i nuovi formati in futuro.
Opzioni sviluppatore
Puoi utilizzare le seguenti opzioni sviluppatore per ignorare il comportamento di transcodifica predefinito di Android:
Sostituisci impostazioni predefinite transcodifica Questa impostazione determina se la piattaforma controlla o meno la transcodifica automatica. Quando l'override è abilitato, le impostazioni predefinite della piattaforma vengono ignorate e l'impostazione Attiva transcodifica controlla la transcodifica automatica. Questa opzione è disattivata per impostazione predefinita.
Attiva la transcodifica. Questa impostazione specifica se i formati non dichiarati vengono transcodificati automaticamente. È attivata per impostazione predefinita, ma ha effetto solo se è attivata anche l'opzione Override delle impostazioni di transcodifica predefinite.
Presupponi che le app supportino i formati moderni Questa impostazione controlla cosa succede quando l'app tenta di riprodurre un formato non dichiarato. Ciò si verifica quando il manifest non dichiara se l'app supporta o meno un determinato formato oppure Google non ha aggiunto l'app all'elenco di transcodifica forzata lato server. Quando l'impostazione è attiva, l'app non esegue la transcodifica, mentre quando è disattivata, l'app esegue la transcodifica. Questa opzione è attiva per impostazione predefinita.
Mostra notifiche relative alla transcodifica. Se questa opzione è abilitata, l'app mostra una notifica di avanzamento della transcodifica quando questa viene attivata dalla lettura di un file multimediale non supportato. Questa opzione è attiva per impostazione predefinita.
Disattiva memorizzazione nella cache per la transcodifica Se questa opzione è attivata, le app che richiedono la transcodifica non utilizzano la memorizzazione nella cache per la transcodifica. Questa operazione può essere utile durante lo sviluppo per attivare facilmente la transcodifica di un file multimediale non supportato, ma può causare prestazioni scadenti del dispositivo. Questa opzione è disattivata per impostazione predefinita.