2015-06-01 22 views
7

Sto utilizzando ffprobe per analizzare i file multimediali archiviati su un server remoto. Questo sembra funzionare bene, ma per alcuni file la durata è mancante o errata (di solito più lunga di quanto dovrebbe essere). Altre volte restituisce queste informazioni in modo accurato e non sembra essere correlato al tipo di supporto (codec, ecc.).In che modo ffprobe determina la durata?

Ecco un esempio di un comando che funziona:

ffprobe -v quiet -print_format json -show_streams -show_format http://host.com/file.aiff

{ 
"streams": [ 
    { 
     "index": 0, 
     "codec_name": "pcm_s16be", 
     "codec_long_name": "PCM signed 16-bit big-endian", 
     "codec_type": "audio", 
     "codec_time_base": "1/44100", 
     "codec_tag_string": "[0][0][0][0]", 
     "codec_tag": "0x0000", 
     "sample_fmt": "s16", 
     "sample_rate": "44100", 
     "channels": 2, 
     "bits_per_sample": 16, 
     "r_frame_rate": "0/0", 
     "avg_frame_rate": "0/0", 
     "time_base": "1/44100", 
     "start_pts": 0, 
     "start_time": "0.000000", 
     "duration_ts": 8494248, 
     "duration": "192.613333", 
     "bit_rate": "1411200", 
     "nb_frames": "8494248", 
     "disposition": { 
      "default": 0, 
      "dub": 0, 
      "original": 0, 
      "comment": 0, 
      "lyrics": 0, 
      "karaoke": 0, 
      "forced": 0, 
      "hearing_impaired": 0, 
      "visual_impaired": 0, 
      "clean_effects": 0, 
      "attached_pic": 0 
     } 
    } 
], 
"format": { 
    "filename": "http://host.com/file.aiff", 
    "nb_streams": 1, 
    "nb_programs": 0, 
    "format_name": "aiff", 
    "format_long_name": "Audio IFF", 
    "start_time": "0.000000", 
    "duration": "192.613333", 
    "probe_score": 100 
} 
} 

Ecco un esempio di uno che non lo fa:

ffprobe -v quiet -print_format json -show_streams -show_format "http://host.com/file.wav"

che genera questo risultato:

{ 
"streams": [ 
    { 
     "index": 0, 
     "codec_name": "pcm_s16le", 
     "codec_long_name": "PCM signed 16-bit little-endian", 
     "codec_type": "audio", 
     "codec_time_base": "1/44100", 
     "codec_tag_string": "[1][0][0][0]", 
     "codec_tag": "0x0001", 
     "sample_fmt": "s16", 
     "sample_rate": "44100", 
     "channels": 2, 
     "bits_per_sample": 16, 
     "r_frame_rate": "0/0", 
     "avg_frame_rate": "0/0", 
     "time_base": "1/44100", 
     "bit_rate": "1411200", 
     "disposition": { 
      "default": 0, 
      "dub": 0, 
      "original": 0, 
      "comment": 0, 
      "lyrics": 0, 
      "karaoke": 0, 
      "forced": 0, 
      "hearing_impaired": 0, 
      "visual_impaired": 0, 
      "clean_effects": 0, 
      "attached_pic": 0 
     } 
    } 
], 
"format": { 
    "filename": "http://host.com/file.wav", 
    "nb_streams": 1, 
    "nb_programs": 0, 
    "format_name": "wav", 
    "format_long_name": "WAV/WAVE (Waveform Audio)", 
    "bit_rate": "1411200", 
    "probe_score": 99 
} 
} 

Questi due esempi sono formati diversi, ma l'ho visto funzionare e non funzionare quando il formato è lo stesso, semplicemente non ho un esempio pratico.

Quello che mi piacerebbe sapere è se c'è qualcosa che posso cambiare sui parametri che sto usando con ffprobe per consentire di determinare la durata in modo coerente e preciso, o qualsiasi informazione che posso trovare su come funziona ffprobe così capisco come posso cambiare i file di input, ecc. in modo che funzionino correttamente.

In alternativa, se esiste uno strumento diverso che funziona in modo più affidabile (dovrebbe essere uno strumento Linux open source) qualsiasi suggerimento o suggerimento è benvenuto.

+1

Il modo più accurato sarebbe probabilmente quello di decodificare completamente il file, quindi guardare l'output della console: 'ffmpeg -i input -f null -'. Sfortunatamente questo può richiedere del tempo a seconda del tuo input. – LordNeckbeard

+0

Pensavo che FFmpeg usasse il contenitore per calcolare la durata (fondamentalmente fidandosi di qualunque metadata fosse nel contenitore ...)? – rogerdpack

+0

@LordNeckbeard ffmpeg fornisce una durata precisa dopo il completamento del processo di transcodifica, ma per la mia applicazione non posso permettermi di memorizzare il risultato prima di iniziare a restituirlo al client (o in alternativa, il tempo di eseguire l'operazione di transcodifica due volte) . – jasongullickson

risposta

3

Una soluzione semplice è quella di utilizzare l'opzione -show_packets

ffprobe -i input.mp4 -show_packets > a.txt 

a.txt ora aperto e andare a l'ultimo pacchetto e vedere dts_time valore che sarebbe la durata precisa di file. Se dts_time non è definito, verificare il valore pts_time.