Skip to content

FFmpeg:CLI

ffmpeg is a very fast video and audio converter that can also grab from a live audio/video source. It can also convert between arbitrary sample rates and resize video on the fly with a high quality polyphase filter.

Synopsis

ffmpeg [global_options] {[input_file_options] -i input_file} ... {[output_file_options] output_file} ...

Categories

Example

  • FFmpeg 항목에 정리됨. <- 중복 정리를 막기 위해 링크로 뽑아둠

python

Docker Images

Commandline arguments

  • -acodec {codec}: (input/output) Set the audio codec. This is an alias for -codec:a.
  • -vf {filtergraph}: (output) filtergraph를 생성한다. This is an alias for -filter:v
    • -vf scale=320:-1: 너비를 320로 변환하고, 높이도 비율에 맞게 변환한다. 즉, "너비"를 기준으로 종횡비(Aspect Ratio)를 유지한다.
    • -vf scale=-1:240: 높이를 240로 변환하고, 너비도 비율에 맞게 변환한다. 즉, "높이"를 기준으로 종횡비(Aspect Ratio)를 유지한다.
    • -vf scale=iw*2:ih: 입력소스의 가로를 2배로 늘린다.
    • -vf "scale=iw/2:ih/2": 입력소스의 가로와 높이를 2배 줄인다.
    • -vf "scale='min(320,iw)':'min(240,ih)'": 위의 명령줄에서 스케일링을 수행하기 위한 최소 너비/높이는 각각 320 및 240픽셀로 설정. 즉, 입력 비디오의 크기를 기반으로 비디오 업스케일링 방지한다. 이는 품질이 좋지 않은 스케일링을 방지하는 매우 간단한 방법입니다.
  • -ss {position}: (input/output) 시작시간. HH:MM:SS로 지정할 수 있다. Input에 적용할 시 -i 옵션 전에 입력해야 한다.
  • -t {duration}: (input/output) Duration 시간. 초단위로 지정할 수 있다. Input에 적용할 시 -i 옵션 전에 입력해야 한다.
  • -to {position}: (output) 분할 완료할 시간 값. HH:MM:SS[.xxx]로 지정할 수 있다.
  • -y: 출력파일을 쓸 때 같은 이름의 파일이 있어도 확인없이 덮어쓰기를 하겠다는 의미.
  • -i {입력파일이름}: 변환할 원본 동영상 파일 이름을 지정합니다.
  • -ab {num}: 오디오 비트레이트를 지정한다.
  • -ar {num}: 오디오 샘플링 레이트를 지정한다.
  • -fs {num}: 파일 사이즈 제한
  • -f {format}: format (Force format)
  • -formats: 지원포맷확인
  • -ac {num}: 오디오 채널을 지정한다. 1이면 mono, 2이면 stereo
  • -b:a {num}: 오디오 비트레이트를 지정한다.
  • -vcodec {codec}: 비디오 코덱을 지정한다.
  • -level {num}: Baseline 값. (30이면, Baseline 3.0)
  • -b:v {num} 비디오 비트레이트를 지정한다.
  • -r {num}: 출력 동영상 프레임 레이트를 지정한다.
  • -s {num}: 화면 크기, 해상도를 지정한다. 원본 해상도보다 크게 할 경우 확대되서 나온다. 프리셋처럼 미리 지정된 문자가 있어서 직접 해상도를 지정하지 않아도 된다.
    • Ex) vga (640x480), sxga (1280x1024), wvga (852x480), hd720 (1280x720)
  • -threads {num}: 쓰레드수를 지정한다. 속도 향상을 위해 멀티쓰레드를 지정해줄 수 있다. 반드시 CPU 코어 갯수와 일치시킬 필요는 없지만, 보통은 코어 갯수에 맞춘다.
  • -strict experimental: 옵션의 엄격함을 느슨하게 풀어주는 옵션
  • -c:v copy: 코덱, 비디오, 복사 = 원본 비디오를 복사한다.
  • -c:a copy: 코덱, 오디오, 복사 = 원본 오디오를 복사한다.
  • -vn: 출력 비디오 제거
  • -an: 출력 오디오 제거
  • -sameq: 원본과 동일한 품질 세팅 - 제거된 옵션
    • -qscale 0: 원본과 동일한 품질 세팅
      • 모호한 표현이라는 경고가 출력된다. -q:v or -q:a를 사용하라 한다.
      • 하단의 #원본과 동일한 품질 항목 참조.
  • -vframes: 레코딩하는 비디오 프레임의 수
  • -re - Read input at native frame rate. Mainly used to simulate a grab device.
    • 즉, 비디오 파일을 스트리밍하려는 경우 이것을 사용하고 싶을 것입니다. 그렇지 않으면 너무 빠르게 스트리밍할 수 있습니다 (기본적으로 회선 속도로 스트리밍을 시도합니다).
    • 일반적으로 라이브 장치에서 스트리밍할 때 이 플래그를 사용하지 않고, 저장된 파일을 사용하여 라이브 스트리밍을 시뮬레이션 할 때 사용된다.
    • StreamingGuide – FFmpeg
  • -itsoffset -0.5 -i INPUT: INPUT 파일 타임스탬프를 0.5초 앞당긴 뒤 '1'로 인식 (map 을 사용할 때 필요)
  • -f concat: 파일 연결
  • -safe 0: ffmpeg에서 파일 경로의 안전성 검사를 비활성화하는 옵션입니다
    • 기본적으로 ffmpeg는 concat 프로토콜을 사용할 때 상대 경로와 절대 경로를 허용하지 않도록 안전 검사를 합니다. 이는 파일 경로로 인해 발생할 수 있는 잠재적인 보안 문제를 방지하기 위한 것입니다.
    • 그러나 스크립트에서 파일 경로를 명시적으로 지정해야 하는 경우, -safe 0 옵션을 사용하여 이러한 안전 검사를 비활성화할 수 있습니다. 이는 현재 디렉토리나 다른 절대 경로를 사용하여 파일을 지정할 때 유용합니다.
  • -fflags +genpts: 새로운 프레임 타임스탬프를 생성하여 재생 시간 문제를 해결합니다.

Hardware acceleration

NVidia

Example:

ffmpeg -y -hide_banner -analyzeduration 30M -probesize 100M -fflags +discardcorrupt  -i "in.ts" -vf "yadif=0:-1:0,scale=1280:720" -map 0:v:0 -c:v h264_nvenc -preset:v fast -rc constqp -qp 29.5 -profile:v high -movflags +faststart -map 0:a:0 -c:a:0 aac -b:a:0 160k -metadata:s:a:0 title="Audio#1" "out.mp4"

조용한 모드 (silent/quieter/less verbose)

ffmpeg -hide_banner -loglevel error ...

DRM

MPEG Common Encryption (CENC) 을 사용하여 암호화 하는 방법은 해당 페이지 참조.

Streaming

RTMP stream Input to FLV file, reencode

$ ffmpeg -i rtmp://IP:PORT/live/STREAMNAME -c:a aac -strict -2 -c:v h264 OUTPUT.flv

MP4 file Input to RTMP stream, reencode

$ ffmpeg -re -i INPUT.mp4 -c:a aac -strict -2 -c:v h264 -f flv rtmp://IP:PORT/live/STREAMNAME

HLS stream input to RTMP stream, reencode

$ ffmpeg -i http://IP:PORT/hls/STREAMNAME/index.m3u8 -c:a aac -strict -2 -c:v h264 -f flv rtmp://IP:PORT/live/STREAMNAME

MP4 file input to RTSP stream, reencode

$ ffmpeg -re -i INPUT.mp4 -c:a aac -strict -2 -c:v h264 -f rtsp -rtsp_transport tcp rtsp://IP:PORT/STREAMNAME

HLS stream input to RTSP stream, reencode

$ ffmpeg -i http://IP:PORT/hls/STREAMNAME/index.m3u8 -c:a aac -strict -2 -c:v h264 -f rtsp -rtsp_transport tcp rtsp://IP:PORT/STREAMNAME

RTSP stream input over TCP to RTMP stream, copy

  • Using ffmpeg to ingest over TCP instead of UDP makes sure you don't have the packet loss problem that UDP has and gives a better and more stable picture for your stream.
