FFmpeg - 3. deo

Share on:

FFmpeg - kraćenje i spajanje



Uzmimo za dalje razmatranje 2 testna fajla:

  1. https://content.videvo.net/videvo_files/video/free/2015-01/originalContent/AMS__Big_Explosion.mov

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

  1. https://www.countryvetclinic.com/wp-content/uploads/2019/05/Pexels-Videos-1321208.mp4

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:

  1. the concat ''demuxer''

  2. 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:

    1. eksplozija_6s.mov (/mnt/8300-podaci/multimedija/eksplozija_6s.mov)
    2. 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:

    1. -i input1.mp4
    2. -i input2.webm
    3. -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.

    1. n=3 informiše filter da postoje 3 fajla
    2. v=1 obaveštava da postoji jedan video strim po segmentu
    3. a=1 daje do znanja da segmenti imaju po 1 audio strim
    4. Filter zatim spaje segmente i stvara dva izlazna strima: [outv] i [outa]

concat filter

  • 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:

  1. https://content.videvo.net/videvo_files/video/free/2015-01/originalContent/GREEN_SCREEN_ANIMALS__ALPACA.mov

i ranije pomenuti:

  1. https://content.videvo.net/videvo_files/video/free/2015-01/originalContent/AMS__Big_Explosion.mov

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
    
    1. 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.

    2. 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
      
    3. 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