FFmpeg: jak validovat multimediální soubor?

FFmpeg: jak validovat multimediální soubor?
« kdy: 16. 11. 2024, 11:53:08 »
Nahram na web audio/video a zbehnem ho cez ffprobe. Ak nedostanem confidence aspon 51, tak upload je neplatny.

Toto je bezny problem pri mp3, kedy perfektne validny subor nedosiahne vyssie skore proste. Neviem preco ale proste je to tak. Takze preto pouzivam take nizke skore. Tiez kontrolujem ci je tam nejaky audio/video track a nejde iba o prazdny kontajner.

Nasledne audio/video konvertujem do nejakeho nakonfigurovaneho formatu a kvality.

Problem je, ze niekedy mi ffmpeg vrati error. Napriklad naposledy:
Citace
ffmpeg error: [mp3float @ 00000000026e6f00] Header missing
[aist#0:0/mp3 @ 00000000026ce140] Error submitting packet to decoder: Invalid data found when processing input

Otazka je, ako zachytit/validovat audio/video subory pred tym, nez sa ich pokusim konvertovat? Myslel som ze ffprobe mi zaruci, ze ked vie precitat metadata, tak subor nemoze byt problem nasledne konvertovat. No ocividne to tak nie je.

Je teda nejak mozne priamo ffmpegom validovat multimedialny subor?


Re:ffmpeg - ako validovat multimedialny subor?
« Odpověď #1 kdy: 16. 11. 2024, 13:48:20 »
Pokud to má fungovat obecně a pro různé typy souborů, tak se to realizuje poměrně blbě.
Párkrát jsem implementoval něco podobného, když jsem hostoval server pro výměnu a sdílení médií mezi různými týmy v rámci jednoho projektu, bohužel se to uploadovalo promocí standardního FTP a téměř odkudkoliv (mobilní sítě, satelitní internet). Byly tam nějaké automatické transkódovací cesty a potřeboval jsem zařídit, aby se odseparovaly nekompletní a případně poškozené uploady ještě než si to přebere transkodér, který byl ještě k tomu proprietární a při zpracování určitých poškozených souborů měl memory leak :(, takže to bylo vcelku důležité.

U některých konkrétních formátů a kontejnerů se snadno zjistí, že nejsou celé, protože s tím od začátku počítají. Parser v podstatě tím, že chybí v souboru určitá struktura, příznak, nebo je tam reference na adresu za koncem souboru, tak snadno zjistí, že je nekompletní. Případně tam je třeba na začátku hlavička, v které je délka. Některé formáty mají i vestavěné checksumy. Takže se dá snadno zkontrolovat i jestli je soubor nejen nekompletní, ale i třeba poškozený při přenosu.
Pak jsou formáty, které tohle v podstatě neřeší a musí se buď kompletně projet a zkontrolovat jeho struktura, případně v nejhorším (časově nejnáročnějším) případě jej zdekódovat, což je ale ve většině případů pořád řádově rychlejší než komplet transkóding do jiného formátu a v případě výskytu chyby jej vyřadit. Tohle se týká primárně některých starších formátů, případně těch co jsou od v podstatě koncipované k nějakému streamování, kde se s výpadky pricipiálně počítá (např. MPEG-2 TS).
Co to navíc ještě pak komplikuje je to, že tam můžou být značné rozdíly i v rámci jednoho formátu, např. jinak se chová MP4/MOV soubor s fast-start hintem (MOOV atom na začátku a dá se "odhadnout" cílová velikost) a bez něj. Některá enkodéry a zařízení ho dají úplně na konec. Je pak nutné ošetřit více stavů.. atp.

Takže v pár bodech mé zkušenosti..
- ffprobe skóre nestačí (to je opravdu jen základní, hrubá identifikace formátu/kontejneru)
- mediainfo (resp. libmediainfo) má podle konkrétního formátu nyní (oproti době, kdy jsem výše zmíněné věci psal) řádově víc možností detekce strukt. chyb (compliance errors) a je schopné řadu variant nekompletních souborů detekovat. Tam bych začal a naintegroval buď pomocí JSON výstupů z cli toolu nebo volal tu knihovnu.
- pro spolehlivou detekci širokého spektra formátů může být pořád nutné aplikovat nějakou heuristiku. Např. já měl po úvodní identifikaci souborů víc nástrojů, až po zmíněné dekódování. Pro některé situace můžete zavolat i ffprobe -show_frames a kontrolovat chyby. Někde (mkv) by mohl stačit remux. Je potřeba mít vzorky poškozených, nekompletních souborů a ozkoušet to.
- jestli vám jde vyloženě o analýzu mpeg-audio rámců v MP3, tak bych do pipeline zařadil mpck
https://github.com/Sjord/checkmate

Pokud to máte pod kontrolou, tak se zamyslete nad zúžením množství vstupních formátů, kde máte ověřenou detekci, nebo vylepšením uploadu. Např.
- upravit upload frontend tak, aby rovnou spočítal do malého souboru bokem nějaký checksum, co pak snadno zkontroluje a zároveň pokud se uploaduje jako poslední, tak může fungovat jako bumper soubor, co pak triggeruje nějaký watchfolder v pipeline za tím (samozřejmě pokud to funguje jen souborově a nemáte to řešené jinak, třeba vytvořením úlohy v nějaké frontě / message brokeru).
- v projektech, co jsem řešil, se spousta věcí vyřešilo použitím hotových (komerčních) nástrojů na posílání souborů (zásilek), který má nativní klienty (appky) na všechny možné platformy, řeší integritu souborů, navazování a nepustí nekompletní zásilky dál do pipeline. Pořád je tam šance, že někdo vygeneruje špatný soubor, ale toho je řádově menší výskyt než potíží s uploadem, zvlášť z míst s nespolehlivým připojením.

Re:FFmpeg: jak validovat multimediální soubor?
« Odpověď #2 kdy: 16. 11. 2024, 14:11:13 »
Ja po uploade suboru viem ze je kompletny pretoze sledujem velkost suboru, ktoru ocakavam. Hash si robim sam ale to je irelevantne.

ffprobe mi vrati info o subore, o tom je prave to skore, a ja si kontrolujem ci nainstalovana verzia ffmpegu podporuje kodedky v audio a video trackoch a tiez aj kontajner. Takze mi ide do systemu subor ktory viem ze ffmpeg spracuje.

Problem ale nastava az pri samotnom spracovnai neskor. A mne ide o to tomu predist prave na zaciatku pri validacii suboru, nez ho poslem dalej na spracovanie. A ci ma mp4 kontajner fast start alebo nie je irelevantne. Ide o to ze ffprobe subor naparsuje a ziska metadata, to je je same o sebe prva kontrola. A ffprobe mi hovori ze subor pouziva kontajner XYZ a ma kodek ABC a DEF pre audio a video tracky. Takze viem co v subore je.

Ale z nejakeh odovodu mi potom ffmpeg hodi chybu ze data nie su validne. A o to mi ide - tomuto zabranit. Idealne ale bez nutnosti preskenovat cely subor, lebo to moze byt aj 10 giga a proste uzivatel pri nahravani nema cas cakat na nieco take.

Napriklad chyba co som pisal hore sa tyka headeru, to by hadam mal ffprobe alebo ffmpeg nejak vediet hned zachytit bez nutnosti skenovat cely kontajner.

Re:FFmpeg: jak validovat multimediální soubor?
« Odpověď #3 kdy: 16. 11. 2024, 15:45:50 »
Já chápu, co je záměrem.
Ale bohužel o tom je právě celá ta debata.. Pro omezení chyb při následném zpracování nestačí jen vydetekovat typ souboru, a identifikovat streamy. Pokud to má spolehlivě validovat a pracovat s různými formáty souborů, co se od sebe zásadně liší, tak je potřeba důkladnější analýza. Ta pak logicky v závislosti na typu souboru vyžaduje nějaký čas.
A jak jsem psal, není to úplně jednoduché, opravdu nestačil jen ffmpeg, musel jsem kombinovat víc nástrojů a stejně jsem pokryl pouze část.

ffmpeg se v podstatě bez dalšího nastavení podívá jen na začátek vstupního souboru (podle -analyzeduration, resp. -probesize) a identifikují se základní parametry kontejneru a streamů, což se pak případně použije na nastavení demuxeru a dekodérů. To je celé, nemá to ambici hledat chyby ve struktuře souboru nebo datových blocích.
ffprobe pak může jít případně dál, procházet streamy (show_frames, show_packets, spočítat hashe atp.) a potencionálně nějaké evidentní věci odhalit, ale zas to bude záležet na formátu a konkrétním typu chyby - obecně bych na to moc nesázel.

Samozřejmě si můžete třeba vyhodnotit, že to nemá smysl řešit a jen reagovat na chyby při kódování.. Pokud vám ffmpeg vyhodí při následném transkódování problém, soubor vyhodíte a notifikujete uživatele. Návratové kódy nejsou 100%, ale když to třeba rozjedete s -v warning a budete parsovat stderr na výskyt určitých slov, tak můžete odchytit poměrně dost problémů.

Jak už jsem zmiňoval, tak některé zásadnější problémy dokáže docela dobře odhalit mediainfo, kterým můžete v nahradit i ten ffprobe na prvotní identifikaci. Dobře se s tím pracuje, v JSONu to vrací pole ConformanceErrors s případnými chybami.
Ale zas, jestli to zafunguje, bude záležet na typu toho problému (např. úplně chybějící kus souboru vs. pár flipnutých nebo zapadovaných bitů někdě v půlce). Můžete si jednoduše vyzkoušet, jestli vám řekne něco k té MP3ce (podle hlášky z ffmpegu mi to nepřijde jako chyba hlavičky, ale jeden nebo více poškozených rámců) a uvidíte.
Ale podobně jako ffprobe je to také nástroj primárně navržený na rychlou identifikaci vlastností souboru, ne na hloubkovou analýzu. Kterou, pokud budete chtít, tak musíte pořešit většinou dedikovaným nástrojem nebo prostě reagovat na chyby návazného transkodéru.

Zdaleka nejrobustnější je použití interních checksumů v hlavičce pro relativně rychlou externí validaci (byť s přečtením a počítáním hashe z téměř celého souboru), což odhalí i jakékoliv drobné chyby v celém řetězci, ale to je bohužel záležitost spíš bezztrátových audio formátů (BWF, FLAC, WavPack) nebo "profi" video kontejnerů (MXF s AS-07 rozšířením pro archivaci) a nedá se to využít u většiny běžných formátů.

Re:FFmpeg: jak validovat multimediální soubor?
« Odpověď #4 kdy: 16. 11. 2024, 16:10:21 »
Pokud vám ffmpeg vyhodí při následném transkódování problém, soubor vyhodíte a notifikujete uživatele.

Najskor asi tak, ako doteraz.


RDa

  • *****
  • 2 720
    • Zobrazit profil
    • E-mail
Re:FFmpeg: jak validovat multimediální soubor?
« Odpověď #5 kdy: 16. 11. 2024, 23:03:28 »
Protoze do toho delam vice nez dost, tak existuje vicero urovni QA:

- validace kontejneru
- validace bitstreamu
- konformita komprese vuci kodovacimu profilu
- konformita obsahu vuci kodovacimu profilu
- kontrola obsahu (vypadky/duplicitni framy)

Na vsechno existuje reseni, ale nebude to ffmpeg, protoze to je pouze bastl-hracka ktera umi jen to, co nekdo potreboval, ale neni to urceno ke QA na teto urovni.

Spise nam rekni co od toho chces, jake kodeky/kontejnery chces pokryvat a jaky na to mas rozpocet :)