$ ... -rtsp_transport tcp -i CameraURL -c copy -f flv rtmp://IP:PORT/live/STREAMNAME

Convert RTSP to HLS using FFmpeg

ffmpeg -fflags nobuffer \
 -rtsp_transport tcp \
 -i rtsp://your-rtsp-server:8554/CH001.sdp \
 -vsync 0 \
 -copyts \
 -vcodec copy \
 -movflags frag_keyframe+empty_moov \
 -an \
 -hls_flags delete_segments+append_list \
 -f segment \
 -segment_list_flags live \
 -segment_time 1 \
 -segment_list_size 3 \
 -segment_format mpegts \
 -segment_list /tmp/stream/index.m3u8 \
 -segment_list_type m3u8 \
 -segment_list_entry_prefix /stream/ \
 /tmp/stream/%d.ts

After running this command you will find the index.m3u8 file along with multiple .ts (segment files) in the output directory that you specify in the command.

In this the index.m3u8 is the playlis file and .ts files are the fragments. You need to serve these files using any http server. I used goof for this.

To display this video in a browoser, you need to include this index.m3u8 file in the video tag in your html page, for example.

<video id="video-player" controls preload="none">
    <source src="/output-directory/index.m3u8" type="application/x-mpegURL">
</video>

Once this is done, navigate to the html page from your browser, you will be able to see the live stream on linux without using any flash plugin.

Example

1분10초 부터 30초 사이의 영상을 자르는 예제
ffmpeg -y -i input.avi -ss 00:01:10 -t 30 -vcodec libx264 -b 3695k -r 29 -acodec ac3 -ar 48000 -ab 192k output.avi
입력 영상의 시작시간 00:01:00 부터 종료시간 00:02:00 까지 영상을 자른다.
ffmpeg -i video.mp4 -ss 00:01:00 -to 00:02:00 -c copy cut.mp4
비디오 재생 속도 4배 빠르게 (재 인코딩 해야되므로 -c copy 불가)
ffmpeg -i TheGoodTheBadAndTheUgly.mp4 -vf "setpts=0.25*PTS" UpTheGoodTheBadAndTheUgly.mp4
비디오 재생 속도 2배 느리게 (재 인코딩 해야되므로 -c copy 불가)
ffmpeg -i TheGoodTheBadAndTheUgly.mp4 -vf "setpts=2*PTS" UpTheGoodTheBadAndTheUgly.mp4
동영상 파일 정보 얻기
ffmpeg -i video.avi
이미지들을 이용해 동영상 만들기 현재 디렉토리의 image1.jpg image2.jpg ... 이런식의 이미지 파일을 video.mpg 파일로 변환해줄 것이다
ffmpeg -f image2 -i image%d.jpg video.mpg
동영상 파일을 여러장의 이미지로 변환 (다음과 같은 이미지 포맷으로 변환가능하다: PGM, PPM, PAM, PGMYUV, JPEG, GIF, PNG, TIFF, SGI)
ffmpeg -i video.mpg image%d.jpg
iPod, iPhone을 위한 포맷으로 인코딩하기
ffmpeg -i source_video.avi input -acodec aac -ab 128kb -vcodec mpeg4 -b 1200kb -mbd 2 -flags +4mv+trell -aic 2 -cmp 2 -subcmp 2 -s 320x180 -title X final_video.mp4
PSP를 위한 포맷으로 인코딩하기
ffmpeg -i source_video.avi -b 300 -s 320x240 -vcodec xvid -ab 32 -ar 24000 -acodec aac final_video.mp4
동영상으로 부터 음성 추출하고 그것을 mp3로 저장하기
ffmpeg -i source_video.avi -vn -ar 44100 -ac 2 -ab 192 -f mp3 sound.mp3
WAV파일을 mp3파일로 변환
ffmpeg -i son_origine.avi -vn -ar 44100 -ac 2 -ab 192 -f mp3 son_final.mp3
AVI동영상을 .mpg 동영상으로 변환
ffmpeg -i video_origine.avi video_finale.mpg
MPG를 .avi로 변환
ffmpeg -i video_origine.mpg video_finale.avi
AVI를 animated gif로 변환 (비압축)
ffmpeg -i video_origine.avi gif_anime.gif
사운드 파일과 동영상 파일 합치기
ffmpeg -i son.wav -i video_origine.avi video_finale.mpg
How to make a Fade in and fade out on video + audio with ffmpeg
ffmpeg -i test.mp4 -vf "fade=in:0:50" -y test2.mp4
AVI파일을 플래쉬 파일 포맷인 FLV로 변환할때 사용하는 명령어
ffmpeg -i filename.avi -ar 22050 -ab 32 -f flv -s 320x240 filename.flv
변환된 FLV파일에서 원하는 순간의 스크린샷 이미지 추출
ffmpeg -i filename.flv -f image2 -t 0.001 -ss 3 filename.jpg
여러개의 동영상을 하나로 합치기
ffmpeg -i test1.avi -i test2.avi -vcodec copy -acodec copy -vcodec copy -acodec copy test12.avi -newvideo -newaudio
1장의 IMAGE와 음악을 합치기
ffmpeg -f image2 -loop 1 -i test.jpg -y -i knstyle.mp3 -vcodec mpeg4 -t 10 output.mp4

좋은 해상도의 GIF 로 변환

화면 영상캡쳐 후 해당 AVI 파일을 GIF로 변환하는 방법은 아래와 같다.

$ ffmpeg -i df.avi -vf crop=640:300:79:49 tmp2/test%03d.jpeg
$ ffmpeg -start_number 86 -r 20 -f image2 -s 600x300 -i tmp2/test%03d.jpeg test.mp4
$ ffmpeg -i test.mp4 test.gif

화질이 좋은 GIF 영상은 아래와 같이 변환할 수 있다.

PALETTE_NAME=__palette__.png
OUTPUT_DIR=output

if [[ ! -d $OUTPUT_DIR ]]; then
    mkdir -p $OUTPUT_DIR
fi

for i in *.mpg; do
    ffmpeg -i $i -vf "fps=15,scale=600:-1:flags=lanczos,palettegen" -y $PALETTE_NAME
    ffmpeg -i $i -i $PALETTE_NAME -filter_complex "fps=15,scale=600:-1:flags=lanczos[x];[x][1:v]paletteuse" $OUTPUT_DIR/$i.gif
done

화면 녹화 방법

Linux: x11grab

x11 예시:

ffmpeg -video_size 1024x768 -framerate 30 -f x11grab -i :0.0+100,200 output.mp4
  • -video_size - 녹화되는 크기
  • -framerate - 녹화 프레임 수
  • -f x11grab -i :0.0+xxx,xxx - 이것이 화면을 캡처한다는 것이고, 뒤에 +xxx,xxx는 왼쪽 위 끝 지점부터 + 몇 픽셀 한 위치를 녹화한다는 얘기이다.

kmsgrab

KMS video input device.

ffmpeg -device /dev/dri/card0 -f kmsgrab -i - -vf 'hwmap=derive_device=vaapi,scale_vaapi=w=1920:h=1080:format=nv12' -c:v h264_vaapi -b:v 2500k -maxrate 4000k -y output-file.mkv

gdigrab (Windows)

Windows 예시:

ffmpeg -f gdigrab -i desktop -f dshow -i audio=[마이크 장치 ] -c:v h264_nvenc -r 30 -preset llhq -tune zerolatency -crf 25 -pix_fmt yuv420p [출력 파일 ]

스케일링 (Resize; Scaling) 방법

여러 가지 스케일 조정 방법:

$ ffmpeg -i input.avi -vf scale=320:240 output.avi
$ ffmpeg -i input.jpg -vf scale=320:240 output_320x240.png
$ ffmpeg -i input.jpg -vf scale=320:-1 output_320.png
$ ffmpeg -i input.jpg -vf scale=iw*2:ih input_double_width.png
$ ffmpeg -i input.jpg -vf scale=iw*.5:ih*.5 input_half_size.png
$ ffmpeg -i input.jpg -vf scale="'if(gt(a,4/3),320,-1)':'if(gt(a,4/3),-1,240)'" output_320x240_boxed.png

