2013-09-25 19:35:33 +0000 2013-09-25 19:35:33 +0000
75
75

如何获得以秒为单位的视频时长?

如何获得以秒为单位的视频时长?

我试过的。

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
```。

答案 (9)

105
105
105
2015-07-26 22:07:37 +0000

直接使用ffprobe即可。不需要sedgrep等。有几种 “持续时间 "你可以获得(取决于你的输入)。

格式(容器)持续时间

$ 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 Wiki: FFprobe Tips .

使用 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是持续时间。

这需要多长时间,当然取决于解码的复杂程度、输入的持续时间和计算机的能力。

35
35
35
2013-09-25 19:41:05 +0000

要得到分钟,你必须将2383秒除以60。

39.7167

然后将小数部分0.7167乘以60得到剩余的秒数。

43.002

所以是39分43秒。应用程序似乎给了你一个准确的数值。

34
34
34
2013-09-25 21:10:07 +0000

如果你有ffmpeg,你也应该有ffprobe

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

这也会给出秒的分数,如果有问题,你可以用sed进一步处理掉。

3
3
3
2018-05-05 08:00:38 +0000
mediainfo --Output='General;%Duration%' file.flv

这将持续时间以毫秒为单位输出为一个整数值。不需要grep/cut/sed/…

3
3
3
2013-09-25 19:56:50 +0000

用mplayer直接给出秒数的解决方案。

mplayer -identify -frames 0 -vo null -nosound file.flv 2>&1 | awk -F= '/LENGTH/{print $2}'
3
3
3
2014-06-16 22:06:49 +0000

对于我的 ffmpeg-0.6.5-1.el6.rf.x86/64,只需获取第二条,ffprobe 命令的格式是。

ffprobe <file> -show_format 2>&1 | sed -n 's/duration=//p'
0
0
0
2019-08-30 19:39:55 +0000

如果你只需要查询元数据。

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"
``` 0x1&
0
0
0
2017-06-01 01:01:24 +0000

我遇到了从一些视频文件中获取一些奇怪的和不正确的元数据的问题,我无法成功地找到一种模式或任何类型的处理方法,使用代码和工具,如ffmpeg, mp4box, ffprobe, mediainfo, mplayer,来获取视频的真实持续时间。

识别视频的真实持续时间是我正在做的一个项目的要求,我发现唯一能让它始终正确的方法是使用ffmpeg重新编码视频文件,并强制编码后的文件忽略原始文件的元数据,比如。

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

(这可能比你想象的要快) 我很惊讶,对于内容的类型和我使用的环境,平均时间是2秒)

……然后用你选择的工具获得持续时间。我喜欢mediainfo,顺便说一下:- “mediainfo FILE –Inform="Video;%Duration%” 给你以毫秒为单位的持续时间。

-6
-6
-6
2015-04-27 01:59:24 +0000

如果你想要准确的持续时间,请忘记FFmpeg。它只给出了一个基于文件大小和平均比特率的估计。我发现,在某些情况下,估计的持续时间偏离了2倍!

在Linux上,如果文件只是在视频录制期间才被创建和修改,另一个解决方案是使用创建和最后修改时间来计算持续时间,如:

stat -c "%X %Y" video.mpg | awk '{print $2 - $1}'
``` 在Linux上,如果文件只是在视频录制期间才被创建和修改,另一个解决方案是使用创建和最后修改时间来计算持续时间。

0x1&