วิธีรับระยะเวลาวิดีโอในไม่กี่วินาที?


69

ฉันจะรับระยะเวลาวิดีโอเป็นวินาทีได้อย่างไร

สิ่งที่ฉันได้ลอง:

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

นี่ใกล้แค่ไหน แต่ก็ไม่แม่นยำ 2383 เป็น 39.71 นาที

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

คำตอบ:


36

ในการรับนาทีคุณต้องแบ่ง 2383 วินาทีด้วย 60

39.7167

จากนั้นคูณส่วนเศษส่วน. 7167 คูณด้วย 60 เพื่อรับวินาทีที่เหลือ

43.002

มันคือ 39 นาที, 43 วินาที แอปพลิเคชันดูเหมือนจะให้คุณค่าที่ถูกต้องแก่คุณ


95

เพียงใช้ffprobeโดยตรง ไม่จำเป็นต้องsed, grepฯลฯ มีหลาย "ระยะเวลา" ที่คุณสามารถได้รับ (ขึ้นอยู่กับการป้อนข้อมูลของคุณ)

ระยะเวลารูปแบบ (คอนเทนเนอร์)

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

30.024000

การเพิ่ม-sexagesimalตัวเลือกจะใช้เวลา HOURS: MM: SS.MICROSECONDS รูปแบบหน่วยเวลา:

0:00:30.024000

ระยะเวลาการสตรีมวิดีโอ

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

คำสั่งดังกล่าวจากFFmpeg วิกิพีเดีย: เคล็ดลับ

กับ ffmpeg

คุณอาจจำเป็นต้องถอดรหัสอินพุตโดยสมบูรณ์หากคุณพบว่าระยะเวลาของคอนเทนเนอร์หรือสตรีมหายไปหรือไม่ถูกต้อง (อาจเป็นเพราะไฟล์ที่เสียหายหรือถูกตัดทอน)

$ 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

ในตัวอย่างนี้time=00:01:03.48คือระยะเวลา:

แน่นอนว่าจะใช้เวลานานเท่าใดขึ้นอยู่กับความซับซ้อนและระยะเวลาในการถอดรหัสของอินพุตและความสามารถของคอมพิวเตอร์ของคุณ


สิ่งเหล่านี้ใช้ไม่ได้กับไฟล์. m2v คุณมีวิธีแก้ปัญหาสำหรับไฟล์เหล่านั้นด้วย
utdev

@utdev ดูส่วน "With ffmpeg"
35470 llogan

วิธีการแก้ปัญหาที่สามของคุณให้ฉันเวลาที่ผิดวิดีโอของฉันมีความยาว 1:19:00 แต่คำสั่งส่งกลับฉันเวลา = 01: 09: 15.32 คุณจะต้องเดาเหตุผลนี้เกิดขึ้น
utdev

มีประโยชน์มากในช่วงเวลาที่กระแสสื่อ ขอขอบคุณ.
เราคือ Borg

สำหรับทุกคนที่ใช้ avprobe พารามิเตอร์จะแตกต่างกันเล็กน้อย: avprobe -v error -show_format_entry Duration \ Sample.mp4
Brad

32

หากคุณมีffmpegคุณควรมีffprobe:

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

สิ่งนี้จะทำให้เศษเสี้ยววินาทีถ้าเป็นปัญหาคุณสามารถดำเนินการต่อไปได้โดยไม่ต้องกังวล


ฉันจะลบส่วนของวินาทีได้อย่างไร
Tina J

@TinaJ เพียงแค่ไพพ์ด้วยprintfเช่น| xargs printf %.0f- นี่จะคืนค่าจำนวนเต็ม
Ilia Rostovtsev

3

สำหรับ ffmpeg-0.6.5-1.el6.rf.x86_64 ของฉันเพื่อให้ได้รูปแบบคำสั่ง ffprobe ที่สองคือ:

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

ฉันจะลบส่วนของวินาทีได้อย่างไร
Tina J

