컴퓨터와 잡동사니 자료

FFmpeg과 youtube-dl에 대한 설명.

K66Google 2019. 6. 8. 22:37

지금까지 나는 동영상 인코딩 프로그램으로 Daum 팟인코더를 사용해왔다.

인코딩뿐만 아니라 동영상 합치기 / 쪼개기 기능도 팟인코더를 주로 사용했다... 그러나 합치기와 쪼개기를 하면 반드시 재인코딩을 해야돼서 시간도 많이 걸리고 번거로웠다. 어차피 똑같은 코덱을 쓰는데 왜 작업할때마다 재인코딩을 해야 된다는 말인가?


그러던 중에, 합치기와 쪼개기를 하는데 별로 시간이 걸리지 않는 법을 알아냈다. 바로 FFMpeg을 이용하는 것이었다.


https://ffmpeg.zeranoe.com/builds/ 에 가서 Architecture 탭에 자신의 운영체제 비트 수를 선택하고 Download Build를 선택한다.

그러면 zip 파일로 다운로드 받을 수 있다. 압축해제까지 마치면 사용할 준비가 완료된다.




* 공통

쪼개기, 자르기, 합치기, m3u8 저장에서 모두 사용되는 기술이다.


1. 먼저 쪼갤 동영상을 ffmpeg.exe 파일이 있는 곳과 동일한 폴더에 넣어준다.



2. 그리고 ffmpeg 폴더에서 바로 탐색기 주소 창에다 cmd라고 입력하고 엔터 키를 친다.



3. 그럼 놀랍게도 cd 명령어 입력할 필요없이 바로 ffmpeg이 있는 폴더 위치에서 명령 프롬프트가 시작된다. 여기서부터 작업을 시작하면 된다.




* 쪼개기

하나의 동영상을 두 개로 쪼개는 작업이다.

동영상을 쪼개고 싶으면 일단 몇분 몇초를 기준으로 쪼갤 것인지 결정을 해야 한다.

혹은 몇분 몇초부터 몇분 몇초까지 추출하고 싶은 경우도 있을 것이다. 이제 그 명령어를 모두 설명하겠다.



ex) 24분 짜리 동영상에서 12분 씩 나누고 싶을 경우


ffmpeg   -i "원본동영상.mp4" -ss 00:00:00 -t 00:12:00  -vcodec copy -acodec copy  "추출파일명1.mp4"


ffmpeg   -i "원본동영상.mp4" -ss 00:12:00 -vcodec copy -acodec copy  "추출파일명2.mp4"


- 확장자 설명


-ss : 쪼개기를 시작할 시간을 지정한다.


-i  : 원본 동영상 파일을 지정한다. (FFmpeg 폴더 내에 있어야 작업하기 쉽다)


-t : 쪼개기를 몇분 몇초나 할 것인지 지정한다.

절대 몇분 몇초까지가 아니다!! 몇분 몇초나 할 것인지를 지정하는 거다!!

예를 들어, -ss를 00:10:00 이라고 지정했고 -t를 00:15:30 이라고 지정했다면 15분 30초까지만 쪼개는 게 아니라 10분 + 15분 30초 = 25분 30초까지 쪼개는 것이다. 혼동하지 않기를 바란다.


-t를 생략하면 FFMpeg이 알아서 동영상 마지막 부분까지 쪼개준다.


-vcodec copy

-acodec copy

: 원본 동영상 파일과 동일한 코덱으로 지정한다는 뜻이다. 이 옵션이 있어야 재인코딩을 하지 않는다.


"추출파일명.mp4" : 결과물로 나올 동영상의 이름을 적는다.



- 참고1 : -ss와 -t의 형식은 초단위 형식 [1202 (= 20분 2초)], 시:분:초 형식 [00:20:02], 시:분:초.밀리초 형식 [00:20:02.333]의 입력을 지원한다. 구체적인 내용은 참고3를 볼 것.


- 참고2 : 왜 -i를 먼저 안 쓰고 -ss부터 쓰냐고 묻냐면, 오디오 싱크에 문제가 있다는 글을 봤기 때문이다. (링크)


- 참고3 : ffmpeg의 홈페이지에 가면 많은 옵션들이 설명되어 있다. (링크)



* 자르기

어떤 동영상에 대해 필요없는 부분(광고 등...)을 빼고 필요한 부분만 뽑아내는 과정을 뭐라고 표현해야 할 지 잘 몰라서 일단 '자르기' 라고 칭해둔다.

그런데 ffmpeg으로 자르는 것보다는 다른 프로그램을 이용해서 자를 것을 권장한다. 자꾸만 근삿값으로 쪼개지는 문제가 있어서 그렇다. ( 링크 )


