[Python] moduli, efficienti, per riconoscimento tipi mime

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Avatar utente
nuzzopippo
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1473
Iscrizione: giovedì 12 ottobre 2006, 11:34

[Python] moduli, efficienti, per riconoscimento tipi mime

Messaggio da nuzzopippo »

I miei saluti,
Sto estendendo il giochetto postato qui con l'idea di fargli riprodurre ed organizzare i files audio/video trovati con ricerca ricorsiva su dischi e periferiche.

Come nel post in link son partito utilizzando, per il riconoscimento dei files multimediali, il modulo "magic" che però nei test si è rivelato insoddisfacente, infatti in alcuni casi da output del genere:

Codice: Seleziona tutto

>>> for f in f_audio:
...     print(f, ' - ', magic.from_file(f, mime=True))
... 
CD1-01.mp3  -  application/octet-stream
CD1-02.mp3  -  application/octet-stream
CD1-03.mp3  -  application/octet-stream
CD1-04.mp3  -  application/octet-stream
quando, invece, si è di fronte a normali files audio

Codice: Seleziona tutto

(vlc_v) NzP:~$ file ./*
./CD1-01.mp3: Audio file with ID3 version 2.3.0
./CD1-02.mp3: Audio file with ID3 version 2.3.0
./CD1-03.mp3: Audio file with ID3 version 2.3.0
./CD1-04.mp3: Audio file with ID3 version 2.3.0
Ovviamente, la cosa complica un po' la vita, non potendosi fidare del responso di magic bisogna percorrere altre strade.

Qualcuno conosce librerie o moduli più efficienti (ovviamente pythonici) per il riconoscimento dei files multimediali? Vorrei evitare di dover ricorrere al riconoscimento delle estensioni, già così valutare un HD usb da 400-500 gb è una cosa lunga

Grazie dell'attenzione, ciao :)
Fatti non foste a viver come bruti ...
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4540
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 18.04.4 64bit

Re: [Python] moduli, efficienti, per riconoscimento tipi mime

Messaggio da vaeVictis »

Codice: Seleziona tutto

>>> import mimetypes
>>> mimetypes.guess_type("Classica/LossLess/Giuseppe Verdi/Rigoletto/Disc 01 - Atto I/01 - Preludio, Atto I.flac")
('audio/flac', None)
>>> mimetypes.guess_type("Rock/Talking Heads/Studio Album/1985 - Little Creatures/06 - Stay Up Late.mp3")
('audio/mpeg', None)
>>> mimetypes.guess_type("Noir/Against All Odds/Against All Odds.avi")
('video/x-msvideo', None)
>>> mimetypes.guess_type("Fantasy/Highlander.mkv")
('video/x-matroska', None)
>>> mimetypes.guess_type("Fantascienza/Blade Runner/Blade Runner Directors Cut.mp4")
('video/mp4', None)
che corrispondono a:

Codice: Seleziona tutto

$ file --mime-type "Classica/LossLess/Giuseppe Verdi/Rigoletto/Disc 01 - Atto I/01 - Preludio, Atto I.flac"
Classica/LossLess/Giuseppe Verdi/Rigoletto/Disc 01 - Atto I/01 - Preludio, Atto I.flac: audio/x-flac
$ file --mime-type "Rock/Talking Heads/Studio Album/1985 - Little Creatures/06 - Stay Up Late.mp3"
Rock/Talking Heads/Studio Album/1985 - Little Creatures/06 - Stay Up Late.mp3: audio/mpeg
$ file --mime-type "Noir/Against All Odds/Against All Odds.avi"
Noir/Against All Odds/Against All Odds.avi: video/x-msvideo
$ file --mime-type "Fantasy/Highlander.mkv"
Fantasy/Highlander.mkv: video/x-matroska
$ file --mime-type "Fantascienza/Blade Runner/Blade Runner Directors Cut.mp4"
Fantascienza/Blade Runner/Blade Runner Directors Cut.mp4: video/mp4
In un'applicazione dovevo filtrare solo i file testuali e ho usato questa funzione:

Codice: Seleziona tutto

def isValidMimeType(filePath):
    fileMimetype = mimetypes.guess_type(filePath)[0]
    return fileMimetype and fileMimetype.startswith("text")
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once, but I fear the man who has practiced one kick 10000 times.»
Avatar utente
nuzzopippo
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1473
Iscrizione: giovedì 12 ottobre 2006, 11:34

Re: [Python] moduli, efficienti, per riconoscimento tipi mime

Messaggio da nuzzopippo »

Grazie @Vae, del suggerimento e delle indicazioni, proverò mimetypes e farò sapere che ne esce ... ovvio, ci vorrà un po', dar la caccia alle "eccezioni" spesso richiede un po' di tempo.

Ciao :)

[Edit] ... Aiah! leggendo la docs, vedo che si basa sulle estensioni dei filename, da una prova "veloce", richiedendo il tipo dei file contenuti in un directory, la risposta è corretta

Codice: Seleziona tutto

>>> import os
>>> import mimetypes
>>> f_audio = os.listdir()
>>> for f in f_audio:
...     print(f, ' - ', mimetypes.guess_type(f))
... 
Fabrizio De André - Canzone per l'estate (VERSIONE INEDITA -.mp3  -  ('audio/mpeg', None)
Un'emozione da poco - YouTube.mp3  -  ('audio/mpeg', None)
MATIA BAZAR - Vacanze Romane (SANREMO 1983 - Prima Esibizion.mp3  -  ('audio/mpeg', None)
ma se vado ad eliminare l'estensione di uno dei file, esso non viene riconosciuto, guarda il pezzo di De Andrè

Codice: Seleziona tutto

>>> f_audio = os.listdir()
>>> for f in f_audio:
...     print(f, ' - ', mimetypes.guess_type(f))
... 
Un'emozione da poco - YouTube.mp3  -  ('audio/mpeg', None)
MATIA BAZAR - Vacanze Romane (SANREMO 1983 - Prima Esibizion.mp3  -  ('audio/mpeg', None)
I Pooh- Noi due nel mondo e nell'anima - YouTube.mp3  -  ('audio/mpeg', None)
Fabrizio De André - Canzone per l'estate (VERSIONE INEDITA -  -  (None, None)
Lucio Dalla - Caruso (Videoclip) - YouTube.mp3  -  ('audio/mpeg', None)
gran problema, da linuxaro incallito negli anni spesso non le ho considerate proprio le estensioni dei filenames, parte dei miei media non verrebbero identificati e comunque le estensioni non garantiscono il contenuto, li c'è un farwest tipo quello dei csv ... mi sa che forse conviene ricorrervi in caso di risposta "application/octet-stream" da parte di magic, giusto per ulteriore controllo, ma non di più.

Comunque, grazie ancora del suggerimento, cercherò altro ed in caso non trovi userò mimetypes per integrare le verifiche :birra:
Fatti non foste a viver come bruti ...
rai
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 2446
Iscrizione: domenica 11 maggio 2008, 18:03
Desktop: plasma
Distribuzione: 20.04
Località: Palermo

Re: [Python] moduli, efficienti, per riconoscimento tipi mime

Messaggio da rai »

Ciao
io ho rinunciato ad usare il modulo mimetypes perchè mi sono accorto che per riconoscere i file non si basa sul contenuto ma sulla estensione.
Nel mio caso (mi bastava riconoscere pochi tipi di documento) avevo deciso di usare il "fai da te" estraendo l'estensione con l'uso del modulo pathlib (che comunque era già importato) e matchandola in un piccolo dizionario prefabbricato

So che esistono in Pypi dei moduli che riproducono il funzionamento della utility file della shell ma io non li ho usati

EDIT per esempio https://pypi.python.org/pypi/filemagic/1.6

RI-EDIT @nuzzopippo non avevo letto il tuo edit, quindi te ne eri accorto da te :birra:
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4540
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 18.04.4 64bit

Re: [Python] moduli, efficienti, per riconoscimento tipi mime

Messaggio da vaeVictis »

Questa cosa non l'avevo proprio notata nella documentazione. Forse con i txt si regola bene anche senza estensione, perché mi andava bene anche in quel caso. Più tardi vedo se trovo alternative.

edit: no, non funziona neanche con i txt. Ammazza che ciofeca che ti ho suggerito, scusami.
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once, but I fear the man who has practiced one kick 10000 times.»
Avatar utente
nuzzopippo
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1473
Iscrizione: giovedì 12 ottobre 2006, 11:34

Re: [Python] moduli, efficienti, per riconoscimento tipi mime

Messaggio da nuzzopippo »

Ciao @rai, si me ne ero accorto ed ho anche provato file-magic (ATTENZIONE : corrompe l'installazione di python-magic, usano entrambi un modulo denominato "magic.py") ed è decisamente più dettagliato di python-magic ... purtoppo, questo non semplifica le cose, nel caso esposto nel primo post viene comunque restituito "application/octet-stream" quale PRIMO elemento di una serie di named tuple, nelle altre, compare si "audio" ad un certo punto, purtoppo la composizione delle named tuple è variabile e non ritengo che aggiungere un ulteriore ciclo di verifica del risultato ottenuto riduca le prestazioni.

... al momento sto mediando inserendo nel thread di scansione questa verifica:

Codice: Seleziona tutto

            self.count_file += 1
            # è un nodo-file, lo esamina
            magic_type = magic.from_file(f_name, mime=True)
            if self.type in magic_type:
                is_type = True
            elif 'application/octet-stream' in magic_type:
                is_type = self._verify_for_extension(f_name)
            else:
                is_type = False
            if is_type:
                # è del tipo richiesto, lo aggiunge
                self.count_media += 1
...
le prestazioni non diminuiscono di molto prima ed il punto "incriminato" viene superato, per altro su di un test limitato ad un migliaio di files i risultati sembrano buoni, la differenza tra i files conteggiati ed i files multimediali trovati corrispondeva con lo stato di fatto ... ora deve venirmi in mente qualche verifica più estesa e meno faticosa del visualizzare direttamente i contenuti trovati e quelli esistenti su set di centinaia di migliaia di files.

Grazie ragazzi :) :birra:
Fatti non foste a viver come bruti ...
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 2 ospiti