ffmpeg 사용 옵션

■스트리밍 추출
ffmpeg로 스트리밍 추출
ffmpeg로 스트리밍을 받으려면 .m3u8이나 .mp4로 된 주소를 알아야 한다
ffmpeg -i "m3u8주소" -c copy 저장할파일명.ts
자세한 방법 보려면 (ffmpeg로 스트리밍 추출 예를 보려면)
https://blog.naver.com/peche99/220816504552 [멜론 영상 추출법] 으로 가서 보면 됨.


■동영상 일괄 변환 스크립트 샘플
@ECHO OFF
CHCP 65001 1> NUL 2> NUL

SET "SRC_DIR=."

FOR /F "TOKENS=*" %%A IN ('DIR /B /ON %SRC_DIR%\*.*') DO (
  CALL :FUNC_FFMPEG_CONV "%SRC_DIR%\%%A"
)

:FUNC_FFMPEG_CONV
  SET OUT_FILE=%~N1.mp3
  ffmpeg -i %1 -vn -af "volume=5dB" -ar 48000 -ac 2 -ab 320k -f mp3 "%OUT_FILE%"
  GOTO :EOF


■FLAC to MP3
ffmpeg -i sample.flac -af "volume=5dB" -codec:a libmp3lame -q:a 0 -map_metadata 0 -id3v2_version 3 sample.mp3


■동영상 합치기
# 인코딩은 UTF-8, 경로 구분자 \는 \\로 작성한다.
# 합치려는 동영상 앞에 file 키워드를 넣어서 작성한다.
# ffmpeg -f concat -safe 0 -i d:\downloads\합칠동영상목록.txt -c copy d:\_ffmpeg\ffmpeg_encoded\동영상파일명.avi
file d:\\_ffmpeg\\ffmpeg_encoded\\동영상파일명_1OF2.avi
file d:\\_ffmpeg\\ffmpeg_encoded\\동영상파일명_2OF2.avi


■동영상에서 오디오 추출과 오디오 포맷 변환
ffmpeg -i sample.avi -vn -af "volume=5dB" -ar 48000 -ac 2 -ab 320k -f mp3 sample.mp3
ffmpeg -i sample.opus -ss "00:46:44" -to "00:52:42" -vn -ar 48000 -ac 2 -ab 320k -f mp3 "D:\0_tmp\output.mp3"
ffmpeg -i sample.opus -vn -ar 48000 -ac 2 -ab 320k -f mp3 "sample.mp3"


■동영상에 오디오 합치기
오디오 넣을 영상에 오디오가 없는 경우-재인코딩 할 때
ffmpeg -i video.mp4 -i audio.wav -c:v copy -c:a aac -strict experimental output.mp4
오디오나 비디오 둘 중하나가 더 길때, -shortest 옵션을 넣으면 ffmpeg가 짧은 쪽이 끝날 때 자동으로 중지한다고 함

오디오 넣을 영상에 오디오가 없는 경우-재인코딩 없이 카피
ffmpeg -i video.mp4 -i audio.wav -c copy output.mkv

오디오 넣을 영상에 이미 오디오가 있는 경우-오디오 교체
ffmpeg -i video.mp4 -i audio.wav -c:v copy -c:a aac -strict experimental -map 0:v:0 -map 1:a:0 output.mp4


■동영상 크롭(Crop)
ffmpeg -i 원본영상.mp4 -filter:v "crop=영상가로:영상세로:X:Y" 결과물.mp4
(원본영상.mp4 를 X,Y 지점부터 영상가로x영상세로 영역만큼만 뽑아냄)

두개의 영상을 한화면에 양옆으로 나란히(Side by Side)

ffmpeg -i 영상1.mp4 -vf "[in] pad=2*iw:ih [left]; movie=영상2.mp4 [right]; [left][right] overlay=main_w/2:0 [out]" 결과물.mp4

(화면크기가 같은 2개의 동영상 영상1.mp4, 영상2.mp4 를 나란히 좌우로 붙여 결과물.mp4로)

두개의 영상을 한화면에 아래 위로

ffmpeg -i input0 -i input1 -filter_complex vstack output
ffmpeg -i ver1-5.mp4 -vf "[in] pad=iw:2*ih [top]; movie=ver2-5.mp4 [bottom]; [top][bottom] overlay=0:main_h/2 [out]" ver5-2.mp4


