Bagaimana cara mendapatkan durasi video dalam hitungan detik?

70

Bagaimana saya bisa mendapatkan durasi video dalam hitungan detik?

Apa yang saya coba:

ffmpeg -i file.flv 2>&1 | grep "Duration"
  Duration: 00:39:43.08, start: 0.040000, bitrate: 386 kb/s


mediainfo file.flv | grep Duration
Duration : 39mn 43s

Ini seberapa dekat, tetapi tidak begitu akurat, 2383 adalah 39,71 menit

ffmpeg -i file.flv 2>&1 | grep "Duration"| cut -d ' ' -f 4 | sed s/,// | sed 's@\..*@@g' | awk '{ split($1, A, ":"); split(A[3], B, "."); print 3600*A[1] + 60*A[2] + B[1] }'
2383
pengguna2783132
sumber

Jawaban:

36

Untuk mendapatkan menit, Anda harus membagi 2383 detik dengan 60.

39.7167

dan kemudian kalikan bagian pecahan .7167 dengan 60 untuk mendapatkan detik yang tersisa.

43.002

Jadi 39 menit, 43 detik. Aplikasi tampaknya memberi Anda nilai yang akurat.

Robert Harvey
sumber
97

Cukup gunakan ffprobelangsung. Tidak perlu untuk sed, grep, dll Ada beberapa "jangka waktu" Anda dapat memperoleh (tergantung pada masukan Anda).

Format (wadah) durasi

$ ffprobe -v error -show_entries format=duration \
  -of default=noprint_wrappers=1:nokey=1 input.mp4

30.024000

Menambahkan -sexagesimalopsi akan menggunakan format satuan waktu JAM: MM: SS.MICROSECONDS:

0:00:30.024000

Durasi aliran video

$ ffprobe -v error -select_streams v:0 -show_entries stream=duration \
  -of default=noprint_wrappers=1:nokey=1 input.mp4
30.000000

Perintah di atas berasal dari FFmpeg Wiki: Tips FFprobe .

Dengan ffmpeg

Anda mungkin perlu mendekodekan input sepenuhnya jika Anda menemukan wadah atau durasi aliran hilang atau tidak akurat (mungkin karena file yang rusak atau terpotong).

$ ffmpeg -i input.mp4 -f null -
  …
  frame= 1587 fps=0.0 q=0.0 Lsize=N/A time=00:01:03.48 bitrate=N/A

Dalam contoh ini time=00:01:03.48adalah durasinya:

Berapa lama ini tentu akan tergantung pada kompleksitas pengodean dan durasi input Anda dan kemampuan komputer Anda.

llogan
sumber
Ini tidak bekerja untuk file .m2v apakah Anda punya solusi untuk mereka juga
utdev
@utdev Lihat bagian "Dengan ffmpeg".
Logan
Solusi ketiga Anda memberi saya waktu yang salah, video saya memiliki panjang 01:19:00 tetapi perintah mengembalikan saya waktu = 01: 09: 15.32, apakah Anda memiliki tebakan mengapa ini terjadi
utdev
Sangat berguna durasi aliran media. Terima kasih.
Kami adalah Borg
Bagi siapa pun yang menggunakan avprobe, parameternya sedikit berbeda: avprobe -v error -show_format_entry durasi. \ Sample.mp4
Brad
33

Jika sudah ffmpeg, Anda juga harus memiliki ffprobe:

ffprobe -i input.file -show_format | grep duration
ffprobe -i input.file -show_format -v quiet | sed -n 's/duration=//p'

Ini juga akan memberikan sepersekian detik, jika itu masalah Anda dapat memproses lebih lanjut dengan sed.

Evilsoup
sumber
bagaimana saya bisa menghapus bagian pecahan detik?
Tina J
@TinaJ Hanya pipa dengan printf, seperti | xargs printf %.0f- ini akan mengembalikan nilai integer.
Ilia Rostovtsev
3

Untuk ffmpeg-0.6.5-1.el6.rf.x86_64 saya, untuk mendapatkan yang kedua, format perintah ffprobe adalah:

ffprobe <file> -show_format 2>&1 | sed -n 's/duration=//p' 
Sunry
sumber
bagaimana saya bisa menghapus bagian pecahan detik?
Tina J
3

Solusi dengan mplayer yang memberikan detik secara langsung:

mplayer -identify -frames 0 -vo null -nosound file.flv 2>&1 | awk -F= '/LENGTH/{print $2}'
micke
sumber
2
mediainfo --Output='General;%Duration%' file.flv

Ini menghasilkan durasi dalam milidetik sebagai nilai integer tunggal. Tidak perlu untuk grep / cut / sed / ...