아무튼, 그래도 ffmpeg으로 자르고 싶은 사람들을 위해 계속 설명 이어가겠다.


ex) 21분 짜리 동영상에서 00:00:01.693 부터 00:20:30.033 까지 추출하고 싶을 경우


ffmpeg -i  "원본파일명.mp4" -ss 00:00:01.693 -t  00:20:28.340  -vcodec copy -acodec copy  "추출파일명.mp4"


대부분의 옵션은 쪼개기와 같아서 생략하는데, 이때 왜 -t값이 00:20:28.340이 나왔는지 계산하는 방법을 설명하겠다.


보통 자르기를 할 때 시:분:초 까지만 하면 엉성하게 잘리는 경우가 있다. 따라서 이때는 밀리초까지 신경써줘야 한다.

그런데 팟플레이어는 밀리초를 볼 수 있는 방법이 없다. 

밀리초를 보기 위해서는 어쩔 수 없이 동영상 편집 프로그램을 써야 하는데, CyberLink PowerDirector 15에서는 밀리초가 아니라 프레임으로 나와서 따로 밀리초 계산이 필요하다. 그럼 00:20:30:01밀리초로 환산해보도록 하자.



동영상을 마우스 오른쪽 클릭하고 '프레임 속도' 를 보면 29.95 프레임. 즉, 거의 30 프레임이라는 것을 알 수 있다.

1000 밀리초가 1초니까... 1000 ÷ 30 = 33.33... 그렇다. 1프레임 당 33을 곱하면 (30 x 33 = 990) 거의 1000에 도달하게 된다.

만약 프레임 속도가 24프레임이라면? 1000 ÷ 24 = 41.66... 1프레임 당 41을 곱하면 (24 x 41 = 984) 거의 1000에 도달하게 된다.

따라서 [ 1000 ÷ 동영상프레임 x 자를프레임 ] 이라는 계산식이 성립된다.


일단 현재 동영상은 약 30프레임이니까 00:20:30:01 을 밀리초로 바꾸자면...

1000 ÷ 30 x 1 = 33.33... x 1 = 33.33... = 33

소수점은 버린다. 그러면 00:20:30.033 로 치환된다.


이제 -ss값이었던 00:00:01.693 과 뺄셈을 해서 t값을 산출해내야 하는데, 먼저 밀리초끼리 뺄셈을 해본다... 어라? 

033보다 693이 커서 뺄셈이 제대로 안된다. 이럴때는 어떻게 해야 하지? 바로 초단위에서 1을 빌려오는 것이다. 

빌려오게 되면 1000으로 환산되면서 1033 - 693 = 340. 뺄셈이 가능해지게 된다.


그 후 초 단위는 초 단위끼리 계산하고, 분 단위는 분 단위끼리 계산하면 된다. 

초단위에서 뺄셈이 안되면 분단위에서 1을 빌려오면 되고 (60으로 환산)

분단위에서 뺄셈이 안되면 시단위에서 1을 빌려오면 된다. (역시 60으로 환산)


이렇게 계산을 하면 최종적으로 -t값인 00:20:28.340 을 도출해낼 수 있다.




- 참고 (-to 설명)

사실 -to라는 옵션을 쓰면 뺄셈할 필요없이 자르기 할 마지막 시간만 입력하면 된다.


ffmpeg -ss 00:00:01.693  -i  "원본파일명.mp4"  -to 00:20:30.033  -vcodec copy -acodec copy -copyts  "추출파일명.mp4"


이렇게 쓰면 된다. 이때 -copyts 를 꼭 붙여줘야 한다. 붙이지 않은 채로 -ss가 -i의 앞에 쓰이게 되면 -to는 -t처럼 작동을 하게 되기 때문이다. (링크)

또한 -ss와 -to.. -copyts 방법을 쓰면 원하는 곳에서 딱 잘리지 않을 때가 많은 그건 키프레임 단위로 자르기를 하게 되기 때문이다. (설명) 이때는 Smart Cutter 같은 다른 동영상 자르기 프로그램을 사용하거나 -ss -t 방법을 사용해야 된다. (관련 내용)




* 합치기 (mp4 기준)