■동영상 프레임 늘리기(슬로우/패스트 비디오 만들기)
ffmpeg -i ~baekrokdam.mov -vf "setpts=(1/4)*PTS" -an baekrokdam4x.mov

setpts=(1/4)*PTS의 1/4를 원하는 배속으로 수정.

오디오는 재생 속도가 변경되지 않으므로 -an 옵션으로 오디오 제거.


■화면 회전
ffmpeg -i in.mov -vf "transpose=1" out.mov

0 = 90CounterCLockwise and Vertical Flip (default)
1 = 90Clockwise
2 = 90CounterClockwise
3 = 90Clockwise and Vertical Flip

자막파일 smi → srt 변환

ffmpeg -i 자막파일.smi 자막파일.srt


■동영상의 뒷부분에서 TAIL_CUT_SEC초 만큼 잘라서 저장
#####################################################################
#
# 윈도우에서 cywin bash를 사용하여 아래와 같이 실행한다.
# bash -c "./sca.sh"
#
#####################################################################
TAIL_CUT_SEC=15
SRC_DIR="d:\videos\video"
DST_DIR="d:\0_tmp"

ffmpeg_conv() {
  DURATION=$(ffprobe -i "${SRC_DIR}/${1}" -show_entries format=DURATION -v quiet -of csv="p=0")
  TRIM=$(echo $DURATION | awk "{print $DURATION - $TAIL_CUT_SEC};")
  ffmpeg -t $TRIM -i "${SRC_DIR}/${1}" -c copy "${DST_DIR}/${1}"
}

ffmpeg_conv "TEST.AVI"


■동영상 분할(일정구간 자르기)
지정된 시간 사이의 동영상 분할 명령 및 설명

ffmpeg -y -i ⓐ -ss ⓑ -to ⓒ -vcodec copy ⓓ -acodec copy ⓔ ⓕ

ⓐ -i <분할파일이름> : 분할할 동영상 파일 이름을 지정합니다.
ⓑ -ss <숫자> : 분할 시작할 시간 값. 초 단위로 적어주거나, HH:MM:SS 로 지정할 수 있다.
ⓒ -to <숫자> : 분할 완료할 시간 값. 초 단위로 적어주거나, HH:MM:SS 로 지정할 수 있다.
ex) 30으로 적어주면 분할을 시작한 시간으로 부터 30초간만 분할된다.
ⓓ -vcodec copy : 비디오 코덱은 원본 동영상과 같게 한다.
ⓔ -acodec copy : 오디오 코덱은 원본 동영상과 같게 한다.
ⓕ <출력파일이름> : 분할하여 저장할 동영상 파일 이름을 지정한다.

* 덧붙임: ss 옵션값이 없으면 시작부터 지정한 시간까지 분할하고, t 옵션값이 없으면 시작으로부터 끝까지 분할한다.

간단 버젼
ffmpeg -i 동영상.avi -ss 600 -t 120 결과물.avi
(동영상.avi 의 600초 지점부터 120초간 자르고 결과물.avi로 저장)

ffmpeg -y -i input.mp4 -ss "00:00:15" -to "00:07:07" -c:v mpeg4 -q:v 5 -tag:v DIVX -s 800x480 -b:v 1200k -maxrate 1200k -qmax 51 -r 23.976 -c:a libmp3lame -b:a 192k "output.avi"
(00:00:15부터 00:07:07까지 잘라서 저장)

ffmpeg -y -i sample.mp4 -ss 0 -t 3600 -vcodec copy -acodec copy sample1.mp4 -y
ffmpeg -y -i sample.mp4 -ss 3601 -vcodec copy -acodec copy sample2.mp4 -y
(동영상을 한시간 짜리 하나와 나머지로 분리한다-속도 빠름)


■관련 링크
ffmpeg 기본 옵션
https://ffmpeg.org/ffmpeg.html

ffmpeg Filters
https://ffmpeg.org/ffmpeg-filters.html

H.264
https://trac.ffmpeg.org/wiki/Encode/H.264

H.265(HEVC-High Efficiency Video Coding)
https://trac.ffmpeg.org/wiki/Encode/H.265

​Advanced Audio Coding(AAC)
https://trac.ffmpeg.org/wiki/Encode/AAC