Josef Kufner
sumber
Terima kasih - ini hanya apa yang saya cari. Dapat diinstal pada MacOS denganbrew install mediainfo
Alex K
0

Saya menemukan masalah mendapatkan beberapa metadata yang aneh dan tidak benar dari beberapa file video yang saya kerjakan dan saya tidak bisa berhasil menemukan pola atau jenis penanganan menggunakan kode dan alat-alat seperti ffmpeg, mp4box, ffprobe, mediainfo, mplayer, untuk mendapatkan durasi nyata dari video.

Mengidentifikasi durasi nyata video adalah persyaratan untuk proyek yang sedang saya kerjakan dan satu-satunya cara yang saya temukan untuk selalu melakukannya dengan benar adalah dengan me-encode ulang file video menggunakan ffmpeg dan memaksa file yang disandikan untuk mengabaikan metadata file asli, seperti:

ffmpeg -i INPUT_FILENAME -acodec copy -vcodec copy -map_metadata -1 OUTPUT_FILENAME"

(Ini mungkin berjalan lebih cepat dari yang Anda harapkan. Saya terkejut, untuk jenis konten dan pada lingkungan yang saya gunakan, waktu rata-rata adalah 2 detik)

... lalu dapatkan durasi menggunakan alat sesuai pilihan Anda. Saya suka mediainfo, btw: - "mediainfo FILE --Inform =" Video;% Duration% "memberi Anda durasi dalam milidetik.

satirio
sumber
Anda tidak memberikan lebih banyak informasi atau solusi yang lebih baik daripada jawaban lain
Sam
0

Jika Anda hanya perlu menanyakan metadata:

ffprobe -hide_banner -v quiet -show_streams -print_format flat video.mp4

[...]

streams.stream.0.duration="5221.146009"

[...]

Jadi Anda dapat menguraikannya:

while read -r; do
  if [[ "$REPLY" =~ ^streams\.stream\.([0-9])+\.duration=\"([^"]+)\"$ ]]; then
    echo -E Duration of stream "${BASH_REMATCH[1]}": "${BASH_REMATCH[2]}"
  fi
done < <(ffprobe -hide_banner -v quiet -show_streams -print_format flat video.mp4)

Tetapi jika Anda ingin mendapatkan durasi penampung yang efektif, Anda harus mendekodekannya:

AV_LOG_FORCE_NOCOLOR=y ffmpeg -nostdin -hide_banner -nostats -loglevel info -i video.mp4 -f null -c copy - 2>&1 | tail -n 2

Butuh waktu CPU untuk memecahkan kode, hingga:

[...]

frame=130527 fps=53271 q=-1.0 Lsize=N/A time=01:27:01.12 bitrate=N/A speed=2.13e+03x
video:152014kB audio:40790kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown

Kemudian, Anda dapat menguraikannya:

if [[ "$(AV_LOG_FORCE_NOCOLOR=y ffmpeg -nostdin -hide_banner -nostats -loglevel info -i video.mp4 -f null -c copy - 2>&1 | tail -n 2 | head -n 1)" =~ \ time=([0-9]+):([0-9]{2}):([0-9]{2})\.([0-9]+) ]]; then
  declare duration=0 us="${BASH_REMATCH[4]}" t
  for t in "${BASH_REMATCH[@]:1:3}"; do
    ((duration *= 60))
    ((duration += ${t#0} ))
  done
  while [ ${#us} -lt 6 ]; do us+=0; done
  ((us >= 500000)) && ((duration++))
  ((duration)) || ((duration++))
fi
echo -E Duration: "$duration"
Luchostein
sumber
-6

Jika Anda ingin durasi ACCURATE, lupakan FFmpeg. Ini hanya memberikan estimasi berdasarkan filesize dan bitrate rata-rata. Saya telah menemukan, dalam beberapa kasus, perkiraan waktu istirahat 2x lipat!

Di Linux, jika file dibuat dan dimodifikasi hanya selama perekaman video tersebut, solusi alternatifnya adalah menggunakan kreasi dan waktu modifikasi terakhir untuk menghitung durasi, seperti pada:

stat -c "%X %Y" video.mpg | awk '{print $2 - $1}'
codechimp
sumber
5
Di mana Anda menemukan bahwa ffmpeg tidak akurat?
aleb
4
% X adalah waktu akses terakhir. % Y adalah waktu sejak terakhir diubah. Ini tidak mengatakan apa-apa tentang panjang video.
Joe Hillenbrand
1
Ini tampaknya menjadi troll
George Chalhoub