원본과 동일한 품질

-c:v copy 으로 인코딩 없이 복사:

ffmpeg -i input.mp4 -c:v copy -c:a copy output.mp4

원본 비디오의 비트레이트를 확인하고 동일한 비트레이트를 사용하도록 설정할 수 있습니다.

ffmpeg -i input.mp4 -b:v <원본 비트레이트> -c:a copy output.mp4

CRF(Constant Rate Factor) 사용시 (H.264와 같은 코덱) 인코딩 품질을 조절하는 데 많이 사용됩니다. CRF 값은 0~51 사이에서 설정되며, 낮을수록 높은 품질을 의미합니다. 일반적으로 18~23 사이의 값을 사용하며, -crf 18은 거의 원본과 동일한 품질로 간주됩니다.

ffmpeg -i input.mp4 -c:v libx264 -crf 18 -preset veryfast output.mp4

-q:v 옵션을 사용해 원본과 유사한 품질을 얻고자 한다면, 일반적으로 -q:v 2 정도를 사용하면 됩니다. 다만 이 옵션은 VBR(Variable Bitrate) 방식이기 때문에 원본과 정확히 동일한 품질을 보장하기는 어렵습니다.

ffmpeg -i input.mp4 -q:v 2 -c:a copy output.mp4

비디오 쌓기 (stack)

Combine/stack two videos or images

Ffmpeg_vstack.png

ffmpeg -i input0 -i input1 -filter_complex vstack=inputs=2 output

Horizontal

Ffmpeg_hstack.png

ffmpeg -i input0 -i input1 -filter_complex hstack=inputs=2 output

With a border

Ffmpeg_stack_with_border.png

ffmpeg -i input0 -i input1 -filter_complex "[0]pad=iw+5:color=black[left];[left][1]hstack=inputs=2" output

Downmix and use original channel placements

Ffmpeg_stack_with_audio.png

ffmpeg -i input0 -i input1 -filter_complex "[0:v][1:v]vstack=inputs=2[v];[0:a][1:a]amerge=inputs=2[a]" -map "[v]" -map "[a]" -ac 2 output

Put all audio from each input into separate channels

Ffmpeg_stack_with_audio_sep_channels.png

ffmpeg -i input0 -i input1 -filter_complex "[0:v][1:v]vstack=inputs=2[v];[0:a][1:a]amerge=inputs=2,pan=stereo|c0<c0+c1|c1<c2+c3[a]" -map "[v]" -map "[a]"  output

Using audio from one particular input

ffmpeg -i input0 -i input1 -filter_complex "[0:v][1:v]vstack=inputs=2[v]" -map "[v]" -map 1:a output

Adding silent audio / If one input does not have audio

ffmpeg -i input0 -i input1 -filter_complex "[0:v][1:v]vstack=inputs=2[v];anullsrc[silent];[0:a][silent]amerge=inputs=2[a]" -map "[v]" -map "[a]" -ac 2 output.mp4

3 videos or images

Ffmpeg_3_hstack.png

ffmpeg -i input0 -i input1 -i input2 -filter_complex "[0:v][1:v][2:v]hstack=inputs=3[v]" -map "[v]" output

2x2 grid Using xstack

Ffmpeg_2x2_grid.png

ffmpeg -i input0 -i input1 -i input2 -i input3 -filter_complex "[0:v][1:v][2:v][3:v]xstack=inputs=4:layout=0_0|w0_0|0_h0|w0_h0[v]" -map "[v]" output

2x2 grid Using hstack and vstack

ffmpeg -i input0 -i input1 -i input2 -i input3 -filter_complex "[0:v][1:v]hstack=inputs=2[top];[2:v][3:v]hstack=inputs=2[bottom];[top][bottom]vstack=inputs=2[v]" -map "[v]" output

2x2 grid with text

Ffmpeg_2x2_grid_with_text.png

ffmpeg -i input0 -i input1 -i input2 -i input3 -filter_complex
"[0]drawtext=text='vid0':fontsize=20:x=(w-text_w)/2:y=(h-text_h)/2[v0];
 [1]drawtext=text='vid1':fontsize=20:x=(w-text_w)/2:y=(h-text_h)/2[v1];
 [2]drawtext=text='vid2':fontsize=20:x=(w-text_w)/2:y=(h-text_h)/2[v2];
 [3]drawtext=text='vid3':fontsize=20:x=(w-text_w)/2:y=(h-text_h)/2[v3];
 [v0][v1][v2][v3]xstack=inputs=4:layout=0_0|w0_0|0_h0|w0_h0[v]"
-map "[v]" output

4x4

ffmpeg -i input0 -i input1 -i input2 -i input3 -i input4 -i input5 -i input6 -i input7 -i input8 -i input9 -i input10 -i input11 -i input12 -i input13 -i input14 -i input15 -i input16 -filter_complex "[0:v][1:v][2:v][3:v][4:v][5:v][6:v][7:v][8:v][9:v][10:v][11:v][12:v][13:v][14:v][15:v]xstack=inputs=16:layout=0_0|w0_0|w0+w1_0|w0+w1+w2_0|0_h0|w4_h0|w4+w5_h0|w4+w5+w6_h0|0_h0+h4|w8_h0+h4|w8+w9_h0+h4|w8+w9+w10_h0+h4|0_h0+h4+h8|w12_h0+h4+h8|w12+w13_h0+h4+h8|w12+w13+w14_h0+h4+h8" output.mp4

If you need to scale the inputs first:

ffmpeg -i input0 -i input1 -i input2 -i input3 -i input4 -i input5 -i input6 -i input7 -i input8 -i input9 -i input10 -i input11 -i input12 -i input13 -i input14 -i input15 -i input16 -filter_complex "[0:v]scale=iw/4:-1[v0];[1:v]scale=iw/4:-1[v1];[2:v]scale=iw/4:-1[v2];[3:v]scale=iw/4:-1[v3];[4:v]scale=iw/4:-1[v4];[5:v]scale=iw/4:-1[v5];[6:v]scale=iw/4:-1[v6];[7:v]scale=iw/4:-1[v7];[8:v]scale=iw/4:-1[v8];[9:v]scale=iw/4:-1[v9];[10:v]scale=iw/4:-1[v10];[11:v]scale=iw/4:-1[v11];[12:v]scale=iw/4:-1[v12];[13:v]scale=iw/4:-1[v13];[14:v]scale=iw/4:-1[v14];[15:v]scale=iw/4:-1[v15];[v0][v1][v2][v3][v4][v5][v6][v7][v8][v9][v10][v11][v12][v13][v14][v15]xstack=inputs=16:layout=0_0|w0_0|w0+w1_0|w0+w1+w2_0|0_h0|w4_h0|w4+w5_h0|w4+w5+w6_h0|0_h0+h4|w8_h0+h4|w8+w9_h0+h4|w8+w9+w10_h0+h4|0_h0+h4+h8|w12_h0+h4+h8|w12+w13_h0+h4+h8|w12+w13+w14_h0+h4+h8" output.mp4

Resize/scale an input

ffmpeg -i input0 -i input2 -filter_complex "[0:v]scale=640:-1[v0];[v0][1:v]vstack=inputs=2" output

Delaying/pausing videos

ffmpeg -i top-left.mp4 -i top-right.mp4 -i bottom-left.mp4 -i bottom-right.mp4 -filter_complex "[1]tpad=start_mode=clone:start_duration=5[tr];[2]tpad=start_mode=clone:start_duration=10[bl];[3]tpad=start_mode=clone:start_duration=15[br];[0][tr][bl][br]xstack=inputs=4:layout=0_0|w0_0|0_h0|w0_h0[v];[1:a]adelay=5s:all=true[a1];[2:a]adelay=10s:all=true[a2];[3:a]adelay=15s:all=true[a3];[0:a][a1][a2][a3]amix=inputs=4[a]" -map "[v]" -map "[a]" output.mp4

비디오 합치기 (Concat)

분할된 동영상을 합칠때 사용한다. 먼저 합칠 동영상 파일을 텍스트 파일로 열거해준다.