MP3
https://trac.ffmpeg.org/wiki/Encode/MP3

■옵션
-L : 라이센스 표시
-h : 헬프표시
-formats : 현재 사용할 수 있는 포맷, 코덱, 프로토콜을 표시
-f fmt : 포맷을 지정 (fmt의 부분에 -formats 그리고 조사한 포맷명이 들어간다)
-img img_fmt : 화상의 포맷을 지정 (img_fmt의 부분에 -formats 그리고 조사한 포맷명이 들어간다)
-i filename : 입력파일명
-y : 동일 파일 존재시 덮어쓰기
-t duration : 완성되는 파일의 시간을 지정한다 (duration의 부분에 0을 넣으면 10초 부분까지 기록)
-ss : 변환시작할 시간
-sn : 입력 옵션으로 파일의 모든 자막 스트림이 필터링되거나 출력에 대해 자동으로 선택 또는 매핑되는 것을 차단한다.
-r <프레임 수>
-preset <options>
  options: ultrafast,superfast,veryfast,faster,fast,medium(default),slow,slower,veryslow
  압축을 하는데 걸리는 시간 또는 압축률을 설정한다. 압축률이 높을수록 데이터를 압축하는데 시간이 오래 걸린다. 압축률이 낮다고 품질이 좋거나 하지는 않으며 압축률이 높다면 파일 용량이 줄어 든다.
  ex) -preset slow
-codec:v 옵션은 비디오 스트림의 코덱을 지정한다. :v는 비디오를 의미한다.
  ex) -c:v libx265
-maxrate
  최대 비트레이트이다. 앞의 비트레이트는 평균적인 설정값이고 그렇기에 영상의 어떤 프레임에서는 비정상적으로 큰 값을 가질 수 있다. 이를 막기 위해 상한선을 지정하는 역할을 한다.
  ex) -maxrate:v 1150k -minrate:v 1150k
-bufsize 옵션은 출력 버퍼를 지정한다. 영상이 재생될 때 이 값만큼의 영상데이터가 메모리에 준비된다고 생각하자.
  ex) -bufsize:v 327680
-vf
  이 옵션은 -filter:v의 alias이며, filtergraph로 지정된 필터 그래프를 생성하고 이를 사용하여 스트림을 필터링한다.
  ex) -vf "scale=-1:720,subtitles=sample.srt:force_style='FontName=MalgunGothic,FontSize=22'"
  ex) -vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2"
  ex) -vf "yadif=0:-1:0"
-scale
  옵션은 비디오 필터의 부분 옵션으로 영상의 해상도를 지정한다. 1024x768 형식으로 설정할 수도 있으나 예문에서처럼
  -1:720 형식의 설정을 주로 쓴다. 이는 소위 말하는 720p 영상이라는 뜻으로 영상의 높이가 720픽셀이라는 뜻이다.
-threads
  옵션은 작업을 하는데 사용할 CPU 코어의 갯수를 의미한다.
  물론 많은 코어를 사용하면 작업 속도도 빠르다. 0으로 설정하면 알아서 최적화된 코어 갯수를 설정하여 작업한다.
-crf
  Constant Rate Factor(CRF)
  1초에 해당하는 동영상에 얼마의 bit를 넣느냐를 의미한다. 높을수록 더 많은 정보를 담아서 화질이 좋아지게 된다. 대표적으로 CBR, VBR 방식이 있으며, CBR(Constant Bitrate)은 고정된 bitrate를 VBR(Variable Bitrate)는 최대, 최소 범위로 변동하는 bitrate를 사용하는 방식을 의미한다. ffmpeg는 기본적으로 CBR 방식을 사용하며, 옵션(vbr)을 통해서 VBR 방식을 사용할 수 있다.
  ex) -crf 23

영상옵션
-s : 사이즈 (가로x세로)
-sameq : 원본과 동일화질
-qscale : 0 ~ 255 (낮을수록 고화질)
-r : frame rate (Hz value, fraction or abbreviation)
-aspect : 비율 (4:3, 16:9 or 1.3333, 1.7777)
-b : bitrate (ex 512k)


