FFmpeg | Выбор потоков (map)

от
FFmpeg    выбор потоков, stream mapping, map, перенести звук

Выбор потоков может потребоваться для создания копии файла с нужными потоками или для случаев, когда нужно скопировать видео- или аудиодорожку из одного файла в другой.

Форматы
-map индекс — выбирает все потоки указанного файла (-map 1)
-map индекс:тип_потока — выбирает все потоки заданного типа (-map 1:v)
-map индекс:номер_потока — выбирает конкретный поток по номеру (-map 1:0)
-map индекс:тип_потока:номер_потока — выбирает конкретный поток по номеру и с указанным типом (-map 1:v:0)
В качестве индекса может быть число или название потока, которое мы задаём в -vf / -filter_complex.
Если указать отрицательный индекс, поток будет исключён (-map -0:v)


Тип потока может быть:
  - v (video) — видео (включая обложки, статичные изображения)
  - V (video) — видео (только видео, не изображения)
  - a (audio) — аудио
  - s (subtitles) — субтитры
  - d (data) — данные
  - t (attachment) — вложения

Есть видео без звука и отдельная звуковая дорожка в mp3. Объединить эти два потока в видео со звуком:
  1. ffmpeg -i input.mp4 -i audio.mp3 -c:v copy -map 1:a result.mp4

Если звуковая дорожка окажется длиннее, чем видео, то по окончанию видео будет чёрный экран, а звук продолжится. Чтобы ограничить результат по длинне самого короткого потока, используется ключ -shortest

Даны два mp4 видео, заменить звук во втором видео звуком из первого видео без перекодирования:
  1. ffmpeg -i a.mp4 -i b.mp4 -map 0:a -map 1:v -c copy -shortest b_result.mp4

Дано видео со звуком и отдельный mp3 файл. Добавить звуковую дорожку в видео второй дорожкой так, чтобы было два аудиопотока.
  1. ffmpeg -i input.mp4 -i audio.mp3 -map 0 -map 1:a -c:v copy result.mp4

Есть mkv-файл в котором одна видеодорожка, две аудиодорожки с разными озвучками и один поток субтитров.
  1. ffmpeg -i input.mkv
  2.  
  3.   Duration: 00:50:28.07, start: 0.000000, bitrate: 2104 kb/s
  4.     Stream #0:0: Video: h264 (High), yuv420p(progressive), 1280x720, SAR 1:1 DAR 16:9, 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc (default)
  5.    Stream #0:1(rus): Audio: aac (LC), 48000 Hz, stereo, fltp (default)
  6.    Stream #0:2: Audio: aac (LC), 48000 Hz, stereo, fltp
  7.    Stream #0:3: Subtitle: ass (default)
Нужно вшить субтитры и сформировать два mp4-видео с разными озвучками.
Решение:
1. Вытаскиваем файл субтитров из контейнера в отдельный файл
  1. ffmpeg -i input.mkv 1.ass
2. Применяем фильтр ass, раздваиваем видеопоток (по одному на каждый файл результата) и выбираем нужный поток аудио с копированием
  1. ffmpeg -i input.mkv ^
  2.     -filter_complex ass=1.ass,split[v1][v2] ^
  3.     -map "[v1]" -map 0:a:0 -c:a copy v1.mp4 ^
  4.     -map "[v2]" -map 0:a:1 -c:a copy v2.mp4
Раздваивать потоки обязательно, иначе видео с хардсабом пойдёт только в первый файл.
Перед началом обработки ffmpeg выдаст информацию о назначении потоков
  1. Stream mapping:
  2.   Stream #0:0 (h264) -> ass
  3.  split:output0 -> Stream #0:0 (libx264)
  4.  Stream #0:1 -> #0:1 (copy)
  5.  split:output1 -> Stream #1:0 (libx264)
  6.  Stream #0:2 -> #1:1 (copy)
Это поможет убедиться, что всё настроено правильно.
Если, к примеру, забыть указать -c:a copy перед вторым результирующим файлом, то ffmpeg выдаст:
  1. Stream mapping:
  2.   Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
  3.  Stream #0:1 -> #0:1 (copy)
  4.  Stream #0:0 -> #1:0 (h264 (native) -> h264 (libx264))
  5.  Stream #0:2 -> #1:1 (aac (native) -> aac (native))
Последняя строка говорит о том, что для второго файла (индекс 1) происходит перекодирование из aac в aac, а это явно не то, чего мы желали.

  • +1
  • views 7011