file 'abcdefg.mp4'
file 'smile.mp4'

</code>filelist.txt</code>파일로 저장했을 경우 아래와 같이 해당 파일들을 연결할 수 있다.

ffmpeg -f concat -i filelist.txt -c copy output.mp4

명령행에서 한줄로 하고싶다면:

ffmpeg -i "concat:in1.mp4|in2.mp4" -c copy "out.mp4"

rtsp 로 스트리밍 하기

ffmpeg -re -f concat -safe 0 -stream_loop -1 -i "$file_list" -c:v copy -c:a copy -f rtsp "$rtsp_url"

여러 이미지 파일을 5초 간격으로 스트리밍하기

images.txt 파일 만들기:

file 'image1.jpg'
duration 5
file 'image2.jpg'
duration 5
file 'image3.jpg'
duration 5
...

실행:

ffmpeg -stream_loop -1 -f concat -safe 0 -i images.txt -vf format=yuv420p -f rtsp rtsp://localhost:8554/demo

목록 파일 없이 사용하는 방법

ffmpeg -framerate 1/5 -i image%03d.jpg -vf format=yuv420p -f rtsp rtsp://localhost:8554/demo

필터를 사용한 방법

ChatGPT 질문 결과임. 확인 필요:

ffmpeg -loop 1 -i image1.jpg -t 5 -loop 1 -i image2.jpg -t 5 -filter_complex "[0][1]concat=n=2:v=1:a=0,format=yuv420p" -f rtsp rtsp://localhost:8554/demo

TS File Concat

(for %i in (*.ts) do @echo file '%i') > mylist.txt
ffmpeg -f concat -i mylist.txt -c copy all.ts
ffmpeg -i all.ts -acodec copy -vcodec copy all.mp4

숫자 패턴일 경우

이미지 파일을 framerate 필요.

ffmpeg -framerate 25 -i %03d.png output.avi

Glob 패턴으로 머지하기

이미지 파일을 framerate 필요.

ffmpeg -framerate 25 -pattern_type glob -i "*.png" output.avi

이미지 목록 정렬 후 파이프라인 전달

이미지 파일을 framerate 필요.

cat $(find . -maxdepth 1 -name "*.png" | sort -V) | ffmpeg -framerate 25 -i - output.avi

영상 영역 잘라내기 (crop)

To crop a 80×60 section, starting from position (200, 100):

$ ffmpeg -i in.mp4 -filter:v "crop=80:60:200:100" -c:a copy out.mp4

영상의 재생 시간 단위 분할

-segment_time 이후에 지정된 시간 이후의 첫 번째 프레임에서 자릅니다. 따라서 완벽하게 정확하지 않다:

ffmpeg -i input.mp4 -c copy -map 0 -segment_time 00:20:00 -f segment output%03d.mp4

첫 번째 청크만 재생 가능한 경우 -reset_timestamps 1을 추가해 보세요:

ffmpeg -i input.mp4 -c copy -map 0 -segment_time 00:20:00 -f segment -reset_timestamps 1 output%03d.mp4

테스트 영상 생성

lavfi를 사용하면 된다. 특별한 input 없이 영상을 생성한다.

  • The allrgb source returns frames of size 4096x4096 of all rgb colors.
  • The allyuv source returns frames of size 4096x4096 of all yuv colors.
  • The color source provides an uniformly colored input.
  • The colorchart source provides a colors checker chart.
  • The colorspectrum source provides a color spectrum input.
  • The haldclutsrc source provides an identity Hald CLUT. See also haldclut filter.
  • The nullsrc source returns unprocessed video frames. It is mainly useful to be employed in analysis / debugging tools, or as the source for filters which ignore the input data.
  • The pal75bars source generates a color bars pattern, based on EBU PAL recommendations with 75% color levels.
  • The pal100bars source generates a color bars pattern, based on EBU PAL recommendations with 100% color levels.
  • The rgbtestsrc source generates an RGB test pattern useful for detecting RGB vs BGR issues. You should see a red, green and blue stripe from top to bottom.
  • The smptebars source generates a color bars pattern, based on the SMPTE Engineering Guideline EG 1-1990.
  • The smptehdbars source generates a color bars pattern, based on the SMPTE RP 219-2002.
  • The testsrc source generates a test video pattern, showing a color pattern, a scrolling gradient and a timestamp. This is mainly intended for testing purposes.
  • The testsrc2 source is similar to testsrc, but supports more pixel formats instead of just rgb24. This allows using it as an input for other tests without requiring a format conversion.
  • The yuvtestsrc source generates an YUV test pattern. You should see a y, cb and cr stripe from top to bottom.

Parameters

The sources accept the following parameters:

level
Specify the level of the Hald CLUT, only available in the haldclutsrc source. A level of N generates a picture of NNN by NNN pixels to be used as identity matrix for 3D lookup tables. Each component is coded on a 1/(N*N) scale.
color, c
Specify the color of the source, only available in the color source. For the syntax of this option, check the (ffmpeg-utils)"Color" section in the ffmpeg-utils manual.
size, s
Specify the size of the sourced video. For the syntax of this option, check the (ffmpeg-utils)"Video size" section in the ffmpeg-utils manual. The default value is 320x240.
This option is not available with the allrgb, allyuv, and haldclutsrc filters.
rate, r
Specify the frame rate of the sourced video, as the number of frames generated per second. It has to be a string in the format frame_rate_num/frame_rate_den, an integer number, a floating point number or a valid video frame rate abbreviation. The default value is "25".
duration, d
Set the duration of the sourced video. See (ffmpeg-utils)the Time duration section in the ffmpeg-utils(1) manual for the accepted syntax.
If not specified, or the expressed duration is negative, the video is supposed to be generated forever.
Since the frame rate is used as time base, all frames including the last one will have their full duration. If the specified duration is not a multiple of the frame duration, it will be rounded up.
sar
Set the sample aspect ratio of the sourced video.
alpha
Specify the alpha (opacity) of the background, only available in the testsrc2 source. The value must be between 0 (fully transparent) and 255 (fully opaque, the default).
decimals, n
Set the number of decimals to show in the timestamp, only available in the testsrc source.
The displayed timestamp value will correspond to the original timestamp value multiplied by the power of 10 of the specified value. Default value is 0.
type
Set the type of the color spectrum, only available in the colorspectrum source. Can be one of the following:
  • black, white, all
patch_size
Set patch size of single color patch, only available in the colorchart source. Default is 64x64.
preset
Set colorchecker colors preset, only available in the colorchart source.
Available values are: reference, skintones
Default value is reference.

Examples

Generate a video with a duration of 5.3 seconds, with size 176x144 and a frame rate of 10 frames per second:
testsrc=duration=5.3:size=qcif:rate=10
The following graph description will generate a red source with an opacity of 0.2, with size "qcif" and a frame rate of 10 frames per second:
[email protected]:s=qcif:r=10
If the input content is to be ignored, nullsrc can be used. The following command generates noise in the luma plane by employing the geq filter:
nullsrc=s=256x256, geq=random(1)*255:128:128

testsrc

The testsrc filter generates a test video pattern showing a color pattern, a scrolling gradient, and a timestamp. This is useful for testing purposes.

This example will create a 10 second output, 30 fps (300 frames total), with a frame size of 640x360

ffmpeg -f lavfi -i testsrc=duration=10:size=1280x720:rate=30 testsrc.mpg

The following command will generate a video with a duration of 5.3 seconds, with size 176x144 and a frame rate of 10 frames per second.

ffmpeg -f lavfi -i testsrc=duration=5.3:size=qcif:rate=10 testsrc2.mp4

smptebars

The smptebars source generates a color bars pattern, based on the SMPTE Engineering Guideline EG 1-1990.

The smptehdbars source generates a color bars pattern, based on the SMPTE RP 219-2002.

This example will create a 10 second output, 30 fps (300 frames total), with a frame size of 640x360:

ffmpeg -f lavfi -i smptebars=duration=10:size=640x360:rate=30 smptebars.mp4

color source

The following graph description will generate a red source with an opacity of 0.2, with size "qcif" and a frame rate of 10 frames per second with the duration of 5 seconds.