(내용 참조 : https://trac.ffmpeg.org/wiki/Concatenate )


두 개의 동영상을 합치고 싶을 경우에 대해 설명한다. 소개하는 방법 외에도 다른 방법이 있는데 그 방법은 mp4 파일에서 먹히지를 않는다. 그래서 mp4 파일에 먹히는 방법에 대해서만 소개하겠다.


메모장을 열고 이렇게 작성한다.


file 합칠동영상1.확장자

file 합칠동영상2.확장자

...

또는

file './폴더명/합칠동영상1.확장자'
file './폴더명/합칠동영상2.확장자'

이때 폴더 구분은 슬래시(/)로 한다.
당연히 합칠 순서에 맞게 작성을 해줘야 하며, 다 작성했으면 ffmpeg 폴더에 텍스트 파일을 저장한다.
그 후 cmd 창으로 들어가서 아래와 같이 명령어를 친다.

ffmpeg -f concat -i ".\텍스트파일명.txt" -c copy "출력파일명.mp4"

또는

ffmpeg -f concat -safe 0 -i ".\텍스트파일명.txt" -c copy "출력파일명.mp4"


만약 Unsafe File Name 오류가 뜨면 -f concat 뒤에 -safe 0 옵션까지 넣으면 된다.



- 확장자 설명


-f : 파일 포맷이 입력인지 출력인지 강제로 지정하는 옵션인데, 솔직히 다른 작업에선 별로 쓸 일이 없는 것 같다.


-i : 합칠 파일 목록이 들어있는 txt 파일을 지정. 쪼개기·자르기에선 동영상 주소를 걸었는데 여기선 txt 파일을 걸었다.


-c copy : 코덱을 원본 파일들과 동일하게 설정한다는 의미.


"출력파일명.mp4" : 합치기 후 결과물로 나올 동영상 파일의 이름을 지정.



- 참고1 : 합치는 명령을 실행했는데 Non-monotonous DTS in output stream 0:0... 오류가 수 백개씩 뜨는 경우가 있다. 팟플레이어에서 정상 재생이 되면 상관없지만, 그렇지 않다면 다른 작업이 필요하다. 링크를 참조. (링크)




* 재인코딩 (mp4)

합치기 등으로 생성한 영상에 문제가 있거나, 자르기를 했는데 자꾸만 엉뚱한 부분에서 잘리는 경우 재인코딩을 해야 한다.

그러나 재인코딩한 영상을 가지고 잘라도 부정확하게 잘린다면 ffmpeg이 아닌 Smart Cutter 같은 다른 프로그램을 사용하기 바란다. ( 링크 )


ffmpeg -i "원본파일명.mp4" -acodec aac -vcodec libx264 "출력파일명.mp4"


-acodec에는 mp4 파일에 주로 쓰이는 aac 코덱을, -vcodec에는 H.264 코덱으로 지정하였다.




* m3u8 저장 (이론)

인터넷 동영상들 중에 m3u8 형식으로 서비스되는 것들이 많아서, 예전과 달리 영상을 저장하는 것도 힘들어졌다. 

아래 명령어를 이용해서 m3u8 동영상을 이론적으로는 다운받을 수 있다. 이론적으로는...


ffmpeg -i "m3u8 주소 경로" -acodec copy -vcodec copy "출력파일명.mp4"


m3u8 주소 경로를 어떻게 파악하는지는 아래 설명을 참조. 크롬이나 파폭 브라우저가 필요하다.



1. 동영상이 있는 페이지로 간 다음에 F12키로 개발자 도구 열고 Network 탭으로 가서 새로고침 한다.



2. 새로고침 후 동영상을 재생하면 온갖 파일들이 레이더망에 걸리는데 위쪽의 필터입력란에 m3u 라고 입력해본다. 그러면 저렇게 몇몇 의심가는 파일이 리스트에 뜨는데 아무거나 클릭해본다.



3. m3u8 형식은 다음과 같다.


#EXTM3U

#EXT-X-VERSION:3

#EXT-X-PLAYLIST-TYPE:VOD

#EXT-X-INDEPENDENT-SEGMENTS

#EXT-X-TARGETDURATION:0

#EXT-X-MEDIA-SEQUENCE:0

#EXT-X-KEY:METHOD=AES-128,URI="어쩌구저쩌구"

#EXTINF:17.617600,

https:// 어쩌구저쩌구

#EXTINF:16.016000,

https:// 어쩌구저쩌구

#EXTINF:15.248567,

https:// 어쩌구저쩌구

#EXTINF:17.917900,


여기서 중요한 것은 EXTINF다. 이것이 바로 핵심 파일이다.

그런데 위의 m3u8 파일은 또 다른 m3u8로 연결을 하고 있을 뿐이다. (EXT-X-STREAM-INF) 이건 우리가 찾는 파일 형식이 아니니 다른 걸 찾아보도록 하자.



4. 바로 이것이 m3u8 파일의 전형적인 형태다.

 그러나 안타깝게도 네이버TV는 ffmpeg을 막아놓은 모양이다. 받으려고 하면 HTTP error 400 Bad Request만 뜬다.

 네이버TV는 m3u8.exe라는 다른 프로그램을 통하여 다운로드 받을 수 있다. (설명 링크 , 2020.11 기준)

 ...일단 가능하다고 전제를 걸고 계속 설명하기로 하겠다.



5. (m3u8 저장이 가능한 경우) 찾은 m3u8 파일을 마우스 오른쪽 클릭 - Copy - Copy link address 하면 m3u8 파일의 주소가 복사된다. 이걸 ffmpeg 명령어의 "m3u8 주소 경로"에다 대입시키면 된다.




* m3u8 저장 (youtube-dl)

위에서도 말했다시피, 일부 사이트들은 ffmpeg이 동영상을 긁어가는 걸 막아놓는 것으로 추정된다. 그래서 youtube-dl 이라는 프로그램을 이용해야 받을 수가 있다.


1. https://ytdl-org.github.io/youtube-dl/download.html 에 가서 Windows exe (둘 중 하나) 클릭하여 youtube-dl 프로그램을 다운받는다.




2. 다운받은 youtube-dl.exe를 찾기 쉬운 곳에 붙여넣는다. ffmpeg 폴더에 같이 넣으면 편하다.

   그런 다음 cmd를 켜서 이런 식으로 명령어를 치면 된다.


youtube-dl "동영상 주소"


또는


youtube-dl -F "https://www.youtube.com/watch?v=어쩌구저쩌구"

(-F는 대문자 F라는 점에 유의할 것)

-F 옵션을 안 주면 그냥 마음대로 다운받고 끝나는데, -F 옵션을 주면 영상의 화질 옵션을 먼저 분석하게 된다.

잠시후 어쩌구저쩌구 하면서 뭔가가 막 뜰 것이다.


249          webm       audio only DASH audio   58k , opus @ 50k, 5.33MiB

250          webm       audio only DASH audio   74k , opus @ 70k, 6.86MiB

140          m4a        audio only DASH audio  131k , m4a_dash container, mp4a.40.2@128k, 14.89MiB

171          webm       audio only DASH audio  145k , vorbis@128k, 10.75MiB

251          webm       audio only DASH audio  145k , opus @160k, 12.98MiB

278          webm       192x144    144p   74k , webm container, vp9, 30fps, video only, 7.09MiB

160          mp4        192x144    144p   84k , avc1.4d400c, 30fps, video only, 3.88MiB

242          webm       320x240    240p  168k , vp9, 30fps, video only, 10.10MiB

133          mp4        320x240    240p  184k , avc1.4d400d, 30fps, video only, 6.81MiB

243          webm       480x360    360p  306k , vp9, 30fps, video only, 17.66MiB

134          mp4        480x360    360p  475k , avc1.4d401e, 30fps, video only, 17.18MiB

244          webm       640x480    480p  567k , vp9, 30fps, video only, 29.70MiB

135          mp4        640x480    480p  872k , avc1.4d401e, 30fps, video only, 33.74MiB

18           mp4        480x360    medium , avc1.42001E, mp4a.40.2@ 96k, 44.95MiB

43           webm       640x360    medium , vp8.0, vorbis@128k, 57.00MiB (best)


이런 식으로. 

audio only, video only라고 적혀있는 건 음성 혹은 영상 단독으로 된 파일을 의미한다. 적혀있지 않으면 영상·음성이 통합된 통합파일이다.

best 표시가 붙어있는 건 통합파일 중 가장 화질이 좋은 파일을 의미한다.

이제 받고 싶은 화질을 선택하여 다운받으면 된다. 그 명령어는...


youtube-dl -f 통합번호 "동영상 주소" 

ex) youtube-dl -f 43 "https://www.youtube.com/watch?v=어쩌구저쩌구"


