Não perca tempo e nem dinheiro com ferramentas caras de edição, edite seus vídeos na linha de comando!
$ git clone https://github.com/anthwlock/untrunc.git && cd untrunc
$ docker build --build-arg FF_VER=3.3.9 -t untrunc .
$ docker run -v $PWD:/mnt untrunc /mnt/video-de-exemplo-que-funciona.mov /mnt/video-quebrado.mov
$ ffmpeg -v warning -hide_banner -stats -i "in.mp4" \
-filter_complex \
"[0:v]crop=280:40:630:785,boxblur=10:enable='between(t,247,258)'[fg]; \
[0:v][fg]overlay=630:785[v]" \
-map "[v]" -map 0:a \
-preset ultrafast -vcodec libx264 -acodec aac -strict -2 out.mp4
Isso vai borrar a posição x=630
, x=785
com uma largura=280
e altura=40
do segundo 247 até o 258
Isso é útil para poder validar se o resultado ficou bom, depois você pode mudar para slow para gerar um arquivo menor
ffmpeg -i input.mp4 -hide_banner -c:v libx264 -preset ultrafast out.mp4
mediainfo --fullscan myvideo.mp4 | less
ffmpeg -loop 1 -i image.jpg -i audio.wav -c:v libx264 -tune stillimage -c:a aac -b:a 192k -pix_fmt yuv420p -shortest out.mp4
sem minuatura (alta qualidade), quem determina a qualidade do video eh o crf entre 0 e 51 quanto maior pior a qualidade
avconv -i input.avi -c:v libx264 -preset slow -crf 18 -c:a copy -pix_fmt yuv420p output.mkv
com miniatura (alta qualidade)
avconv -i thumb.png -i input.mp4 -c:v libx264 -preset slow -crf 18 -c:a copy -pix_fmt yuv420p output-with-thumb.mp4
testar colocar o encode do audio
libfdk_aac -b:a 128k
converter rotacionando
$ ffmpeg -i in.mov -vf "transpose=1" out.mov
For the transpose parameter you can pass:
0 = 90CounterCLockwise and Vertical Flip (default)
1 = 90Clockwise
2 = 90CounterClockwise
3 = 90Clockwise and Vertical Flip
for v in *.avi ; do $
avconv -i "$v" -strict -2 "cv/`basename \"$v\" .avi`.mp4"
done
180 Graus
avconv -i video.mp4 -vf transpose=1,transpose=1 out.mkv
90 Graus
avconv -i video.mp4 -vf transpose=1,transpose=1 out.mkv
Mais algumas opções:
Rotate 90 clockwise:
ffmpeg -i in.mov -vf "transpose=1" out.mov
For the transpose parameter you can pass:
0 = 90CounterCLockwise and Vertical Flip (default)
1 = 90Clockwise
2 = 90CounterClockwise
3 = 90Clockwise and Vertical Flip
ffmpeg -i "https://acme.com/playlist.m3u8" -bsf:a aac_adtstoasc -vcodec copy -c copy -crf 50 file3.mp4
ffmpeg -i my.m4a -acodec mp3 -ac 2 -ab 192k my.mp3
Va nas propriedades do video e veja o formato do video, ex: Vorbis, então rode o comando abaixo com a extensao do audio no formato original que está dentro do seu video, assim ele vai extrair muito rapido, ex: vorbis é .ogg
ffmpeg -i desenvolver-com-testes-unitarios-04.mp4 -vn -acodec copy audio-3.ogg
Se desejar converter o audio extraido ao inves de soh extrair
avconv -i desenvolver-com-testes-unitarios-04.mp4 -vn -acodec mp3 audio-3.mp3
FILES_TO_CONVERT=(*.*) &&\
OUT_DIR=mp3 && mkdir -p ${OUT_DIR} &&\
for IN in "${FILES_TO_CONVERT[@]}"; do
ffmpeg -i "$IN" -vn -acodec mp3 "$OUT_DIR/${IN%.*}.mp3";
done
ffmpeg -i in.mp4 -i new-audio.mp3 -map 0:0 -c:v copy -map 1 -c:a copy out.mp4
$ ffprobe -select_streams v -show_streams VID_20170917_135221811.mp4 2>/dev/null | grep "nb_frames"
nb_frames=18079
esse comando tem varias informacoes de video
$ ffprobe -select_streams v -show_streams VID_20170917_135221811.mp4 2>/dev/null
[STREAM]
index=0
codec_name=h264
codec_long_name=H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
profile=High
codec_type=video
codec_time_base=5422753/325422000
codec_tag_string=avc1
codec_tag=0x31637661
width=1920
height=1080
coded_width=1920
coded_height=1080
has_b_frames=0
sample_aspect_ratio=1:1
display_aspect_ratio=16:9
pix_fmt=yuvj420p
level=40
color_range=pc
color_space=smpte170m
color_transfer=smpte170m
color_primaries=smpte170m
chroma_location=left
field_order=unknown
timecode=N/A
refs=1
is_avc=true
nal_length_size=4
id=N/A
r_frame_rate=30/1
avg_frame_rate=162711000/5422753
time_base=1/90000
start_pts=0
start_time=0.000000
duration_ts=54227530
duration=602.528111
bit_rate=16999112
max_bit_rate=N/A
bits_per_raw_sample=8
nb_frames=18079
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=1
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
TAG:creation_time=2017-09-17T17:02:26.000000Z
TAG:language=eng
TAG:handler_name=VideoHandle
[/STREAM]
ffmpeg -i input.mp4 -c copy -map 0 -segment_time 00:20:00 -f segment -reset_timestamps 1 output%03d.mp4
$ bash <(curl -s -L http://bit.ly/39TxtVc)
ffmpeg -ss 00:00:05 -t 00:00:10 -i input -c:v copy -c:a copy -copyinkf output
ffprobe -select_streams v -show_frames -print_format csv -show_entries frame=key_frame,pkt_dts_time input.mp4 | grep "frame,1"
ffmpeg -v quiet -y -i in.mp4 -b:v 4.5m -vcodec libx264 -acodec copy -ss 00:10:44 -sn out.mp4
time ffmpeg -v quiet -y -i IMG_5765.mp4 -vcodec copy -acodec copy -ss 00:00:00 -t 00:00:30 -sn IMG_5765-part1.mp4
ffmpeg -ss 00:00:00 -t 00:13:31 -i in.mp4 -vcodec copy -acodec copy out.mp4
avconv -v quiet -y -i IMG_5765.mp4 -vcodec libx264 -acodec copy -ss 00:00:00 -t 00:00:30 -sn IMG_5765-part1.mp4
ffmpeg -i IMG_5765.mp4 -crf 29.97 -vcodec libx264 -acodec copy -ss 00:00:00 -t 00:00:30 -sn IMG_5765-part1.mp4
$ cat list.txt
file output-7.mp4
file output-6.mp4
$ ffmpeg -safe 0 -f concat -i list.txt -c copy output.mp4
VIDEOS=('001.mp4' '002.mp4') &&\
ffmpeg -f concat -safe 0 -i <( for x in ${VIDEOS[@]} ; do echo "file '$PWD/$x'"; done ) -c copy out.mp4
Essa forma requer re-encoding
ffmpeg -i part1.mp4 -i part2.mp4 -i part3.mp4 \
-filter_complex "\
[0:v] [0:a] \
[1:v] [1:a] \
[2:v] [2:a] \
concat=n=3:v=1:a=1 [v] [a] \
" -map "[v]" -map "[a]" -hide_banner -preset ultrafast -c:v libx264 output.mp4
Você precisa criar um canal de audio dummy
ffmpeg -i part01.mp4 -i part02.mp4 -f lavfi -t 0.1 -i anullsrc \
-filter_complex "\
[0:v] [0:a] \
[1:v] [2:a] \
concat=n=2:v=1:a=1 [v] [a] \
" -map "[v]" -map "[a]" -hide_banner -preset ultrafast -c:v libx264 output.mp4
Se tiver o erro
Too many packets buffered for output stream 0:0.
Então adicione a opção
-max_muxing_queue_size 9999
Será criado um canal de áudio dummy para preencher o primeiro e o último vídeo, o vídeo do meio ficará com o áudio original
ffmpeg -i part1-no-audio.mp4 -i part2.mp4 -i part3-no-audio.mp4 -f lavfi -t 0.1 -i anullsrc \
-filter_complex "\
[0:v] [3:a] \
[1:v] [1:a] \
[2:v] [3:a] \
concat=n=3:v=1:a=1 [v] [a] \
" -map "[v]" -map "[a]" -hide_banner -preset ultrafast -c:v libx264 edited/output.mp4
Como o vídeo tem 3 -i
logo ele tem 3 streams (0, 1, 2), temos que fazer um map que mantém os vídeos inalterados e usa o audio dummy do 4º canal para preencher os vídeos 1 e 3 que não tem som
[0:v] [3:a] vídeo 1: use o vídeo dele mesmo e o audio dummy
[1:v] [1:a] vídeo 2: use o vídeo e o audio dele mesmo
[2:v] [3:a] vídeo 3: use o vídeo dele mesmo e o audio dummy
As cameras costumam gravar com bitrate bem acima do que necessário (17 mbps) para subir no youtube voce soh precisa de algo em torno de 4300 k
ffmpeg -i my-video.mp4 -c:v libx264 -b:v 4300k out.mp4
O mais recomendado para diminuir o tamanho do video é usar o framerate porque assim o ffmpeg sozinho calcula o melhor bitrate (joga fora o excesso)
ffmpeg -v quiet -y -i in.mp4 -crf 30 -vcodec libx264 -acodec copy out.mp4
ffmpeg -i input.mp4 -filter:v "subtitles=input.srt:force_style='Fontsize=6,PrimaryColour=&H0000ff&'" -c:a copy output.mp4
Exemplo para video de 1080p (limitando o framerate)
ffmpeg -i 2019_02_08_08_09_37.mp4 -filter:v "subtitles=2019_02_08_08_09_37.srt:force_style='Fontsize=6,Alignment=3'" -b:v 12M -c:a copy output-7.mp4
O formato é sempre em segundos, você pode fazer coisas como 1*60
para converter para minutos
ffmpeg -i part02.mp4 -vf drawtext="text='Stack Overflow': fontcolor=white: fontsize=24: box=1: boxcolor=black@0.5: \
boxborderw=5: x=(w-text_w)/2: y=(h-text_h)/2: enable='between(t,15,20)" -codec:a copy output.mp4
@0.5
= opacidade, pode remover ou ajustar
between
= em que range de tempo será colocado o texto,em segundos, algo como 5*60
também é aceito
x
= posição x, usando (w-text_w)/2
fica centralizado, se não passar o x
e y
, vai ficar alinhando ao topo e esquerda
y
= posição y
ffmpeg -i part02.mp4 -vf drawtext="text='Stack Overflow': fontcolor=white: fontsize=24: box=1: boxcolor=black@0.5: \
boxborderw=5: x=(w-text_w): enable='between(t,0,20)" -codec:a copy output.mp4
OUT=output.mp4 && ffmpeg -i part02.mp4 -vf drawtext="text='Stack Overflow
Other Text' \
:x=(w-text_w) - 5 :y=5 :enable='between(t,0,20) \
:fontcolor=white: fontsize=30 \
:borderw=2 :bordercolor=black \
" -codec:a copy ${OUT}
OUT=output.mp4 && ffmpeg -i part02.mp4 -vf drawtext="text='Stack Overflow
Other Text :fontfile=/usr/share/fonts/opentype/linux-libertine/LinLibertine_M.otf' \
:x=(w-text_w) - 5 :y=5 :enable='between(t,0,20) \
:fontcolor=white: fontsize=24 \
:borderw=2 :bordercolor=black \
" -codec:a copy ${OUT}
Isso garante que o texto ficará tabulado
OUT=output.mp4 && ffmpeg -i joined.mp4 -i narracao.wav -vf drawtext="text='São Paulo.............\: Gasolina = 4.500, Álcool = 2.890
Ipiranga Frango Assado\: Gasolina = 4.799, Álcool = 3.399
Graal Perdões.........\: Gasolina = 4.617, Álcool = 3.297
Posto Petrobrás BR-135\: Gasolina = 4.850, Álcool = 3.180
Posto Opção II - MOC..\: Gasolina = 4.850, Álcool = 3.250' \
:x=(w-text_w) - 5 :y=5 :enable='between(t,45,60) \
:fontcolor=white :fontsize=30 :fontfile=/usr/share/fonts/truetype/ubuntu/UbuntuMono-R.ttf \
:box=1 :boxcolor=black@0.5 :boxborderw=5
" -c:a aac -map 0:v:0 -map 1:a:0 -c:v libx264 -preset ultrafast ${OUT}
FONT_FILE=/usr/share/fonts/truetype/ubuntu/UbuntuMono-R.ttf \
FONT_SIZE=30 \
LINE_HEIGHT=5 \
DEFAULT_FORMAT="drawtext=fontsize=${FONT_SIZE} :fontfile=${FONT_FILE} :x=0 :y=0" &&\
ffmpeg -i part01.mp4 -vf "[in]\
${DEFAULT_FORMAT} :fontcolor=White :text='onLine1' :x=(w)/2 :y=(h) / 2\
, ${DEFAULT_FORMAT} :fontcolor=Red :text='onLine2' :x=(w)/2 :y=(h) / 2 + (${LINE_HEIGHT} + ${FONT_SIZE}) * 1 \
, ${DEFAULT_FORMAT} :fontcolor=Blue :text='onLine3' :x=(w)/2 :y=(h) / 2 + (${LINE_HEIGHT} + ${FONT_SIZE}) * 2 \
[out]" -hide_banner -c:v libx264 -c:a copy -preset ultrafast output.mp4
FONT_FILE=/usr/share/fonts/truetype/ubuntu/UbuntuMono-R.ttf \
FONT_SIZE=30 \
LINE_HEIGHT=5 \
DEFAULT_FORMAT="drawtext=fontsize=${FONT_SIZE} :fontfile='${FONT_FILE}' :x=5 :y=5 :fontcolor=White " &&\
ffmpeg -i part01.mp4 -vf "[in]\
${DEFAULT_FORMAT} :enable='between(t,1,10)' :text='First text' \
, ${DEFAULT_FORMAT} :enable='between(t,15,20)' :text='Second text' \
, ${DEFAULT_FORMAT} :enable='between(t,21,30)' :text='Third text' \
[out]" -hide_banner -c:v libx264 -c:a copy -preset ultrafast output.mp4
Gere o comando com essa ferramenta
No segundo 5 ele tem fade in de 2 segundos e no segundo 10 ele tem fade out de 2
FONT_FILE=/usr/share/fonts/truetype/ubuntu/UbuntuMono-R.ttf \
FONT_SIZE=30 \
LINE_HEIGHT=5 \
DEFAULT_FORMAT="drawtext=fontsize=${FONT_SIZE} :fontfile=${FONT_FILE} :x=0 :y=0" &&\
ffmpeg -i part01.mp4 -vf "[in]\
${DEFAULT_FORMAT} :fontsize=50 :fontcolor=White :text='E assim vamos terminando mais uma viagem ...' :x=(w)/2 :y=(h) / 2 \
:alpha='if(lt(t,5),0,if(lt(t,12),(t-5)/2,if(lt(t,12),1,if(lt(t,19),(2-(t-12))/2,0))))' \
[out]" -hide_banner -c:v libx264 -c:a copy -preset ultrafast output.mp4
for i in *.mp4; do
echo "> converting $i"
ffmpeg -v quiet -y -i "$i" -crf 30 -vcodec libx264 -acodec copy "${i%.mp4}-30-fps.mp4"
done
ffmpeg -i in.mp4 -vf deshake out.mp4
IN=/data/sjcam/2019-06-04/2016_0101_073012_003.MOV &&\
OUT="${IN%.*}-stabilized.mp4" &&\
export PATH="/opt/ffmpeg-4.1.3-amd64-static:$PATH" &&\
ffmpeg -i "$IN" -vf vidstabdetect=shakiness=10 -f null - &&\
ffmpeg -i "$IN" -crf 30 -vcodec libx264 -acodec ac3 -vf vidstabtransform=smoothing=30:input="transforms.trf",unsharp=5:5:0.8:3:3:0.4 $OUT
ffmpeg \
-i input0 \
-i input1 \
-filter_complex "\
[0:v][1:v]hstack=inputs=2[v];\
[0:a]amerge=inputs=1[a]\
" \
-map "[v]" \
-map "[a]" \
output.mp4
ffmpeg \
-i 2016_0101_000111_003.MOV \
-i 2016_0101_065406_003.MOV \
-i 2016_0101_001359_001.MOV \
-filter_complex "[0:v][1:v][2:v]hstack=3" \
output.mp4
ffmpeg \
-i 2016_0101_000111_003.MOV \
-i 2016_0101_065406_003.MOV \
-i 2016_0101_001359_001.MOV \
-filter_complex \
"[0:v][1:v]hstack[top]; \
[2:v]hstack[bottom]; \
[top][bottom]vstack,format=yuv420p[v]; \
[0:a]amerge=inputs=1[a]" \
-map "[v]" \
-map "[a]" \
-ac 2 \
output.mp4
ffmpeg \
-i 2016_0101_000111_003.MOV \
-i 2016_0101_065406_003.MOV \
-i 2016_0101_001359_001.MOV \
-i 2016_0101_001359_001.MOV \
-filter_complex \
"[0:v][1:v]hstack[top]; \
[2:v][3:v]hstack[bottom]; \
[top][bottom]vstack,format=yuv420p[v]; \
[0:a]amerge=inputs=1[a]" \
-map "[v]" \
-map "[a]" \
-ac 2 \
-c:v libx264 \
-c:a ac3 \
output.mp4
Os 4 com som
ffmpeg \
-i 2016_0101_000111_003.MOV \
-i 2016_0101_065406_003.MOV \
-i 2016_0101_001359_001.MOV \
-i 2016_0101_001359_001.MOV \
-filter_complex \
"[0:v][1:v]hstack[top]; \
[2:v][3:v]hstack[bottom]; \
[top][bottom]vstack,format=yuv420p[v]; \
[0:a][1:a][2:a][3:a]amerge=inputs=4[a]" \
-map "[v]" -map "[a]" -ac 2 output.mp4
Começa o video preto e faz fade in de 2 segundos a partir do segundo 0
ffmpeg -i part01.mp4 -vf "fade=in:st=0:d=2" -hide_banner -c:v libx264 -c:a copy -preset ultrafast output.mp4
ffmpeg -i example.mkv -c copy -an example-nosound.mkv
ffmpeg -i input.mp4 -i input.mp3 -c copy -c:a aac -map 0:v:0 -map 1:a:0 output.mp4
AUDIOS=('one.mp3' 'two.mp3') &&\
IN_VIDEO=in.mp4 &&\
VIDEO_DURATION=$(ffmpeg -i ${IN_VIDEO} 2>&1 | grep -oP "Duration: \K(\d+:\d+:\d+)") &&\
ffmpeg \
-f concat -safe 0 -i <( for x in ${AUDIOS[@]} ; do echo "file '$PWD/$x'"; done ) \
-i "${IN_VIDEO}" \
-codec copy \
-t ${VIDEO_DURATION} \
out.mp4
ffmpeg -i input.mp4 -i input.wav \
-filter_complex amix=inputs=2:duration=longest \
-c:v copy -c:a aac -preset ultrafast output.mp4
ffmpeg -i input.mp4 -i narracao.wav -c:a aac -map 0:v:0 -map 1:a:0 -c:v libx264 -preset ultrafast output.mp4
Mutando duas partes do vídeo
ffmpeg -i input.mp4 -af "\
volume=enable='between(t,5,10)':volume=0 \
, volume=enable='between(t,33,36)':volume=0 \
" -c:a aac -c:v copy output.mp4
ffmpeg -i video.avi -i audio1.mp3 -i audio2.mp3 -map 0 -map 1 -map 2 -codec copy output
Se for um audio
ffmpeg -i input.wav -filter:a "volume=0.5" output.wav
Se for um vídeo
ffmpeg -i joined.mp4 -filter:a "volume=0.15" -c:a aac -c:v copy reduced-volume.mp4
1 = normal
0.5 = 2x
0.1 = 10x
0.05 = 20x
ffmpeg -i in.mp4 -filter:v "setpts=0.05*PTS" -an out.mp4
ffmpeg \
-ss 30 \
-t 3 \
-i input.mp4 \
-vf "fps=10,scale=1080:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 \
output.gif
Transforme a imagem num vídeo
ffmpeg -loop 1 -i edited/final.jpg -t 00:00:20 -c:v libx264 -vf scale=1920:1080 -pix_fmt yuv420p edited/final.mp4
Junte os dois vídeos, para fazer isso veja o passo Forma 3.2 de como juntar vídeos
A cada 5 segundos vai troca de imagem
ffmpeg -r 1/5 -i a%03d.jpg -c:v libx264 -vf scale=1920x1080,setdar=16:9,fps=25 -pix_fmt yuv420p inicio-02.mp4
ffmpeg -i VID_20201102_122619504-ed1.mp4 -i grafico-bt-vs-lk.png -filter_complex "\
[0:v][1:v] overlay=10:10:enable='between(t,19 * 60 + 9, 19 * 60 + 9 + 10)'\
" -hide_banner -c:v libx264 -c:a aac -preset ultrafast VID_20201102_122619504-ed2.mp4
ffmpeg -i input.mp4 -i image1.jpg -i image2.jpg -i image4.jpg -filter_complex "\
[0:v][1:v] overlay=10:10:enable='between(t,60,65)' [v1]; \
[v1][2:v] overlay=10:10:enable='between(t,65,70)' [v2]; \
[v2][3:v] overlay=10:10:enable='between(t,70,75)'\
" -preset ultrafast out.mp4
ffmpeg commands, avconv commands, ffmpeg examples, ffmpeg exemplos, ffmpeg bookmarks