ffmpeg -f lavfi -i color=c=[email protected]:duration=5:s=qcif:r=10 colorsrc.mp4

rgbtestsrc

The rgbtestsrc source generates an RGB test pattern useful for detecting RGB vs BGR issues. We should see a red, green and blue stripe from top to bottom.

ffmpeg -f lavfi -i rgbtestsrc -pix_fmt yuv420p -t 5 rgbtestsrc.mp4

파일이름 시간으로 포맷팅

strftime

파일 이름에 strftime()을 사용하여 세그먼트 파일 이름을 현지시간(localtime)으로 확장합니다. 이 모드에서는 세그먼트 번호도 사용할 수 있지만 이를 사용하려면 second_level_segment_index hls_flag를 지정해야 하며 %%d가 지정자가 됩니다.

ffmpeg -i in.nut -strftime 1 -hls_segment_filename 'file-%Y%m%d-%s.ts' out.m3u8

이 예에서는 재생 목록 out.m3u8 및 세그먼트 파일(file-20160215-1455569023.ts, file-20160215-1455569024.ts 등)을 생성합니다. 참고: 일부 시스템/환경에서는 %s 지정자를 사용할 수 없습니다. strftime() 문서를 참조하세요.

ffmpeg -i in.nut -strftime 1 -hls_flags second_level_segment_index -hls_segment_filename 'file-%Y%m%d-%%04d.ts' out.m3u8

이 예에서는 재생 목록 out.m3u8 및 세그먼트 파일(file-20160215-0001.ts, file-20160215-0002.ts 등)을 생성합니다.

strftime_mkdir

-strftime_mkdir과 함께 사용하면 파일 이름으로 확장되는 모든 하위 디렉터리가 생성됩니다.

ffmpeg -i in.nut -strftime 1 -strftime_mkdir 1 -hls_segment_filename '%Y%m%d/file-%Y%m%d-%s.ts' out.m3u8

이 예에서는 디렉터리 201560215(없는 경우)를 생성한 다음 재생 목록 out.m3u8 및 세그먼트 파일(20160215/file-20160215-1455569023.ts, 20160215/file-20160215-1455569024.ts 등)을 생성합니다. .

ffmpeg -i in.nut -strftime 1 -strftime_mkdir 1 -hls_segment_filename '%Y/%m/%d/file-%Y%m%d-%s.ts' out.m3u8

이 예에서는 디렉터리 계층 구조 2016/02/15(하나라도 존재하지 않는 경우)를 생성한 다음 재생 목록 out.m3u8 및 세그먼트 파일 2016/02/15/file-20160215-1455569023.ts, 2016/02/15/file-20160215-1455569024.ts 등을 생성합니다.

영상 퀄리티 조절 (sameq, qscale)

-sameq 플래그였는데, 이젠 안 쓴다. -qscale 0를 사용하자.

오디오 샘플 포맷 변경 방법 (sample_fmt)

ffmpeg -i  -c:a flac -sample_fmt s16 output.flac

Constant Rate Factor (CRF)

Bitrate 대신 우리 눈으로 인식하는 화질로 품질을 조절.

최상의 품질을 유지하고 파일 크기에 신경을 덜 쓰고 싶다면 이 속도 제어 모드를 사용하십시오. 이것은 대부분의 용도에 권장되는 속도 제어 모드입니다.

이 방법을 사용하면 출력 파일 크기가 덜 중요할 때 인코더가 전체 파일에 대해 특정 출력 품질을 달성하려고 시도할 수 있습니다. 이는 단일 패스로 최대 압축 효율성을 제공합니다. 각 프레임에 대해 소위 양자화기를 조정하여 요청된 품질 수준을 유지하는 데 필요한 비트 전송률을 얻습니다. 단점은 특정 파일 크기를 얻거나 특정 크기 또는 비트 전송률을 초과하지 않도록 말할 수 없다는 것입니다. 즉, 이 방법은 스트리밍용 비디오 인코딩에 권장되지 않습니다.

스트리밍용으로 저장된 영상을 1시간 단위로 다시 저장하기

mkdir records
ffmpeg -hide_banner -i rtsp://localhost:8554/cam4 -c copy -f segment -strftime 1 -strftime_mkdir 1 -segment_time 3600 -reset_timestamps 1 ./records/%Y%m%d-%H%M%S.mp4

이러면 records 폴더에

20240515_101044-328758.mp4
20240515_111042-062053.mp4
...

이런식으로 파일이 저장된다. -segment_time 3600 옵션을 지정했지만 제멋대로 파일 크기가 바뀌더라.

이 파일을 직접 사용하려면 다음과 같은 에러가 발생된다:

DTS 1624139402481, next:10790932074 st:0 invalid dropping
PTS 1624139402481, next:10790932074 invalid dropping st:0

DTS, PTS가 잘못된듯... (왜 잘못된진 모른다. 추정컨데 스트리밍 상황 등에 따라 파일을 잘라내는듯 하다.)

그래서 이 파일 목록을 만들고

for f in *.mp4; do echo "file '$PWD/$f'"; done > file_list.txt

이 목록으로 재 인코딩하여 파일을 다시 분할한다.

mkdir output
ffmpeg -f concat -safe 0 -i file_list.txt -c:v libx264 -crf 18 -preset veryslow -c:a copy -f segment -strftime_mkdir 1 -strftime 1 -segment_time 3600 -reset_timestamps 1 ./output/%Y%m%d-%H%M%S.mp4

재 인코딩을 해야 하므로 -c:v copy 플래그는 사용 금지.

좌우 반전/상하 반전 (Flip)

ffmpeg -i input_video_file_path -vf hflip output_video_file_path
ffmpeg -i input_video_file_path -vf vflip output_video_file_path

회전 (rotate)

$ ffmpeg -i input.m4v -metadata:s:v rotate="90" -codec copy output.m4v

카메라 영상 회전하기

카메라 영상을 cv2 같은 걸로 불러오면 비정상 출력된다. (회전된 상태)

카메라 영상은 metadata 에 rotation 정보가 있으므로 이 것을 제거한다:

ffmpeg -i input.mp4 -c copy -metadata:s:v:0 rotate=0 output.mp4

그러면 원본 파일이 나오는데 이 것을 다시 회전시켜 인코딩한다:

ffmpeg -i input.mp4 -vf "transpose=2" output.mp4

transpose 옵션은 아래 목록 참조:

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

참고로 180도 회전은 vflip, hflip 하면 된다:

ffmpeg.exe -i input.mp4 -vf "vflip,hflip" output.mp4

영상 병합 (map)

Video and Audio muxing example:

$ ffmpeg -i video_only.mp4 -i audio_only.webm -c:v copy -c:a aac  -map 0:v:0 -map 1:a:0 result.mp4

모바일용 영상 변환

안드로이드 공식 지원 파일 포맷:

코덱

확장자

비고

H.263

3gp, mp4

H.264 AVC

3gp, mp4, ts

인코딩은 허니컴부터 지원
ts 형식 또한 허니컴부터 지원

MPEG-4 SP

3gp

VP8

webm, mkv

2.3.3 부터 지원
스트리밍 형태는 ICS 부터 가능

아이폰 공식 지원 파일 포맷:

코덱

확장자

비고

H.264

m4v, mp4, mov, 3gp

640 * 480, 30fps, 1.5Mbps
320 * 240, 30fps, 768Kbps

MPEG-4

m4v, mp4, mov, 3gp

640 * 480, 30fps, 2.5Mbps

참고로 아이폰에서의 동영상 재생 심사 기준 중 HLS를 사용하지 않고, 10Mb 이상의 파일을 스트리밍 형식으로 재생하는 경우 Reject 사유에 포함될 수 있다. 인코딩시 비트레이트 조건:

화질

비디오

오디오

Low

96Kbps

64Kbps

Medium

256Kbps

64Kbps

High

800Kbps

64Kbps

자주 사용하는 모바일용 변환:

$ ffmpeg -i input.avi -c:v libx264 -b:v 800k -c:a aac -b:a 64k -ar 44100 output.mp4

TS 변환 방법

See also: MPEG transport stream#Use ffmpeg

