Транскодирование между форматами
При сборке Transformer вы можете указать желаемые форматы выходного аудио и видео. Например, следующий код показывает, как настроить Transformer для вывода видео в формате H.264/AVC и аудио в формате AAC:
Котлин
Transformer.Builder(context)
.setVideoMimeType(MimeTypes.VIDEO_H264)
.setAudioMimeType(MimeTypes.AUDIO_AAC)
.build() Java
new Transformer.Builder(context)
.setVideoMimeType(MimeTypes.VIDEO_H264)
.setAudioMimeType(MimeTypes.AUDIO_AAC)
.build(); Если формат входного медиафайла уже соответствует конфигурациям для аудио или видео, Transformer автоматически переключается на _трансмьюксирование_, то есть копирование сжатых сэмплов из входного контейнера в выходной контейнер без изменений. Это позволяет избежать вычислительных затрат и потенциальной потери качества при декодировании и повторном кодировании в одном и том же формате. ## Удаление аудио или видео {: #remove-audio-video} Удалите аудио или видео с помощью `EditedMediaItem.Builder`, например:
Котлин
EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build()
Java
new EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build();
## Обрезка клипа {: #trim } Вы можете удалить любые медиафайлы, выходящие за пределы указанных начальных и конечных временных меток, задав параметры обрезки для входного медиафайла. Например, чтобы создать клип, содержащий только медиафайлы в промежутке от 10 до 20 секунд:
Котлин
val inputMediaItem = MediaItem.Builder()
.setUri(uri)
.setClippingConfiguration(
MediaItem.ClippingConfiguration.Builder()
.setStartPositionMs(10_000)
.setEndPositionMs(20_000)
.build())
.build() Java
MediaItem inputMediaItem =
new MediaItem.Builder()
.setUri(uri)
.setClippingConfiguration(
new MediaItem.ClippingConfiguration.Builder()
.setStartPositionMs(10_000)
.setEndPositionMs(20_000)
.build())
.build(); ## Списки редактирования MP4 {: #mp4-edit-lists } Для более быстрой обрезки Transformer поддерживает списки редактирования MP4, что позволяет более эффективно выполнять редактирование только «обрезкой» без полного перекодирования видео. Этот метод использует существующие закодированные сэмплы и «предварительный просмотр» в списке редактирования, который указывает проигрывателю начать воспроизведение с определенной точки, фактически пропуская нежелательный начальный сегмент. Чтобы значительно ускорить редактирование только «обрезкой», вызовите `experimentalSetMp4EditListTrimEnabled(true)`.
Котлин
Transformer.Builder(context)
.experimentalSetMp4EditListTrimEnabled(true)
.build() Java
new Transformer.Builder(context)
.experimentalSetMp4EditListTrimEnabled(true)
.build(); Важно отметить, что не все медиаплееры поддерживают позицию «pre-roll». Это означает, что при использовании такого плеера воспроизведение файла начнется с самого начала закодированного фрагмента, независимо от информации в списке правок, которая может указывать на другую начальную точку. Внимание: обрезка видео часто подразумевает безвозвратное удаление ненужных фрагментов. Однако использование списков правок создает риск для конфиденциальности: пользователи могут неосознанно делиться конфиденциальной, «удаленной» информацией, «скрытой» позицией «pre-roll». ## Оптимизация обрезки {: #trim-optimization } Чтобы уменьшить задержку при обрезке начала видео, включите оптимизацию обрезки.
Котлин
Transformer.Builder(context)
.experimentalSetTrimOptimizationEnabled(true)
.build() Java
new Transformer.Builder(context)
.experimentalSetTrimOptimizationEnabled(true)
.build(); Это ускоряет экспорт за счет декодирования и перекодирования как можно меньшего объема видео, а затем сшивания перекодированных данных с остальной частью исходного видео. Оптимизация основана на возможности сшивания части входного файла с новым закодированным выходным файлом, что означает, что выходной формат кодировщика и входной формат должны быть совместимы. Например, если файл изначально был создан на устройстве с другой реализацией кодировщика, то, вероятно, применение оптимизации будет невозможно. Для успешной оптимизации кодировщик, предоставленный Transformer через `EncoderFactory`, должен иметь уровень и профиль, совместимые с входным форматом. Эта оптимизация работает только с входным файлом MP4 с одним ресурсом без эффектов, за исключением видеоэффектов и поворотов, кратных 90 градусам. Если оптимизация не удается, Transformer автоматически возвращается к обычному экспорту и сообщает о результате оптимизации в `ExportResult.OptimizationResult`. Мы проверяем эту функциональность и ожидаем, что она станет неэкспериментальной в одном из последующих релизов. ## Редактирование видео {: #video-edits } `EditedMediaItems` содержат списки аудиопроцессоров и видеоэффектов, которые можно применять по порядку. Библиотека включает в себя реализации видеоэффектов для распространенных сценариев использования, или вы можете написать собственные эффекты и передать их при создании редактируемых медиафайлов. Вы можете масштабировать медиафайлы, что может быть полезно для экономии вычислительных ресурсов или полосы пропускания при работе с входным видео очень высокого разрешения, например, 4K или 8K. Например, для пропорционального масштабирования до высоты 480 пикселей:
Котлин
EditedMediaItem.Builder(MediaItem.fromUri(uri))
.setEffects(Effects(
/* audioProcessors= */ listOf(),
/* videoEffects= */ listOf(Presentation.createForHeight(480))
)).build() Java
new EditedMediaItem.Builder(MediaItem.fromUri(uri))
.setEffects(new Effects(
/* audioProcessors= */ ImmutableList.of(),
/* videoEffects= */ ImmutableList.of(Presentation.createForHeight(480))))
.build(); В качестве альтернативы, вы можете масштабировать изображение с заданным коэффициентом, например, чтобы уменьшить размер вдвое:
Котлин
val editedMediaItem = EditedMediaItem.Builder(MediaItem.fromUri(uri))
.setEffects(Effects(
/* audioProcessors= */ listOf(),
/* videoEffects= */ listOf(
ScaleAndRotateTransformation.Builder().setScale(.5f, .5f).build())
)).build() Java
new EditedMediaItem.Builder(MediaItem.fromUri(uri))
.setEffects(new Effects(
/* audioProcessors= */ ImmutableList.of(),
/* videoEffects= */ ImmutableList.of(
new ScaleAndRotateTransformation.Builder().setScale(.5f, .5f).build())))
.build(); Поворот можно настроить аналогичным образом:
Котлин
EditedMediaItem.Builder(MediaItem.fromUri(uri))
.setEffects(Effects(
/* audioProcessors= */ listOf(),
/* videoEffects= */ listOf(
ScaleAndRotateTransformation.Builder()
.setRotationDegrees(90f)
.build())
)).build() Java
new EditedMediaItem.Builder(MediaItem.fromUri(uri))
.setEffects(new Effects(
/* audioProcessors= */ ImmutableList.of(),
/* videoEffects= */ ImmutableList.of(
new ScaleAndRotateTransformation.Builder().setRotationDegrees(90f).build())))
.build(); ### Пользовательские видеоэффекты {: #custom-video } Конструктор `Effects` принимает список аудио- и видеоэффектов для применения. Внутри фреймворк эффектов Transformer преобразует список видеоэффектов в последовательность программ шейдеров GL, которые применяются по порядку. В некоторых случаях фреймворк эффектов может применять несколько эффектов с помощью одной программы шейдера. Например, одна программа шейдера может применять несколько последовательных матричных преобразований, что повышает эффективность и качество. Видеоэффекты также поддерживаются для предварительного просмотра в ExoPlayer с помощью `ExoPlayer.setVideoEffects`. Пример использования этого API можно посмотреть в [демо-приложении эффектов][effect-demo-app]. [Демо-приложение](demo-application) включает примеры пользовательских видеоэффектов. ## Ввод изображений {: #image-input } Transformer поддерживает ввод изображений, рассматривая их как статические видеоклипы. Чтобы настроить изображение в качестве источника входного сигнала, выполните следующие действия: * Создайте объект `MediaItem` с помощью `MediaItem.Builder`. Укажите длительность отображения изображения в выходном видео, вызвав `setImageDurationMs`. * Создайте объект `EditedMediaItem`, обертывающий `MediaItem`. Укажите целевую частоту кадров для генерируемого видеопотока, используя `EditedMediaItem.Builder#setFrameRate`. Следующий пример демонстрирует, как настроить входное изображение для генерации 5-секундного видео с частотой 30 кадров в секунду:
Котлин
val imageMediaItem = MediaItem.Builder()
.setUri(imageUri)
.setImageDurationMs(5000) // 5 seconds
.build()
val editedImageItem = EditedMediaItem.Builder(imageMediaItem)
.setFrameRate(30) // 30 frames per second
.build() Java
MediaItem imageMediaItem = new MediaItem.Builder()
.setUri(imageUri)
.setImageDurationMs(5000) // 5 seconds
.build();
EditedMediaItem editedImageItem = new EditedMediaItem.Builder(imageMediaItem)
.setFrameRate(30) // 30 frames per second
.build(); Редактирование аудио
Звуковые эффекты реализуются путем применения последовательности экземпляров AudioProcessor к необработанному (PCM) аудио. ExoPlayer поддерживает передачу аудиопроцессоров в DefaultAudioSink.Builder , что позволяет предварительно просматривать изменения в аудио.