■동영상 기본 인코딩
ffmpeg -y ⓐ -i ⓑ -acodec ⓒ -ab ⓓ -ar ⓔ -ac ⓕ -b:a ⓖ -vcodec ⓗ -level ⓘ -b:v ⓙ
-r ⓚ -s ⓛ -threads ⓜ -strict experimental ⓝ ⓞ

ⓐ -y : 출력파일을 쓸 때 같은 이름의 파일이 있어도 확인없이 덮어쓰기를 하겠다는 의미.
ⓑ -i <입력파일이름> : 변환할 원본 동영상 파일 이름을 지정.
ⓒ -acodec <오디오코덱> : 오디오 코덱을 지정한다. 여기서는 aac 로 함.
ⓓ -ab <숫자> : 오디오 비트레이트를 지정한다.
ⓔ -ar <숫자> : 오디오 샘플링 레이트를 지정한다.
ⓕ -ac <숫자> : 오디오 채널을 지정한다.
ⓖ -b:a <숫자> : 오디오 비트레이트를 지정한다.
ⓗ -vcodec <비디오코덱> : 비디오 코덱을 지정한다. 여기서는 libx264 로 함. (H.264 코덱)
ⓘ -level <숫자> : Baseline 값. 30이면, Baseline 3.0
ⓙ -b:v <숫자> : 비디오 비트레이트를 지정한다.
ⓚ -r <숫자> : 출력 동영상 프레임 레이트를 지정한다.
ⓛ -s <숫자> : 화면 크기, 해상도를 지정한다. 원본 해상도보다 크게 할 경우 확대되서 나온다.
    프리셋처럼 미리 지정된 문자가 있어서 직접 해상도를 지정하지 않아도 된다.
    ex) vga – 640 x 480, sxga 1280 x 1024, wvga 852 x 480, hd720 – 1280 x 720 등
ⓜ -threads <숫자> : 쓰레드수를 지정한다. 속도 향상을 위해 멀티쓰레드를 지정해줄 수 있다.
반드시 CPU 코어 갯수와 일치시킬 필요는 없지만, 보통은 코어 갯수에 맞춘다.
ⓝ -strict experimental : 옵션의 엄격함을 느슨하게 풀어주는 옵션
ⓞ <출력파일이름> : 변환하여 저장할 동영상 파일 이름을 지정한다.

동영상 변환 옵션 예)

ffmpeg -y -i 변환전동영상파일명.avi -acodec aac -ab 192k -ar 48000 -ac 2 -b:a 300k  -vcodec libx264 -level 30 -b:v 3000k -r 29.97 -s 1280:720 -threads 4 -strict -2 변환후동영상파일명.mp4

* 덧붙임: 본인이 생각하기에 필요없거나 중요치 않다고 생각하는 부분은 생략할 수 있다. 나는 f, i, m, n은 항상 안 쓴다.
아예 다른 부분은 다 생략하고

ffmpeg -i 변환전동영상파일명.avi 변환후동영상파일명.mp4

이렇게 입력해도 ffmpeg가 알아서 인코딩 해준다.

@ECHO OFF
CHCP 65001 1> NUL 2> NUL
CLS
ECHO ############################################################
ECHO #
ECHO # 동영상 파일을 합치는 스크립트.
ECHO #
ECHO ############################################################
SET "SRC_DIR=m:\0_tmp"
SET "SRC_FILES=20221029*.MP4"
SET "OUTPUT_FILE=m:\0_tmp\output.mp4"

REM 추가할 동영상 목록을 만든다.
SET "TMP_LIST_FILE=ffmpeg_concat.list"
IF EXIST %TMP_LIST_FILE% DEL /Q %TMP_LIST_FILE%
SET /A FILE_COUNT=0
FOR /F "TOKENS=*" %%A IN ('DIR /B /ON "%SRC_DIR%\%SRC_FILES%"') DO (
  ECHO file '%SRC_DIR%\%%A'>>%TMP_LIST_FILE%
  ECHO file '%SRC_DIR%\%%A'
  SET /A FILE_COUNT+=1
)
ECHO.
ECHO *** 위의 파일들을 합치겠습니다. 동의하면 ENTER키를 눌러주세요 ***
PAUSE

ffmpeg -f concat -safe 0 -i "%TMP_LIST_FILE%" -c copy "%OUTPUT_FILE%"
DEL /Q "%TMP_LIST_FILE%"
PAUSE
위로 스크롤