무제한 스트리밍 (Infinite stream; -stream_loop)

You should be able to use the -stream_loop -1 flag before the input (-i):

$ ffmpeg -threads 2 -re -fflags +genpts -stream_loop -1 -i ./test.mp4 -c copy ./test.m3u8

The -fflags +genpts will regenerate the pts timestamps so it loops smoothly, otherwise the time sequence will be incorrect as it loops.

H264 변환

인코딩 시작 시간 180초, FrameRate 10초, h.264 비디오 코덱을 사용한다.

$ ffmpeg -i n5.mp4 -ss 180 -r 10 -vcodec h264 n6.mp4

입력 파일의 1시간 44분 17초 부터 800초 까지 Video profile=high, Bitrate=2015kb/s, H264, Audio=copy

$ ffmpeg -ss 01:44:17 -t 800 -i original.mp4 -profile:v high -b:v 2015k -c:v h264 -c:a copy original-convert.mp4

특정 프레임 STEP으로 이미지 저장 방법

$ ffmpeg -i sageri.mp4 -vf framestep=20,setpts=N/FRAME_RATE/TB result/result.%05d.jpg

폴더안의 모든 mp4파일을 변환하는 스크립트:

#!/bin/bash

for i in *.mp4; do
    dirname=${i%.*}
    if [[ ! -d "$dirname" ]]; then
        mkdir "$dirname"
    fi
    ffmpeg -i $i -vf framestep=20,setpts=N/FRAME_RATE/TB $dirname/$dirname.%05d.jpg
done

INFORMATION

딥영상 영상 추출 할 때 사용한 명령이다

키프레임 단위 이미지 추출

I-Frame 단위로 영상을 선택하는 필터를 적용한다.

$ ffmpeg -i save-20191127_104234.avi -q:v 2 -vf select="eq(pict_type\,PICT_TYPE_I)" -vsync 0 front1/%04d.jpg

특정 프레임 이미지 추출

ffmpeg -i lcsc130906-164626.255.mp4 -s 320x240 -ss 00:00:13 -vcodec png test.png

FFmpeg 썸네일(Thumbnail) 지정 방법

ffmpeg -loop 1 -i "thumb.jpg" -i "in.aac" -c:v libx264 -tune stillimage -acodec copy -pix_fmt yuv420p -shortest "out.mp4"

자막 파일을 내장하는 MP4 파일 만들기

ffmpeg -i "in.mp4" -i "sub.srt" -map 0:v:0 -c:v copy -map 0:a:0 -c:a copy -map 1 -c:s:0 mov_text -metadata:s:s:0 title=srt -metadata:s:s:0 language=kor "out.mp4"

FFmpeg 여러장의 이미지와 음악을 병합하는 명령어

(Android NDK에서 FFmpeg v1.2.2으로 테스트가 완료되었다)

# -threads 1: Thread 1개를 사용한다.
# -f image2: 이미지를 변환하는 포맷을 적용한다.
# -s 320x240: 영상의 크기는 320x240으로 적용한다.
# -r 18: FrameRate(FPS)는 18로 설정한다.
# -i /sdcard/sdcard0/DCIM/img%d.jpg: 위의 설정을 해당 INPUT파일에 적용한다.
# -----------------------------------------------------------------------
# -ss 2: 2초 부터 시작한다.
# -t 10: 10초동안 적용한다.
# -i /sdcard/sdcard0/Music/temp.mp3: 위의 설정을 해당 INPUT파일에 적용한다.
# -----------------------------------------------------------------------
# -acodec copy: 오디오코덱 정보를 복사(COPY)한다.
# -y: 동일한 파일이 존재할 경우 덮어쓰기 한다.
# /sdcard/sdcard0/Download/result.mp4: 위의 설정을 해당 OUTPUT파일에 적용한다.
# -----------------------------------------------------------------------
ffmpeg -threads 1 -f image2 -s 320x240 -r 18 -i /sdcard/sdcard0/DCIM/img%d.jpg -ss 2 -t 10 -i /sdcard/sdcard0/Music/temp.mp3 -acodec copy -y /sdcard/sdcard0/Download/result.mp4

비디오와 오디오를 함께 파이프로 전달하는 방법

Use a named pipe (FIFO). Simplified example for Linux/macOS:

Make named pipes:

mkfifo video
mkfifo audio

Output/pipe video and audio to stdout. This is using ffmpeg to generate video and audio to the named pipes just for demonstration purposes.

ffmpeg -y -re -f lavfi -i testsrc2=s=1280x720:r=25 -f rawvideo video & ffmpeg -y -re -f lavfi -i sine=r=44100 -f s16le audio

Use the named pipes as inputs for ffmpeg:

ffmpeg -f rawvideo -video_size 320x240 -pixel_format yuv420p -framerate 25 -i video -f s16le -sample_rate 44100 -channels 1 -i audio -t 10 output.mp4

전체 프레임의 PTS를 출력하는 방법

-vf showinfo 플래그를 사용하면 비디오의 프레임별 정보를 확인할 수 있다.

ffmpeg -i 20240516_000830-336375.mp4 -vf showinfo -f null -

다음과 같이 출력됨:

DTS -18446492073, next:1684276 st:0 invalid dropping
PTS -18446492073, next:1684276 invalid dropping st:0
[Parsed_showinfo_0 @ 0x5e90efa16100] n:  44 pts: 127561 pts_time:1.41734 pos:   748517 fmt:yuvj420p sar:0/1 s:1920x1080 i:P iskey:0 type:P checksum:282D0C62 plane_checksum:[BC978477 F7302159 8DDE6683] mean:[103 126 135] stdev:[44.3 5.8 9.9]
[Parsed_showinfo_0 @ 0x5e90efa16100] color_range:pc color_space:bt709 color_primaries:bt709 color_trc:bt709
DTS -18446486043, next:1717643 st:0 invalid dropping
PTS -18446486043, next:1717643 invalid dropping st:0
[Parsed_showinfo_0 @ 0x5e90efa16100] n:  45 pts: 130564 pts_time:1.45071 pos:   760197 fmt:yuvj420p sar:0/1 s:1920x1080 i:P iskey:0 type:P checksum:15F81C80 plane_checksum:[C55EC981 3F730DCF 9C7F4521] mean:[102 126 136] stdev:[43.5 5.9 10.1]
[Parsed_showinfo_0 @ 0x5e90efa16100] color_range:pc color_space:bt709 color_primaries:bt709 color_trc:bt709
DTS -18446483073, next:1751010 st:0 invalid dropping
PTS -18446483073, next:1751010 invalid dropping st:0
[Parsed_showinfo_0 @ 0x5e90efa16100] n:  46 pts: 133567 pts_time:1.48408 pos:   779000 fmt:yuvj420p sar:0/1 s:1920x1080 i:P iskey:0 type:P checksum:A0AED87B plane_checksum:[45526828 5139182B 50745828] mean:[102 126 136] stdev:[43.5 5.9 10.1]
[Parsed_showinfo_0 @ 0x5e90efa16100] color_range:pc color_space:bt709 color_primaries:bt709 color_trc:bt709
DTS -18446477043, next:1784377 st:0 invalid dropping
PTS -18446477043, next:1784377 invalid dropping st:0
[Parsed_showinfo_0 @ 0x5e90efa16100] n:  47 pts: 136570 pts_time:1.51744 pos:   789899 fmt:yuvj420p sar:0/1 s:1920x1080 i:P iskey:0 type:P checksum:98464413 plane_checksum:[B4F2AAE9 75DA6E86 A1792A95] mean:[102 125 136] stdev:[43.3 5.9 10.3]
[Parsed_showinfo_0 @ 0x5e90efa16100] color_range:pc color_space:bt709 color_primaries:bt709 color_trc:bt709
...

원하는 정보만 jsonl 포맷으로 출력하려면 다음과 같이 하면 된다:

ffmpeg -i 20240516_000830-336375.mp4 -vf showinfo -f null - 2>&1 \
    | grep '^\[Parsed_showinfo' \
    | sed -e 's/\[.* @ 0x[a-f0-9]*\] //g' \
    | grep '^n:' \
    | sed -e 's/ fmt:.*//g' -e 's/n: *\([0-9]*\) *pts: *\([0-9]*\) *pts_time: *\([0-9.]*\) *pos: *\([0-9]*\)/{"n": \1, "pts": \2, "pts_time": \3, "pos": \4}/g'

