Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 4개 있습니다.)
(시리즈 글이 7개 있습니다.)
.NET Framework: 288. FFmpeg.exe를 이용한 C# 동영상 인코더 예제
; https://www.sysnet.pe.kr/2/0/1210

개발 환경 구성: 622. vcpkg로 ffmpeg를 빌드하는 경우 생성될 구성 요소 제어하는 방법
; https://www.sysnet.pe.kr/2/0/12900

개발 환경 구성: 623. ffmpeg.exe를 사용해 비디오 파일의 이미지를 PGM(Portable Gray Map) 파일 포맷으로 출력하는 방법
; https://www.sysnet.pe.kr/2/0/12912

개발 환경 구성: 626. ffmpeg.exe를 사용해 비디오 파일을 MPEG1 포맷으로 변경하는 방법
; https://www.sysnet.pe.kr/2/0/12923

개발 환경 구성: 634. ffmpeg.exe - 기존 동영상 컨테이너에 다중 스트림을 추가하는 방법
; https://www.sysnet.pe.kr/2/0/12947

개발 환경 구성: 636. ffmpeg.exe를 이용해 planar 포맷의 데이터를 packed 형식으로 변환하는 방법?
; https://www.sysnet.pe.kr/2/0/12957

개발 환경 구성: 639. ffmpeg.exe - Intel Quick Sync Video(qsv)를 이용한 인코딩
; https://www.sysnet.pe.kr/2/0/12973




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개의 비디오를 함께 보여줍니다.

(사진은 유튜브 영상 "디에이드"의 "안다은" 님이고 사용을 허락받고 올립니다.)
ffmpeg_add_stream_1.png

또한, 작은 비디오 화면을 클릭하면 큰 화면과 작은 화면의 렌더링이 서로 바뀝니다. 즉, 1920x1080 비디오 렌더링 중에 작은 화면을 클릭하면 640x360 비디오가 큰 화면에 나와 이미지가 다소 깨져 보입니다. 그리고 다시 작은 화면을 클릭하면 1920x1080 비디오가 큰 화면으로 렌더링됩니다. 은근히, GOM 플레이어가 작은 부분까지 꽤나 세심하게 신경 쓴 것을 확인할 수 있습니다. ^^




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 1/30/2022]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 151  152  [153]  154  155  156  157  158  159  160  161  162  163  164  165  ...
NoWriterDateCnt.TitleFile(s)
1227정성태2/3/201229268.NET Framework: 299. 해당 어셈블리가 Debug 빌드인지, Release 빌드인지 알아내는 방법파일 다운로드1
1226정성태1/28/201270199.NET Framework: 298. 홀 펀칭(Hole Punching)을 이용한 Private IP 간 통신 - C# [15]파일 다운로드3
1225정성태1/24/201225863.NET Framework: 297. 특정 EXE 파일의 실행을 Internet Explorer처럼 "Protected Mode"로 실행하는 방법 [1]파일 다운로드1
1224정성태1/21/201237354개발 환경 구성: 139. 아마존 EC2에 새로 추가된 "1년 무료 Windows 서버 인스턴스"가 있다는데, 직접 만들어 볼까요? ^^ [11]
1223정성태1/20/201227316.NET Framework: 296. 괜찮은 문자열 해시함수? - 두 번째 이야기 [1]파일 다운로드1
1222정성태1/18/201235033.NET Framework: 295. 괜찮은 문자열 해시 함수? [4]파일 다운로드1
1221정성태1/17/201224028오류 유형: 147. System.Runtime.InteropServices.COMException (0x80005000)
1220정성태1/15/201224223.NET Framework: 294. Master web.config 파일을 수정하려면?파일 다운로드1
1219정성태1/15/201226588.NET Framework: 293. Microsoft PowerPoint 슬라이드를 HTML 파일로 ".files" 폴더 없이 저장하는 방법 (C# 코드)파일 다운로드1
1218정성태1/15/201239137.NET Framework: 292. RSACryptoServiceProvider의 공개키와 개인키 구분 [1]파일 다운로드2
1217정성태1/14/201241236.NET Framework: 291. .NET에서 WAV, MP3 파일 재생하는 방법 [1]파일 다운로드1
1216정성태1/14/201229948오류 유형: 146. Microsoft Visual C++ 재배포 패키지 - 설치 로그 남기는 방법 [1]
1215정성태1/9/201227504제니퍼 .NET: 20. 제니퍼 닷넷 적용 사례 (3) - '닷넷'이 문제일까? '닷넷 개발자'가 문제일까? [6]
1214정성태1/3/201224332제니퍼 .NET: 19. 제니퍼 닷넷 설치/제거 방법 - IIS
1213정성태12/31/201124290.NET Framework: 290. WCF - 접속된 클라이언트의 IP 주소 알아내는 방법 - 두 번째 이야기
1212정성태12/31/201124378오류 유형: 145. The trust relationship between this workstation and the primary domain failed.
1211정성태12/31/201129155.NET Framework: 289. WindowsFormsHost를 사용하는 XBAP 응용 프로그램파일 다운로드1
1210정성태12/30/201148130.NET Framework: 288. FFmpeg.exe를 이용한 C# 동영상 인코더 예제 [9]파일 다운로드1
1209정성태12/29/201122773개발 환경 구성: 138. BizTalk 2006 설치 방법
1208정성태12/28/201145791.NET Framework: 287. Excel Sheet를 WinForm에서 사용하는 방법 [8]파일 다운로드2
1207정성태12/26/201125049.NET Framework: 286. x86/x64로 구분된 코드를 포함하는 경우, 다중으로 어셈블리를 만들어야 할까요?파일 다운로드1
1206정성태12/25/201126074.NET Framework: 285. Shader 강좌와 함께 배워보는 XNA Framework (3) - 텍스처 매핑 예제파일 다운로드1
1205정성태12/25/201131706.NET Framework: 284. Thread 개체의 Interrupt와 Abort의 차이점파일 다운로드1
1204정성태12/22/201125203.NET Framework: 283. MEF를 ASP.NET에 성능 손실 없이 적용하려면? [7]
1203정성태12/21/201125574제니퍼 .NET: 18. MEF가 적용된 ASP.NET 웹 사이트를 제니퍼 닷넷으로 모니터링 해본 결과! [6]
1202정성태12/21/201126010오류 유형: 144. The database '...' cannot be opened because it is version 661.
... 151  152  [153]  154  155  156  157  158  159  160  161  162  163  164  165  ...