3

วิธีแก้ปัญหาด้วย mplayer ที่ให้วินาทีโดยตรง:

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

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

สิ่งนี้จะแสดงระยะเวลาเป็นมิลลิวินาทีเป็นค่าจำนวนเต็มเดียว ไม่จำเป็นต้องใช้ grep / cut / sed / ...


ขอบคุณ - นี่เป็นสิ่งที่ฉันกำลังมองหา สามารถติดตั้งบน MacOS ด้วยbrew install mediainfo
Alex K

0

ฉันพบปัญหาในการรับข้อมูลเมตาที่แปลกและไม่ถูกต้องจากไฟล์วิดีโอบางไฟล์ที่ฉันทำงานด้วยและฉันไม่สามารถค้นหารูปแบบหรือการจัดการประเภทใด ๆ โดยใช้รหัสและเครื่องมือเช่น ffmpeg, mp4box, ffprobe, mediainfo, mplayer เพื่อรับช่วงเวลาที่แท้จริงของวิดีโอ

การระบุระยะเวลาที่แท้จริงของวิดีโอเป็นข้อกำหนดสำหรับโครงการที่ฉันใช้งานและวิธีเดียวที่ฉันพบว่าทำให้ถูกต้องเสมอคือการเข้ารหัสไฟล์วิดีโอโดยใช้ ffmpeg และบังคับให้เข้ารหัสไฟล์เพื่อละเว้นเมทาดาทาของไฟล์ดั้งเดิมเช่น:

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

(สิ่งนี้อาจทำงานได้เร็วกว่าที่คุณคาดหวังฉันประหลาดใจสำหรับประเภทของเนื้อหาและสภาพแวดล้อมที่ฉันใช้เวลาเฉลี่ย 2 วินาที)

... จากนั้นใช้ระยะเวลาในการเลือกเครื่องมือตามที่คุณต้องการ ฉันชอบ mediainfo, btw: - "mediainfo FILE --Inform =" วิดีโอ;% Duration% "ให้ระยะเวลาเป็นมิลลิวินาที


คุณไม่ได้ให้ข้อมูลเพิ่มเติมหรือมีวิธีแก้ปัญหาที่ดีกว่าคำตอบอื่น ๆ
Sam

0

หากคุณต้องการสืบค้นข้อมูลเมตา:

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

[ ... ]

streams.stream.0.duration="5221.146009"

[ ... ]

ดังนั้นคุณสามารถแยกมัน:

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)

แต่ถ้าคุณต้องการได้ระยะเวลาของคอนเทนเนอร์ที่มีประสิทธิภาพคุณต้องถอดรหัสมัน:

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

จะใช้เวลา CPU ในการถอดรหัสจนถึง:

[ ... ]

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

จากนั้นคุณสามารถวิเคราะห์ได้:

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

หากคุณต้องการระยะเวลาที่ถูกต้องลืม FFmpeg มันให้ค่าประมาณตามขนาดไฟล์และบิตเรตเฉลี่ย ฉันพบว่าในบางกรณีระยะเวลาโดยประมาณปิดลง 2x!

บน Linux หากไฟล์ถูกสร้างและแก้ไขในระหว่างการบันทึกวิดีโอดังกล่าวโซลูชันทางเลือกจะใช้การสร้างและเวลาการแก้ไขครั้งล่าสุดเพื่อคำนวณระยะเวลาดังใน:

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

5
คุณพบว่า ffmpeg ไม่ถูกต้องที่ไหน
aleb

4
% X คือเวลาที่เข้าถึงครั้งสุดท้าย % Y คือเวลาตั้งแต่แก้ไขครั้งสุดท้าย นี่ไม่ได้พูดอะไรเกี่ยวกับความยาววิดีโอ
Joe Hillenbrand

1
สิ่งนี้ดูเหมือนจะเป็นการหมุนรอบ
George Chalhoub
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.