또는


youtube-dl -f 영상번호+음성번호 "동영상 주소"

ex) youtube-dl -f 135+140 "https://www.youtube.com/watch?v=어쩌구저쩌구"


(이때는 대문자 -F가 아닌 소문자 -f 라는 것에 유의.)

-f 옵션으로 통합번호 또는 영상+음성번호를 선택하여 영상을 다운받을 수 있다. youtube-dl은 합치기 기능도 지원해서, 영상 단독·음성 단독 파일도 하나로 합칠 수 있다고 한다. (링크)

혹시 webm 파일로 받았으면 ffmpeg을 통해 mp4로 변환하면 된다. 명령어는 아래와 같다.


ffmpeg -i "원본.webm" "출력될파일.mp4"


이렇게 하면 webm 파일이 mp4로 재인코딩 될 것이다. (-vcodec -acodec copy를 안 쓰는 이유는 webm 파일이라서 높은 확률로 vp8 코덱 오류가 뜨기 때문이다)


m3u8을 지정하지 않고 그냥 동영상 주소를 입력하면 된다는 점에서는 ffmpeg보다 편하기도 하다.


자. 지금까지 ffmpeg과 youtube-dl에 대해서 알아보았다. 이 두 프로그램은 활용하기에 매우 뛰어난 프로그램이라고 생각된다.

그럼 이만...