ffmpeg.exe - 기존 동영상 컨테이너에 다중 스트림을 추가하는 방법
다중 스트림 추가를 위해 예제를 구해 볼까요? ^^
우선, youtube-dl로 동영상이 지원하는 미디어 정보를 -f 옵션으로 조회할 수 있습니다.
C:\temp> youtube-dl.exe -F f-sxdm4QIvc
[youtube] f-sxdm4QIvc: Downloading webpage
[info] Available formats for f-sxdm4QIvc:
format code extension resolution note
249 webm audio only tiny 53k , webm_dash container, opus @ 53k (48000Hz), 1.20MiB
250 webm audio only tiny 70k , webm_dash container, opus @ 70k (48000Hz), 1.57MiB
140 m4a audio only tiny 129k , m4a_dash container, mp4a.40.2@129k (44100Hz), 2.90MiB
251 webm audio only tiny 134k , webm_dash container, opus @134k (48000Hz), 3.02MiB
278 webm 256x144 144p 85k , webm_dash container, vp9@ 85k, 30fps, video only, 1.92MiB
160 mp4 256x144 144p 91k , mp4_dash container, avc1.4d400c@ 91k, 30fps, video only, 2.04MiB
242 webm 426x240 240p 137k , webm_dash container, vp9@ 137k, 30fps, video only, 3.09MiB
133 mp4 426x240 240p 209k , mp4_dash container, avc1.4d4015@ 209k, 30fps, video only, 4.69MiB
243 webm 640x360 360p 214k , webm_dash container, vp9@ 214k, 30fps, video only, 4.80MiB
134 mp4 640x360 360p 442k , mp4_dash container, avc1.4d401e@ 442k, 30fps, video only, 9.92MiB
244 webm 854x480 480p 349k , webm_dash container, vp9@ 349k, 30fps, video only, 7.83MiB
135 mp4 854x480 480p 810k , mp4_dash container, avc1.4d401f@ 810k, 30fps, video only, 18.17MiB
247 webm 1280x720 720p 608k , webm_dash container, vp9@ 608k, 30fps, video only, 13.63MiB
136 mp4 1280x720 720p 1560k , mp4_dash container, avc1.64001f@1560k, 30fps, video only, 34.97MiB
248 webm 1920x1080 1080p 989k , webm_dash container, vp9@ 989k, 30fps, video only, 22.18MiB
137 mp4 1920x1080 1080p 3073k , mp4_dash container, avc1.640028@3073k, 30fps, video only, 68.86MiB
18 mp4 640x360 360p 543k , avc1.42001E, 30fps, mp4a.40.2 (44100Hz), 12.19MiB (best)
이것을 다운로드해,
C:\temp> youtube-dl.exe f-sxdm4QIvc -o test.mkv
[youtube] f-sxdm4QIvc: Downloading webpage
WARNING: Requested formats are incompatible for merge and will be merged into mkv.
[download] Destination: test.mkv.f137
[download] 100% of 68.86MiB in 15:26
[download] Destination: test.mkv.f251
[download] 100% of 3.02MiB in 00:40
[ffmpeg] Merging formats into "test2.mkv.mkv"
Deleting original file test.mkv.f137 (pass -k to keep)
Deleting original file test.mkv.f251 (pass -k to keep)
ffprobe로 조사해 보면,
c:\temp> ffprobe test.mkv
ffprobe version 4.4.1 Copyright (c) 2007-2021 the FFmpeg developers
built with Microsoft (R) C/C++ Optimizing Compiler Version 19.30.30705 for x64
configuration: ...[생략]...
libpostproc 55. 9.100 / 55. 9.100
Input #0, matroska,webm, from 'test.mkv':
Metadata:
COMPATIBLE_BRANDS: iso6avc1mp41
MAJOR_BRAND : dash
MINOR_VERSION : 0
ENCODER : Lavf58.45.100
Duration: 00:03:07.98, start: -0.007000, bitrate: 3206 kb/s
Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 1k tbn, 59.94 tbc (default)
Metadata:
HANDLER_NAME : ISO Media file produced by Google Inc.
DURATION : 00:03:07.954000000
Stream #0:1(eng): Audio: opus, 48000 Hz, stereo, fltp (default)
Metadata:
DURATION : 00:03:07.981000000
h264 비디오와 opus 오디오 스트림이 있는 것을 확인할 수 있습니다.
테스트를 위해, 44100 Hz의 오디오 스트림을 하나 더 다운로드하고,
c:\temp> youtube-dl.exe -f 140 f-sxdm4QIvc -o test.m4a
[youtube] f-sxdm4QIvc: Downloading webpage
[download] Destination: test.m4a
[download] 100% of 2.90MiB in 00:39
[ffmpeg] Correcting container in "test.m4a"
이에 더해 640x360 해상도의 비디오 스트림도 다운로드합니다.
c:\temp> youtube-dl.exe -f 243 f-sxdm4QIvc -o test.webm
[youtube] f-sxdm4QIvc: Downloading webpage
[download] Destination: test.webm
[download] 100% of 4.80MiB in 01:04
이렇게 소스가 준비되었는데요, 그럼 어떻게 스트림을 추가할 수 있을까요? 이에 대해서는 다음의 질문/답변에 잘 정리되어 있습니다.
ffmpeg - add 3 audio streams to video
; https://stackoverflow.com/questions/70001130/ffmpeg-add-3-audio-streams-to-video
즉, -map 옵션을 사용하는 것인데요, 가령 이렇게 명령을 내리면,
ffmpeg -i video.mp4 -i input1.mp3 -i input2.mp3
-map 0 -map 1:a -map 2:a
-c:v copy -shortest
output.mp4
사용된 map 옵션은 다음과 같은 의미를 갖습니다.
-map 0 to copy all streams from the input #0 (video)
-map 1:a to include all audio streams from input#1 file (audio1)
-map 2:a to include all audio streams from input#2 file (audio2)
따라서, 제가 이 글에서 다운로드한 상황에서는,
test.mkv: 기준이 되는 미디어 파일, 오디오와 비디오 스트림 모두 존재
test.m4a: 추가할 스트림, 오디오만 존재
test.webm: 추가할 스트림, 비디오만 존재
이렇게 명령을 내릴 수 있습니다.
C:\temp> ffmpeg -i test.mkv -i test.m4a -i test.webm -map 0 -map 1:a -map 2:v -c:v copy -shortest output2.mp4
ffmpeg version 4.3.2-2021-02-27-full_build-www.gyan.dev Copyright (c) 2000-2021 the FFmpeg developers
built with gcc 10.2.0 (Rev6, Built by MSYS2 project)
configuration: ...[생략]...
libpostproc 55. 7.100 / 55. 7.100
Input #0, matroska,webm, from 'test.mkv':
Metadata:
COMPATIBLE_BRANDS: iso6avc1mp41
MAJOR_BRAND : dash
MINOR_VERSION : 0
ENCODER : Lavf58.45.100
Duration: 00:03:07.98, start: -0.007000, bitrate: 3206 kb/s
Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 1k tbn, 59.94 tbc (default)
Metadata:
HANDLER_NAME : ISO Media file produced by Google Inc.
DURATION : 00:03:07.954000000
Stream #0:1(eng): Audio: opus, 48000 Hz, stereo, fltp (default)
Metadata:
DURATION : 00:03:07.981000000
Input #1, mov,mp4,m4a,3gp,3g2,mj2, from 'test.m4a':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2mp41
encoder : Lavf58.45.100
Duration: 00:03:08.01, start: 0.000000, bitrate: 129 kb/s
Stream #1:0(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 127 kb/s (default)
Metadata:
handler_name : ISO Media file produced by Google Inc.
Input #2, matroska,webm, from 'test.webm':
Metadata:
encoder : google/video-file
Duration: 00:03:07.95, start: 0.000000, bitrate: 214 kb/s
Stream #2:0(eng): Video: vp9 (Profile 0), yuv420p(tv, bt709), 640x360, SAR 1:1 DAR 16:9, 29.97 fps, 29.97 tbr, 1k tbn, 1k tbc (default)
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:1 -> #0:1 (opus (native) -> aac (native))
Stream #1:0 -> #0:2 (aac (native) -> aac (native))
Stream #2:0 -> #0:3 (copy)
Press [q] to stop, [?] for help
Output #0, mp4, to 'output2.mp4':
Metadata:
COMPATIBLE_BRANDS: iso6avc1mp41
MAJOR_BRAND : dash
MINOR_VERSION : 0
encoder : Lavf58.45.100
Stream #0:0: Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 29.97 fps, 29.97 tbr, 16k tbn, 1k tbc (default)
Metadata:
HANDLER_NAME : ISO Media file produced by Google Inc.
DURATION : 00:03:07.954000000
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
DURATION : 00:03:07.981000000
encoder : Lavc58.91.100 aac
Stream #0:2(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
handler_name : ISO Media file produced by Google Inc.
encoder : Lavc58.91.100 aac
Stream #0:3(eng): Video: vp9 (Profile 0) (vp09 / 0x39307076), yuv420p(tv, bt709), 640x360 [SAR 1:1 DAR 16:9], q=2-31, 29.97 fps, 29.97 tbr, 16k tbn, 1k tbc (default)
frame= 5633 fps=1836 q=-1.0 Lq=-1.0 size= 81540kB time=00:03:07.93 bitrate=3554.4kbits/s speed=61.3x
video:75317kB audio:5901kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.396938%
[aac @ 000002a27b0333c0] Qavg: 207.853
[aac @ 000002a27b035380] Qavg: 227.588
실제로 다중 오디오 스트림이 되었는지 확인해 볼까요? ^^
C:\temp> ffprobe output2.mp4
ffprobe version 4.4.1 Copyright (c) 2007-2021 the FFmpeg developers
built with Microsoft (R) C/C++ Optimizing Compiler Version 19.30.30705 for x64
configuration: ...[생략]...
libpostproc 55. 9.100 / 55. 9.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'output2.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.45.100
Duration: 00:03:07.95, start: 0.000000, bitrate: 3553 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 3070 kb/s, 29.97 fps, 29.97 tbr, 16k tbn, 59.94 tbc (default)
Metadata:
handler_name : ISO Media file produced by Google Inc.
vendor_id : [0][0][0][0]
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
handler_name : SoundHandler
vendor_id : [0][0][0][0]
Stream #0:2(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
handler_name : ISO Media file produced by Google Inc.
vendor_id : [0][0][0][0]
Stream #0:3(eng): Video: vp9 (Profile 0) (vp09 / 0x39307076), yuv420p(tv, bt709), 640x360, 212 kb/s, SAR 1:1 DAR 16:9, 29.97 fps, 29.97 tbr, 16k tbn, 16k tbc (default)
Metadata:
handler_name : VideoHandler
vendor_id : [0][0][0][0]
보는 바와 같이 동영상 컨테이너에 4개의 스트림(2개의 오디오, 2개의 비디오)이 잘 들어갔습니다. 재생 테스트도 해볼까요? ^^
ffplay로 -vst와 -ast 옵션을 사용하면 각각 비디오 스트림과 오디오 스트림을 선택해서 재생할 수 있습니다. 예를 들어, 위의 상황에서 만약 640x360 비디오로 44100 Hz 오디오를 재생하고 싶다면 다음과 같이 명령을 내리면 됩니다.
// -ast: 2번 오디오 스트림
// -vst: 3번 비디오 스트림
C:\temp> ffplay output2.mp4 -ast 2 -vst 3
그래서 ffplay의 재생 화면은 640x360 크기로 나옵니다. ffplay 외에, 재미있게도 이걸 GOM Player로 재생해 보면 다음과 같이 2개의 비디오를 함께 보여줍니다.
(사진은
유튜브 영상 "디에이드"의 "안다은" 님이고 사용을 허락받고 올립니다.)
또한, 작은 비디오 화면을 클릭하면 큰 화면과 작은 화면의 렌더링이 서로 바뀝니다. 즉, 1920x1080 비디오 렌더링 중에 작은 화면을 클릭하면 640x360 비디오가 큰 화면에 나와 이미지가 다소 깨져 보입니다. 그리고 다시 작은 화면을 클릭하면 1920x1080 비디오가 큰 화면으로 렌더링됩니다. 은근히, GOM 플레이어가 작은 부분까지 꽤나 세심하게 신경 쓴 것을 확인할 수 있습니다. ^^
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]