다음과 같이 출력됨:

{"n": 0, "pts": 6030, "pts_time": 0.067, "pos": 13942}
{"n": 1, "pts": 9000, "pts_time": 0.1, "pos": 73771}
{"n": 2, "pts": 18000, "pts_time": 0.2, "pos": 140669}
{"n": 3, "pts": 20250, "pts_time": 0.225, "pos": 154912}

쓰기 편하게 스크립트로:

#!/usr/bin/env bash

REMOVE_LOGGING_PREFIX='s/\[.* @ 0x[a-f0-9]*\] //g'
REMOVE_FMT='s/ fmt:.*//g'
FORMAT_JSONL='s/n: *\([0-9]*\) *pts: *\([0-9]*\) *pts_time: *\([0-9.]*\) *pos: *\([0-9]*\)/{"n": \1, "pts": \2, "pts_time": \3, "pos": \4}/g'

function gen_pts
{
    if [[ ! -f "$1" ]]; then
        echo "Not found video file: '$1'" 1>&2
        exit 1
    fi

    ffmpeg -hide_banner -i "$1" -vf showinfo -f null - 2>&1 \
        | grep '^\[Parsed_showinfo' \
        | sed -e "$REMOVE_LOGGING_PREFIX" \
        | grep '^n:' \
        | sed -e "$REMOVE_FMT" \
        | sed -e "$FORMAT_JSONL"
}

while [[ -n $1 ]]; do
    echo "Run ffmpeg: '$1' ..."
    gen_pts "$1" > "$1.pts"
    shift
done

Filter complex

-filter_complex 플래그 사용법.

세아 영상 처리 예제

ffmpeg -i video1.mp4 -i video2.mp4 -filter_complex "[0:v]scale=1920:1080[left];[1:v]scale=1920:1080[right];[right]hflip[right_flip];[left][right_flip]hstack=inputs=2[v]" -map "[v]" output.mp4
  1. video1.mp4 영상을 1920x1080 으로 스케일 한다음 왼쪽,
  2. video2.mp4 영상을 1920x1080 으로 스케일 한다음 좌우반전(hflip) 후 오른쪽,
  3. 그리고 두 영상을 수평으로 쌓는다(hstack)

Realtime Overlay

ffmpeg -re -loop 1 -i smpte-color-bars-1080p.png -vf drawtext="fontfile=monofonto.ttf: fontsize=96: box=1: [email protected]: boxborderw=5: fontcolor=white: x=(w-text_w)/2: y=((h-text_h)/2)+((h-text_h)/4): text='%{gmtime\:%H\\\\\:%M\\\\\:%S}'" -r 25 -vcodec libx264 -f mpegts udp://127.0.0.1:1234

The important bit for the timecode being: text='%{gmtime\:%H\\\\\:%M\\\\\:%S}'

There is some crazy escaping in there to get the colons to display(in bash), but that is UTC/GMT time of day timecode burnt in... just need to figure out the syntax for multiple drawtext functions now and I'm all set...

Realtime Overlay 2

-vf drawtext="expansion=strftime:fontfile='/usr/share/fonts/cantarell/Cantarell-Light.otf':fontsize=14:fontcolor=white:shadowcolor=black:shadowx=2:shadowy=1:text='%Y-%m-%d\ %H\\\\:%M\\\\:%S':x=8:y=8"

Ffmpeg-embed-current-time-example-02.png

Stream Mapping (-map flag)

-map 옵션은 출력에 포함되어야 하는 입력의 스트림을 선택하는 데 사용됩니다. -map 옵션을 사용하여 네거티브 매핑으로 특정 스트림을 제외할 수도 있습니다.

Ffmpeg_map_example.png

Stream specifiers

Some options are applied per-stream, e.g. bitrate or codec. Stream specifiers are used to precisely specify which stream(s) a given option belongs to.

A stream specifier is a string generally appended to the option name and separated from it by a colon. E.g. -codec:a:1 ac3 contains the a:1 stream specifier, which matches the second audio stream. Therefore, it would select the ac3 codec for the second audio stream.

A stream specifier can match several streams, so that the option is applied to all of them. E.g. the stream specifier in -b:a 128k matches all audio streams.

An empty stream specifier matches all streams. For example, -codec copy or -codec: copy would copy all the streams without reencoding.

Possible forms of stream specifiers are:

stream_index
Matches the stream with this index. E.g. -threads:1 4 would set the thread count for the second stream to 4. If stream_index is used as an additional stream specifier (see below), then it selects stream number stream_index from the matching streams. Stream numbering is based on the order of the streams as detected by libavformat except when a program ID is also specified. In this case it is based on the ordering of the streams in the program.
stream_type[:additional_stream_specifier]
비디오의 경우 'v' 또는 'V'
  • 'v'는 모든 비디오 스트림과 일치하며,
  • 'V'는 첨부된 사진, 비디오 썸네일 또는 커버 아트가 없는 비디오 스트림에만 일치합니다.
오디오의 경우 'a'
자막의 경우 's'
데이터의 경우 'd'
첨부 파일의 경우 't'
additional_stream_specifier를 사용할 경우, 이 유형(Type)을 가지고 있고 additional_stream_specifier와 일치하는 스트림과 매칭합니다.
p:program_id[:additional_stream_specifier]
Matches streams which are in the program with the id program_id. If additional_stream_specifier is used, then it matches streams which both are part of the program and match the additional_stream_specifier.
#stream_id or i:stream_id
Match the stream by stream id (e.g. PID in MPEG-TS container).
m:key[:value]
Matches streams with the metadata tag key having the specified value. If value is not given, matches streams that contain the given tag with any value.
u
Matches streams with usable configuration, the codec must be defined and the essential information such as video dimension or audio sample rate must be present.

Note that in ffmpeg, matching by metadata will only work properly for input files.

저 지연 모드 (Lowest Latency) 방법

  • Input Flags
    • -fflags nobuffer
    • -flags low_delay
  • Output Flags
    • -c:v libx264
    • -preset ultrafast
    • -crf 30

H.264

RTSP flags

rtsp_transport

  -rtsp_transport    <flags>      ED...... set RTSP transport protocols (default 0)
     udp                          ED...... UDP
     tcp                          ED...... TCP
     udp_multicast                .D...... UDP multicast
     http                         .D...... HTTP tunneling

FFmpeg#Nonmatching transport in server reply 관련 에러 발생시 사용하면 된다.

rtsp_flags

  -rtsp_flags        <flags>      .D...... set RTSP flags (default 0)
     filter_src                   .D...... only receive packets from the negotiated peer IP
     listen                       .D...... wait for incoming connections
     prefer_tcp                   ED...... try RTP via TCP first, if available

-rtsp_flags listen 를 사용하면 연결이 될 때 까지 기다린다.

다중 해상도 HLS를 생성하는 방법

ffmpeg -f flv -i "rtmp://server/live/livestream" \
  -map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 -map 0:v:0 -map 0:a:0 \
  -c:v libx264 -crf 22 -c:a aac -ar 44100 \
  -filter:v:0 scale=w=480:h=360  -maxrate:v:0 600k -b:a:0 500k \
  -filter:v:1 scale=w=640:h=480  -maxrate:v:1 1500k -b:a:1 1000k \
  -filter:v:2 scale=w=1280:h=720 -maxrate:v:2 3000k -b:a:2 2000k \
  -var_stream_map "v:0,a:0,name:360p v:1,a:1,name:480p v:2,a:2,name:720p" \
  -preset fast -hls_list_size 10 -threads 0 -f hls \
  -hls_time 3 -hls_flags independent_segments \
  -master_pl_name "livestream.m3u8" \
  -y "livestream-%v.m3u8"

WARNING

명령행 결과 다시 테스트 해 봐야 한다. 아마도 잘못된듯

The master m3u8, generated by FFmpeg:

