FFmpeg - 3. deo
FFmpeg - kraćenje i spajanje
Uzmimo za dalje razmatranje 2 testna fajla:
Evo koje parametre nam daje mediainfo za prvi:
1mediainfo --Inform="Video;rezolucija = %Width%x%Height% Px, dijagonala = %DisplayAspectRatio/String%, bitrejt = %BitRate/String%, frejmrejt = %FrameRate% fps, dužina = %Duration/String1%, %InternetMediaType%" https://content.videvo.net/videvo_files/video/free/2015-01/originalContent/AMS__Big_Explosion.mov
rezolucija = 1920x1080 Px, dijagonala = 16:9, bitrejt = 14.4 Mb/s, frejmrejt = 29.970 fps, dužina = 14 s 982 ms, video/H264
Parametri za drugi:
1mediainfo --Inform="Video;rezolucija = %Width%x%Height% Px, dijagonala = %DisplayAspectRatio/String%, bitrejt = %BitRate/String%, frejmrejt = %FrameRate% fps, dužina = %Duration/String1%, %InternetMediaType%" https://www.countryvetclinic.com/wp-content/uploads/2019/05/Pexels-Videos-1321208.mp4
rezolucija = 3840x2160 Px, dijagonala = 16:9, bitrejt = 22.0 Mb/s, frejmrejt = 29.970 fps, dužina = 23 s 123 ms, video/H264
SKRAĆIVANJE SA ZADATIM POČETNIM VREMENOM I DUŽINOM TRAJANJA SEGMENTA:
- primer 1 (skraćujemo na segment od druge sekunde sa trajanjem od 6 sekundi):
1ffmpeg -i "https://content.videvo.net/videvo_files/video/free/2015-01/originalContent/AMS__Big_Explosion.mov" -ss 00:00:02 -t 00:00:06 -c copy -avoid_negative_ts make_zero "eksplozija_6s.mov"
SKRAĆIVANJE SA ZADATIM POČETNIM I ZAVRŠNIM VREMENOM SEGMENTA:
- primer 2 (skraćujemo na segment od osme sekunde do trinaeste sekunde):
1ffmpeg -i "https://content.videvo.net/videvo_files/video/free/2015-01/originalContent/AMS__Big_Explosion.mov" -ss 00:00:08 -to 00:00:13 -c copy -avoid_negative_ts make_zero "eksplozija_5s.mov"
SPAJANJE VIDEO FAJLOVA:
Najpre da usaglasimo značenje termina:
- Strimovanje ili striming (Streaming) u osnovnom značenju predstavlja isporučivanje multimedijalnih sadržaja (video i audio materijal) od strane servera isporučioca do klijenta - krajnjeg korisnika i to u realnom vremenu. Više o tome ovde.
- Kodeci (Codecs), su tehnologije kompresije sastavljene od dve komponente: enkodera zaduženog za komprimovanje fajlova i dekodera koji služi za dekompresiju.Tako postoje kodeci za podatke (ZIP,RAR), za statične slike (JPEG,TIFF,PNG), audio fajlove (MP3,AAC), video fajlove (Cinepak,MPEG-2,H.264,VP9). Više o tome ovde.
- Jedan od još uvek najraširenijih video kodeka H.264 je ugrađen u brojne "kontejner" formate od kojih je najpoznatiji MPEG-4 (.mp4), ali i u QuickTime (.MOV), Flash (.F4V), 3GP koji se koristi za mobilne telefone (.3GP), kao i MPEG transport stream (.ts)
- H.264 kodek se u izveštaju programa za analizu parametara može pojaviti i pod nazivom AVC kako je registrovan od strane druge institucije. Više o H.264 ovde.
SPAJANJE VIDEO FAJLOVA SA ISTIM KODEKOM:
Za spajanje dva video fajla sa istim kodekom (oba test fajla su H.264),postoje dve metode:
-
the concat ''demuxer''
-
the concat ''protocol''
Concat demuxer:
Ova metoda zahteva iste kodeke, ali dozvoljava različite formate "kontejnera", dok je primena "protocol" metode ograničena na svega nekoliko.
Procedura je sledeća:
-
Formiramo fajl mylist.txt sa svim fajlovima koje želimo da spojimo (prva linija se igniriše) i to u formi:
1# this is a comment 2file '/path/to/file1.wav' 3file '/path/to/file2.wav' 4file '/path/to/file3.wav'
Putanje mogu biti relativne ili apsolutne (ipak sam pobornik apsolutnih).
-
Novonastali strim možemo da re-enkodiramo ili ostavimo postojeće parametre kodeka:
1ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.wav
-
U našoj probi skraćivanja dobili smo 2 fajla istog kodeka koje ćemo spojiti:
- eksplozija_6s.mov (/mnt/8300-podaci/multimedija/eksplozija_6s.mov)
- eksplozija_5s.mov (/mnt/8300-podaci/multimedija/eksplozija_5s.mov)
1mv eksplozija_6s.mov 1.eksplozija_6s.mov # preimenujemo zbog redosleda
2mv eksplozija_5s.mov 2.eksplozija_5s.mov # preimenujemo zbog redosleda
3# spajamo prvi deo od 02. do 08. s i drugi deo od 08. do 13. s
4printf "file '%s'\n" ./*.mov > mylist.txt
-
Izvršimo spajanje bez re-enkodiranja:
1ffmpeg -f concat -safe 0 -i mylist.txt -c copy eksplozija_11s.mov
-
Izvršimo spajanje direktno, bez formiranja mylist.txt fajla:
1ffmpeg -f concat -safe 0 -i <(for f in ./*.mov; do echo "file '$PWD/$f'"; done) -c copy eksplozija_11s.mov
-
Napravimo fajl koji je 10 puta ponovljeni naš eksplozija_11s.mov
1for i in {1..10}; do printf "file '%s'\n" eksplozija_11s.mov >> mylist.txt; done 2ffmpeg -f concat -i mylist.txt -c copy 10xeksplozija_11s.mov
Concat protocol:
Dok demuxer radi na nivou strima, concat protocol radi na nivou fajla.Tako neki fajlovi, pvenstveno MPEG-2 transport streams mogu da budu spajani.
Evo primera spajanja tri MPEG-2 TS fajla bez re-enkodiranja:
1ffmpeg -i "concat:input1.ts|input2.ts|input3.ts" -c copy output.ts
-
SPAJANJE POMOĆU POSREDNIČKIH FAJLOVA:
Spajanje MP4 fajlova bez gubitaka (losslessly), možemo da izvedemo transkodirajući ih u MPEG-2 transport stream. Za slučaj video komponenti enkodiranih u H.264 i audio u AAC imali bi:
1ffmpeg -i input1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate1.ts 2ffmpeg -i input2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate2.ts 3ffmpeg -i "concat:intermediate1.ts|intermediate2.ts" -c copy -bsf:a aac_adtstoasc output.mp4
Svi MPEG kodeci (MPEG-4 Part 10 / AVC, MPEG-4 Part 2, MPEG-2 Video, MPEG-1 Audio Layer II, MPEG-2 Audio Layer III (MP3), MPEG-4 Part III (AAC)), su podržani od strane MPEG-2 TS "kontejnera", mada komande traže izvesne izmene kao što su bitstrim filteri (-bsf).
SPAJANJE VIDEO FAJLOVA SA RAZLIČITIM KODEKOM:
Često je slučaj da trba spojiti fajlove sa različitim kodecima čime su nam onemogućene prethodno navedene metode.
Concat:
Spajanje audio i video strimova se vrši po reosledu jedan za drugim.
Filter u stvari obrađuje segmente sinhronizovanih audio i video strimova.
Svi segmenti treba da imaju identičan broj strimova svakog tipa, što predstavlja ujedno i broj strimova na izlazu.
Potrebno je da spajani fajlovi imaju istu rezoluciju (npr. 1920x1080 Px) kao i frejmrejt. Moguće je pre spajanja ,fajlove kojima je potrebno, dodati scale filter ili scale2ref . Još nekoliko parametara treba da se podudaraju kao npr. dijagonala (aspect ratio).
Procedura je sledeća:
Recimo da imamo tri fajla da spojimo, a svaki sa po jednim video i audio strimom.
Concat filter bi izgledao ovako:
1ffmpeg -i input1.mp4 -i input2.webm -i input3.mov \
2-filter_complex "[0:v:0][0:a:0][1:v:0][1:a:0][2:v:0][2:a:0]concat=n=3:v=1:a=1[outv][outa]" \
3-map "[outv]" -map "[outa]" output.mkv
Hajde da analiziramo komandu:
-
Prvo unesemo ulazne fajlove:
- -i input1.mp4
- -i input2.webm
- -i input3.mov
-
Zatim -filter_complex pošto postoji više ulaza i više izlaza.
-
Zatim sledi:
1[0:v:0][0:a:0][1:v:0][1:a:0][2:v:0][2:a:0]
ovde svaki prvi karakter svake srednje zagrade predstavlja ulazni fajl (0 --> imput1.mp4 ; 1 --> imput2.webm ; 2 --> imput3.mov)
drugi karakter svake srednje zagrade predstavlja strim (video ili audio) odgovarajućeg segmenta (fajla). (video strim 0[0:v:0]
i audio strim 0[0:a:0]
su od input1.mp4 itd.). -
1concat=n=3:v=1:a=1[outv][outa]
Ovo sam concat filter.
- n=3 informiše filter da postoje 3 fajla
- v=1 obaveštava da postoji jedan video strim po segmentu
- a=1 daje do znanja da segmenti imaju po 1 audio strim
- Filter zatim spaje segmente i stvara dva izlazna strima:
[outv]
i[outa]
-
Sada ide deo sa mapiranjem izlaznih strimova i unošenje naziva izlaznog fajla:
1-map "[outv]" -map "[outa]" output.mkv
ovo daje instrukciju FFmpeg-u da da prioritet concat filteru u odnocu na strimove koji potiču direktno od imput fajlova.
proba:
Daunlodujmo sledeće fajlove:
i ranije pomenuti:
Prvi nam daje parametre:
1mediainfo --Inform="Video;rezolucija = %Width%x%Height% Px, dijagonala = %DisplayAspectRatio/String%, bitrejt = %BitRate/String%, frejmrejt = %FrameRate% fps, dužina = %Duration/String1%, %InternetMediaType%" https://content.videvo.net/videvo_files/video/free/2015-01/originalContent/GREEN_SCREEN_ANIMALS__ALPACA.mov
1rezolucija = 1920x1080 Px, dijagonala = 16:9, bitrejt = 16.4 Mb/s, frejmrejt = 23.976 fps, dužina = 34 s 76 ms, video/H264
a za drugi već imamo:
1rezolucija = 1920x1080 Px, dijagonala = 16:9, bitrejt = 14.4 Mb/s, frejmrejt = 29.970 fps, dužina = 14 s 982 ms, video/H264
-
Transkodirajmo prvi fajl iz H264 MOV u H265 MP4 skaliran na 720p i sa bitrejtom od 16 Mb/s
1ffmpeg -i GREEN_SCREEN_ANIMALS__ALPACA.mov -vf scale=1280:720,setsar=1:1 -b:v 16M -c:v libx265 -crf 1 output.mp4
preimenujmo ga u alpaka_720p.mp4 i pogledajmo šta daje mediainfo:
1rezolucija = 1280x720 Px, dijagonala = 16:9, bitrejt = 5 420 kb/s, frejmrejt = 23.976 fps, dužina = 34 s 76 ms, video/H265
preimenujmo i drugi fajl u explosion_1080p.mp4
-
Po svim navedenim parametrima osim dijagonale (aspect ratio), alpaka_720p.mp4 i explosion_1080p.mov su različiti. Kako da ih spojimo? Evo kako:
-
1ffmpeg -i explosion_1080p.mov -i alpaka_720p.mp4 -filter_complex "[0:v]scale=1280:720:force_original_aspect_ratio=1[v0];[v0][0:a][1:v][1:a]concat=n=2:v=1:a=1[v][a]" -map [v] -map [a] output.mp4
-
Video strim prvog segmenta mora da se skalira na rezoluciju 720p ako nju želimo.Pri tome video strim drugog segmenta preskače skaliranje jer je već u 720p.
-
Da smo želeli izlazni fajl u 1024:576 , moralo bi ovako:
1ffmpeg -i explosion_1080p.mov -i alpaka_720p.mp4 -filter_complex "[0:v]scale=1024:576:force_original_aspect_ratio=1[v0];[1:v]scale=1024:576:force_original_aspect_ratio=1[v1];[v0][0:a][v1][1:a]concat=n=2:v=1:a=1[v][a]" -map [v] -map [a] output1.mp4
-
Da bi izlazni fajl imao dužinu 1152 Px, ne treba da računamo drugu stranu da bi slika zadržala proporcije 16:9
1ffmpeg -i explosion_1080p.mov -i alpaka_720p.mp4 -filter_complex "[0:v]scale=1152:-2:force_original_aspect_ratio=1[v0];[1:v]scale=1152:-2:force_original_aspect_ratio=1[v1];[v0][0:a][v1][1:a]concat=n=2:v=1:a=1[v][a]" -map [v] -map [a] output1.mp4
faktor -2 važi i za dužinu ako je zahtevana mera visina slike na primer 684 Px:
1ffmpeg -i explosion_1080p.mov -i alpaka_720p.mp4 -filter_complex "[0:v]scale=-2:684:force_original_aspect_ratio=1[v0];[1:v]scale=-2:684:force_original_aspect_ratio=1[v1];[v0][0:a][v1][1:a]concat=n=2:v=1:a=1[v][a]" -map [v] -map [a] output2.mp4
-