Làm cách nào để có thời lượng video tính bằng giây?


69

Làm cách nào tôi có thể nhận được thời lượng video trong vài giây?

Những gì tôi đã thử:

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

Điều này rất gần, nhưng nó không chính xác lắm, 2383 là 39,71 phút

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

Câu trả lời:


36

Để có được phút, bạn phải chia 2383 giây cho 60.

39.7167

và sau đó nhân phần phân số .7167 với 60 để có các giây còn lại.

43.002

Vậy là 39 phút, 43 giây. Ứng dụng này dường như mang lại cho bạn một giá trị chính xác.


96

Chỉ cần sử dụng ffprobetrực tiếp. Không cần sed, grepvv Có rất nhiều "khoảng thời gian" bạn có thể có được (phụ thuộc vào đầu vào của bạn).

Định dạng (container) thời lượng

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

30.024000

Thêm -sexagesimaltùy chọn sẽ sử dụng định dạng đơn vị thời gian HOURS: MM: SS.MICROSECONDS:

0:00:30.024000

Thời lượng luồng video

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

Các lệnh trên là từ FFmpeg Wiki: FFprobe Tips .

Với ffmpeg

Bạn có thể cần giải mã hoàn toàn đầu vào nếu bạn thấy thời gian chứa hoặc luồng bị thiếu hoặc không chính xác (có thể do tệp bị hỏng hoặc bị cắt).

$ 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

Trong ví dụ time=00:01:03.48này là thời lượng:

Tất nhiên việc này sẽ kéo dài bao lâu tùy thuộc vào độ phức tạp giải mã và thời lượng đầu vào của bạn và khả năng của máy tính.


Chúng không hoạt động đối với các tệp .m2v, bạn có giải pháp nào cho chúng không
utdev

@utdev Xem phần "Với ffmpeg".
llogan

Giải pháp thứ ba của bạn cho tôi thời gian sai, video của tôi có độ dài là 01:19:00 nhưng lệnh trả lại cho tôi thời gian = 01: 09: 15.32, bạn có đoán được tại sao điều này xảy ra không
utdev 15/2/2017

Rất hữu ích thời lượng luồng phương tiện truyền thông. Cảm ơn bạn.
Chúng tôi là Borg

Đối với bất kỳ ai sử dụng avprobe, các tham số hơi khác nhau: avprobe -v error -show_format_entry thời gian. \ Sample.mp4
Brad

32

Nếu bạn có ffmpeg, bạn cũng nên có ffprobe:

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

Điều này cũng sẽ cho các phân số của giây, nếu đó là vấn đề bạn có thể xử lý thêm với sed.


Làm thế nào tôi có thể loại bỏ phần phân số của giây?
Tina J

@TinaJ Chỉ cần đặt nó với printf, như | xargs printf %.0f- điều này sẽ trả về một giá trị số nguyên.
Ilia Rostovtsev

3

Đối với ffmpeg-0.6.5-1.el6.rf.x86_64 của tôi, để có được định dạng lệnh thứ hai, ffprobe là:

ffprobe <file> -show_format 2>&1 | sed -n 's/duration=//p' 

Làm thế nào tôi có thể loại bỏ phần phân số của giây?
Tina J

3

Giải pháp với mplayer cung cấp giây trực tiếp:

mplayer -identify -frames 0 -vo null -nosound file.flv 2>&1 | awk -F= '/LENGTH/{print $2}'

2
mediainfo --Output='General;%Duration%' file.flv

Điều này xuất ra thời lượng tính bằng mili giây dưới dạng một giá trị số nguyên duy nhất. Không cần grep / cut / sed / ...


Cảm ơn - đây chỉ là những gì tôi đang tìm kiếm. Có thể được cài đặt trên MacOS vớibrew install mediainfo
Alex K

0

Tôi đã gặp phải vấn đề nhận một số siêu dữ liệu lạ và không chính xác từ một số tệp video mà tôi đang làm việc và tôi không thể thành công trong việc tìm mẫu hoặc bất kỳ loại xử lý nào bằng mã và công cụ như ffmpeg, mp4box, ffprobe, mediainfo, mplayer, để có được thời lượng thực của video.

Xác định thời lượng thực của video là một yêu cầu cho một dự án tôi đang làm việc và cách duy nhất tôi thấy để luôn luôn đúng là mã hóa lại tệp video bằng ffmpeg và buộc các tệp được mã hóa bỏ qua siêu dữ liệu của tệp gốc, như:

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

(Điều này có thể chạy nhanh hơn bạn mong đợi. Tôi đã rất ngạc nhiên, đối với loại nội dung và trên môi trường tôi đang sử dụng, thời gian trung bình là 2 giây)

... Và sau đó nhận được thời lượng bằng cách sử dụng một công cụ theo lựa chọn của bạn. Tôi thích mediainfo, btw: - "mediainfo FILE --Inform =" Video;% Thời lượng% "cung cấp cho bạn thời lượng tính bằng miliseconds.


Bạn đã không cung cấp nhiều thông tin hoặc giải pháp tốt hơn các câu trả lời khác
Sam

0

Nếu bạn chỉ cần truy vấn siêu dữ liệu:

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

[...]

streams.stream.0.duration="5221.146009"

[...]

Vì vậy, bạn có thể phân tích nó:

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)

Nhưng nếu bạn muốn có được thời lượng của bộ chứa hiệu quả, bạn cần giải mã nó:

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

Sẽ mất một chút thời gian CPU để giải mã nó, cho đến khi:

[...]

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

Sau đó, bạn có thể phân tích nó:

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"

-6

Nếu bạn muốn thời lượng CHÍNH XÁC, hãy quên FFmpeg. Nó chỉ đưa ra ước tính dựa trên kích thước tệp và bitrate trung bình. Trong một số trường hợp, tôi đã tìm thấy thời gian nghỉ ước tính gấp 2 lần!

Trên Linux, nếu tệp được tạo và sửa đổi chỉ trong quá trình quay video đã nói, một giải pháp thay thế sẽ là sử dụng thời gian tạo và sửa đổi lần cuối để tính thời lượng, như trong:

stat -c "%X %Y" video.mpg | awk '{print $2 - $1}'

5
Trường hợp bạn thấy rằng ffmpeg là không chính xác?
aleb

4
% X là thời gian truy cập lần cuối. % Y là thời gian kể từ lần sửa đổi cuối cùng. Điều này không nói gì về độ dài video.
Joe Hillenbrand

1
Đây dường như là một trò troll
George Chalhoub
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.