клипы, применение видеоэффектов и оптимизация экспорта. keywords_public: Media3, Transformer, transcode, video editing, trimming, audio processing, Android media
Транскодирование между форматами
При сборке 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 автоматически переключается на трансмьюксирование , то есть копирование сжатых сэмплов из входного контейнера в выходной контейнер без изменений. Это позволяет избежать вычислительных затрат и потенциальной потери качества, связанных с декодированием и повторным кодированием в одном и том же формате.
Удалить аудио или видео
Удалять аудио или видео можно, используя EditedMediaItem.Builder , например:
Котлин
EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build()
Java
new EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build();
Обрезать клип
Вы можете удалить любые медиафайлы, выходящие за пределы указанных начальных и конечных временных меток, задав параметры обрезки для входного медиафайла. Например, чтобы создать клип, содержащий только медиафайлы в промежутке от 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
Для более быстрой обрезки Transformer поддерживает списки редактирования MP4, что позволяет более эффективно выполнять только обрезку без полного перекодирования видео. Этот метод использует существующие закодированные сэмплы и «предварительную вставку» в списке редактирования, которая указывает проигрывателю начать воспроизведение с определенной точки, фактически пропуская нежелательный начальный сегмент.
Чтобы значительно ускорить редактирование только фрагментов, вызовите метод experimentalSetMp4EditListTrimEnabled(true) .
Котлин
Transformer.Builder(context) .experimentalSetMp4EditListTrimEnabled(true) .build()
Java
new Transformer.Builder(context) .experimentalSetMp4EditListTrimEnabled(true) .build();
Важно отметить, что не все медиаплееры поддерживают позицию «pre-roll». Это означает, что при использовании такого плеера воспроизведение файла начнется с самого начала закодированного фрагмента, независимо от информации в списке правок, которая может указывать на другую начальную точку.
Оптимизация отделки
Чтобы уменьшить задержку при обрезке начала видео, включите оптимизацию обрезки.
Котлин
Transformer.Builder(context) .experimentalSetTrimOptimizationEnabled(true) .build()
Java
new Transformer.Builder(context) .experimentalSetTrimOptimizationEnabled(true) .build();
Это ускоряет экспорт за счет декодирования и повторного кодирования как можно меньшего объема видео, а затем сшивания повторно закодированных данных с остальной частью исходного видео. Оптимизация основана на возможности сшивания части входного файла с вновь закодированным выходным файлом, что означает, что выходной формат кодировщика и входной формат должны быть совместимы. Например, если файл изначально был создан на устройстве с другой реализацией кодировщика, то, вероятно, применение оптимизации будет невозможно. Для успешной оптимизации кодировщик, предоставленный Transformer через EncoderFactory должен иметь уровень и профиль, совместимые с входным форматом.
Эта оптимизация работает только с входными данными в формате MP4, содержащими один ресурс и не имеющими никаких эффектов, кроме видеоэффектов и поворотов, кратных 90 градусам. Если оптимизация не удается, Transformer автоматически возвращается к обычному экспорту и сообщает о результате оптимизации в ExportResult.OptimizationResult .
Мы проверяем эту функциональность и ожидаем, что в последующих версиях она перестанет быть экспериментальной.
Видеомонтаж
Библиотека 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();
Пользовательские видеоэффекты
Конструктор Effects принимает список аудио- и видеоэффектов для применения. Внутри фреймворк эффектов Transformer преобразует список видеоэффектов в последовательность шейдерных программ GL, которые применяются в указанном порядке. В некоторых случаях фреймворк эффектов может применять несколько эффектов с помощью одной шейдерной программы. Например, одна шейдерная программа может применять несколько последовательных матричных преобразований, что повышает эффективность и качество.
В ExoPlayer также поддерживаются видеоэффекты для предварительного просмотра с помощью ExoPlayer.setVideoEffects . Пример использования этого API можно посмотреть в демонстрационном приложении с эффектами .
Демонстрационное приложение включает примеры пользовательских видеоэффектов.
Ввод изображения
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 , что позволяет предварительно просматривать изменения в аудио.