#EXTM3U
#EXT-X-VERSION:6
#EXT-X-STREAM-INF:BANDWIDTH=1210000,RESOLUTION=480x360,CODECS="avc1.640015,mp4a.40.2"
livestream-360p.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=2283600,RESOLUTION=640x480,CODECS="avc1.64001e,mp4a.40.2"
livestream-480p.m3u8

#EXT-X-STREAM-INF:BANDWIDTH=3933600,RESOLUTION=1280x720,CODECS="avc1.64001f,mp4a.40.2"
livestream-720p.m3u8

HLS를 저장하면서 m3u8 파일을 이용하여 스트리밍 출력

명령행 두 개로 사용하는 방법

ffmpeg -i rtsp://admin:[email protected]/stream1 -c copy asdf.m3u8
ffmpeg -i asdf.m3u8 -f rtsp rtsp://localhost:8554/stream

단말기별 FFmpeg 옵션정리

Android Conversions

device

screen resolution

command

Nexus One
(if input video size > 800x480)

800x480

ffmpeg -i ally.avi -y -acodec aac -strict experimental -ac 2 -ab 160k -s 800x480 -vcodec libx264 -vpre ipod640 -vpre slow -crf 22 -f mp4 1.mp4

Nexus One
(if input video size <= 800x480)

800x480

ffmpeg -i ally.avi -y -acodec aac -strict experimental -ac 2 -ab 160k -vcodec libx264 -vpre ipod640 -vpre slow -crf 22 -f mp4 2.mp4

Dream/G1
if input video size > 480x320

480x320

ffmpeg -i ally.avi -y -acodec aac -strict experimental -ac 2 -ab 160k -vcodec libx264 -s 480x320 -vpre ipod640 -vpre slow -crf 22 -f mp4 3.mp4

Dream/G1
if input video size <= 480x320

480x320

ffmpeg -i ally.avi -y -acodec aac -strict experimental -ac 2 -ab 160k -vcodec libx264 -vpre ipod640 -vpre slow -crf 22 -f mp4 4.mp4

Magic/myTouch

480x320

same as G1

Droid
(if input video size > 854x480)

854x480

ffmpeg -i ally.avi -y -acodec aac -strict experimental -ac 2 -ab 160k -vcodec libx264 -s 854x480 -vpre ipod640 -vpre slow -crf 22 -f mp4 5.mp4

Droid
(if input video size <= 854x480)

854x480

ffmpeg -i ally.avi -y -acodec aac -strict experimental -ac 2 -ab 160k -vcodec libx264 -vpre ipod640 -vpre slow -crf 22 -f mp4 6.mp4

Eris/Desire

480x320

same as G1

Hero

480x320

same as G1

Cliq/DEXT

480x320

same as G1

Behold II

480x320

same as G1

Apple Format Conversions

device

screen resolution

command

iPhone

320x480

ffmpeg -i ally.avi -acodec aac -strict experimental -ac 2 -ab 160k -s 480x320 -vcodec libx264 -vpre slow -vpre ipod640 -b 1200k -f mp4 a1.mp4

ipod touch

same as iphone

same as iphone

ipod nano

320x480

same as iphone

ipod classic

640x480

same as iphone

iPhone 4/iPod Touch 4

640x480

ffmpeg -i ally.avi -acodec aac -strict experimental -ac 2 -ab 160k -s 640x480 -vcodec libx264 -vpre slow -vpre ipod640 -b 1200k -f mp4 -threads 0 a2.mp4

iPad

1024x768

ffmpeg -i ally.avi -acodec aac -strict experimental -ac 2 -ab 160k -s 1024x768 -vcodec libx264 -vpre slow -vpre ipod640 -b 1200k -f mp4 -threads 0 a3.mp4

Apple Universal

1280x720

ffmpeg -i ally.avi -acodec aac -strict experimental -ac 2 -ab 160k -s 1080x720 -vcodec libx264 -vpre slow -vpre ipod640 -b 1200k -f mp4 -threads 0 a4.mp4

Old Android Conversions

device

screen resolution

command

Nexus One
(if input video size > 800x480)

800x480

ffmpeg -i all.flv -y -f mp4 -strict experimental -vcodec mpeg4 -sameq -s 800x480 -acodec aac -ab 160000 -r 18 old2.mp4

Nexus One
(if input video size <= 800x480)

800x480

ffmpeg -i INPUT -y -f mp4 -vcodec mpeg4 -sameq -acodec aac -ab 160000 -r 18 OUTPUT

Dream/G1
if input video size > 480x320

480x320

ffmpeg -i all.flv -y -f mp4 -strict experimental -vcodec mpeg4 -sameq -s 480x320 -acodec aac -ab 160000 -r 18 old3.mp4

Dream/G1
if input video size <= 480x320

480x320

same as old2

Magic/myTouch

480x320

same as G1

Droid
(if input video size > 854x480)

854x480

ffmpeg -i all.flv -y -f mp4 -strict experimental -vcodec mpeg4 -sameq -s 854x480 -acodec aac -ab 160000 -r 18 old4.mp4

Droid
(if input video size <= 854x480)

850x480

ffmpeg -i all.flv -y -f mp4 -vcodec mpeg4 -sameq -acodec aac -ab 160000 -r 18 old5.mp4

Eris/Desire

480x320

same as G1

Nexus One
(if input video size > 800x480)

480x320

same as G1

Nexus One
(if input video size > 800x480)

480x320

same as G1

Nexus One
(if input video size > 800x480)

480x320

same as G1

Old Apple Format Conversions

device

screen resolution

command

iPhone

320x480

ffmpeg -i ally.avi -acodec aac -strict experimental -ac 2 -ab 160k -s 480x320 -vcodec libx264 -vpre slow -vpre ipod640 -b 1200k -f mp4 a1.mp4

ipod touch

same as iphone

same as iphone

ipod nano

same as iphone

same as iphone

ipod classic

same as iphone

same as iphone

iPad/iPhone G4

for 3.5

ffmpeg -i all.flv -acodec aac -ab 160000 -strict experimental -vcodec mpeg4 -b 1200kb -mbd 2 -cmp 2 -subcmp 2 -s 640x480 -r 20 olda2.mp4

iPad

1024x768

ffmpeg -i need a command to output to h.264 OUTPUT

Apple Universal

1280x720

ffmpeg -i all.flv -acodec aac -ab 160000 -strict experimental -vcodec mpeg4 -b 1200kb -mbd 2 -cmp 2 -subcmp 2 -s 1280x720 -r 20 olda3.mp4

내가 테스트한 내용

[Ohys-Raws] 1280x720
ffmpeg -i input.mkv -c:a copy -s 1280x720 -vcodec libx264 -b:v 1200k a4.mp4
원주시 드론 화재 감지 1280x720 (평균 740k)
ffmpeg -i input.mp4 -profile:v high -b:v 750k -c:v h264 output.mp4

FFplay

Mac OSX Homebrew install:

$ brew install ffmpeg --with-sdl2

자세한건 해당 항목 참조.

Troubleshooting

FFmpeg#Troubleshooting 항목으로 일괄 정리한다.

See also

Favorite site

Online Tools

  • FFmpeg Explorer! - ffmpeg 필터를 온라인 테스트 해보기
    • FFMpeg의 다양한 필터를 브라우저에서 실시간으로 테스트 해볼 수 있음
    • GUI로 필터 그래프를 표시. 필터간 연결을 변경하거나 각 항목의 상세 옵션들을 우측에 리스트해서 보여주고 변경 가능
    • 3초짜리 짧은 영상을 가지고 실시간으로 렌더링해서 결과를 보면서 비교
    • 테스트해본 필터의 실제 입력 커맨드를 보여줘서 카피해서 사용
    • ffmpeg.wasm 으로 구현된 오픈소스
    • 오류 로그를 보고, 오류를 지우는 옵션을 제공
    • FFmpeg에 익숙하지 않은 사람들이나 다양한 필터와 옵션을 실험해보고 싶은 사람들에게 특히 유용

Tip & Guide

References


  1. High_quality_GIF_with_FFmpeg.pdf 

  2. Using_ffmpeg_to_convert_a_set_of_images_into_a_video.pdf 

  3. Ffmpeg_commandline_howto.pdf