如何从 ffmpeg 输出中提取持续时间?
- 2024-10-12 10:28:00
- admin 原创
- 86
问题描述:
要获取有关媒体文件的大量信息,可以这样做
ffmpeg -i <filename>
它会输出很多行,特别是其中一行
Duration: 00:08:07.98, start: 0.000000, bitrate: 2080 kb/s
我只想输出00:08:07.98
,所以我尝试
ffmpeg -i file.mp4 | grep Duration| sed 's/Duration: (.*), start//g'
但它打印所有内容,而不仅仅是长度。
甚至ffmpeg -i file.mp4 | grep Duration
输出一切。
我如何才能获得持续时间长度?
解决方案 1:
您可以使用ffprobe
:
ffprobe -i <file> -show_entries format=duration -v quiet -of csv="p=0"
它将以秒为单位输出持续时间,例如:
154.12
添加该选项将以小时:分钟:秒.微秒的-sexagesimal
形式输出持续时间:
00:02:34.12
解决方案 2:
ffmpeg 正在将该信息写入stderr
,而不是stdout
。尝试以下操作:
ffmpeg -i file.mp4 2>&1 | grep Duration | sed 's/Duration: (.*), start//g'
注意重定向stderr
到stdout
:2>&1
编辑:
您的sed
语句也不起作用。请尝试以下操作:
ffmpeg -i file.mp4 2>&1 | grep Duration | awk '{print $2}' | tr -d ,
解决方案 3:
根据我的经验,许多工具以某种表格/有序结构提供所需数据,并提供参数来收集该数据的特定部分。这也适用于例如smartctl、nvidia-smi和ffmpeg/ffprobe。简单地说 - 通常不需要将数据传输到管道或打开子shell来完成这样的任务。
因此,我会使用正确的工具来完成这项工作 - 在这种情况下,ffprobe 将以秒为单位返回原始持续时间值,之后人们可以自行创建所需的时间格式:
$ ffmpeg --version
ffmpeg version 2.2.3 ...
该命令可能因您使用的版本而异。
#!/usr/bin/env bash
input_file="/path/to/media/file"
# Get raw duration value
ffprobe -v quiet -print_format compact=print_section=0:nokey=1:escape=csv -show_entries format=duration "$input_file"
解释一下:
“-v quiet”:除了所需的原始数据值外,不输出任何其他内容
“-print_format”:使用一定的格式打印出数据
“compact=”:使用紧凑的输出格式
“print_section=0”:不打印章节名称
“:nokey=1”:不打印键值对的键
“:escape=csv”:转义值
“-show_entries format=duration”:获取名为 format 的部分内名为 duration 的字段的条目
参考:ffprobe 手册页
解决方案 4:
我建议使用 json 格式,它更容易解析
ffprobe -i your-input-file.mp4 -v quiet -print_format json -show_format -show_streams -hide_banner
{
"streams": [
{
"index": 0,
"codec_name": "aac",
"codec_long_name": "AAC (Advanced Audio Coding)",
"profile": "HE-AACv2",
"codec_type": "audio",
"codec_time_base": "1/44100",
"codec_tag_string": "[0][0][0][0]",
"codec_tag": "0x0000",
"sample_fmt": "fltp",
"sample_rate": "44100",
"channels": 2,
"channel_layout": "stereo",
"bits_per_sample": 0,
"r_frame_rate": "0/0",
"avg_frame_rate": "0/0",
"time_base": "1/28224000",
"duration_ts": 305349201,
"duration": "10.818778",
"bit_rate": "27734",
"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": "your-input-file.mp4",
"nb_streams": 1,
"nb_programs": 0,
"format_name": "aac",
"format_long_name": "raw ADTS AAC (Advanced Audio Coding)",
"duration": "10.818778",
"size": "37506",
"bit_rate": "27734",
"probe_score": 51
}
}
您可以在格式部分找到持续时间信息,适用于视频和音频
解决方案 5:
如果有一个请求参数,使用 mediainfo 及其输出格式会更简单,如下所示(持续时间;以毫秒为单位回答)
mediainfo --Output="General;%Duration%" ~/work/files/testfiles/+h263_aac.avi
输出
24840
解决方案 6:
如果您想使用 python 脚本通过 ffmpeg 从媒体文件中检索长度(以及可能所有其他元数据),您可以尝试以下操作:
import subprocess
import json
input_file = "< path to your input file here >"
metadata = subprocess.check_output(f"ffprobe -i {input_file} -v quiet -print_format json -show_format -hide_banner".split(" "))
metadata = json.loads(metadata)
print(f"Length of file is: {float(metadata['format']['duration'])}")
print(metadata)
输出:
Length of file is: 7579.977143
{
"streams": [
{
"index": 0,
"codec_name": "mp3",
"codec_long_name": "MP3 (MPEG audio layer 3)",
"codec_type": "audio",
"codec_time_base": "1/44100",
"codec_tag_string": "[0][0][0][0]",
"codec_tag": "0x0000",
"sample_fmt": "fltp",
"sample_rate": "44100",
"channels": 2,
"channel_layout": "stereo",
"bits_per_sample": 0,
"r_frame_rate": "0/0",
"avg_frame_rate": "0/0",
"time_base": "1/14112000",
"start_pts": 353600,
"start_time": "0.025057",
"duration_ts": 106968637440,
"duration": "7579.977143",
"bit_rate": "320000",
...
...
解决方案 7:
由于它解码输入,所以速度很慢,但即使元数据中存在错误/缺失的信息,也会显示正确的持续时间:
ffmpeg -i <filename> -f null - 2>&1 | awk -F= 'BEGIN{RS=" "}/^time=/{t=$2}END{print t}'
解决方案 8:
对于那些想要在 Windows 中不使用任何附加软件执行相同计算的人,这里是命令行脚本:
set input=video.ts
ffmpeg -i "%input%" 2> output.tmp
rem search " Duration: HH:MM:SS.mm, start: NNNN.NNNN, bitrate: xxxx kb/s"
for /F "tokens=1,2,3,4,5,6 delims=:., " %%i in (output.tmp) do (
if "%%i"=="Duration" call :calcLength %%j %%k %%l %%m
)
goto :EOF
:calcLength
set /A s=%3
set /A s=s+%2*60
set /A s=s+%1*60*60
set /A VIDEO_LENGTH_S = s
set /A VIDEO_LENGTH_MS = s*1000 + %4
echo Video duration %1:%2:%3.%4 = %VIDEO_LENGTH_MS%ms = %VIDEO_LENGTH_S%s
同样的答案发布在这里:如何从 TS 视频中裁剪最后 N 秒
解决方案 9:
这是我使用ffmpeg和awk的非常简单的解决方案。 的输出ffmpeg -i file.mp3
包含一个字符串Duration: 00:00:04.80, bitrate: 352 kb/s
。 只需简单地使用awk即可:
ffmpeg -i file.mp3 |& awk '/Duration:/ {print $2}'
我可以打印预期的结果:00:00:04.80
解决方案 10:
无需 grepping 或类似操作。只需输入此命令,您就会获得微秒级的精确时间!
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 file.mp4
来自 ffmpeg 文档
https://trac.ffmpeg.org/wiki/FFprobeTips
解决方案 11:
ffmpeg -i abc.mp4 2>&1 | grep Duration | cut -d ' ' -f 4 | sed s/,//
给出输出
HH:MM:SS.毫秒
解决方案 12:
# Returns duration (in seconds) of a video $1 (uses ffmpeg).
get_video_duration() {
OUTPUT=$(ffmpeg -i "$1" -vframes 1 -f rawvideo -y /dev/null 2>&1) ||
{ debug -e "get_video_duration: error running ffmpeg:
$OUTPUT"; return 1; }
DURATION=$(echo "$OUTPUT" | grep -m1 "^[[:space:]]*Duration:" |
cut -d":" -f2- | cut -d"," -f1 | sed "s/[:.]/ /g") ||
{ debug -e "get_video_duration: error parsing duration:
$OUTPUT"; return 1; }
read HOURS MINUTES SECONDS DECISECONDS <<< "$DURATION"
echo $((10#$HOURS * 3600 + 10#$MINUTES * 60 + 10#$SECONDS))
}
用法:
DURATION=$(get_video_duration "$VIDEO")
解决方案 13:
使用 ffprobe 从媒体文件中提取元数据
使用 pip 安装 ffprobe
pip 安装 ffprobe-python
`从子进程导入 check_output
文件名 = “video1.mp4”
command = str(check_output('ffprobe -i "'+file_name+'" 2>&1 |grep "Duration"',shell=True))
输出:b' 持续时间:00:17:56.62,开始:0.000000,比特率:397 kb/s n'
以hh:mm:ss格式分割持续时间 co = a.split(",")[0].split("Duration:")[1].strip()
h, m, s = a.split(':') 持续时间 = int(h) 3600 + int(m) 60 + float(s)
打印(持续时间)`
解决方案 14:
我尝试了上面的答案,但都没有用,因为我的音频没有任何元数据。我终于在这个网站上找到了一个可行的答案。
ffmpeg -i "${file}" -f null /dev/null 2>&1 | grep -oE "[0-9]{1}:[0-9]{2}:[0-9]{2}" | tail -n 1
解决方案 15:
最佳解决方案:切断出口,得到类似00:05:03.22 的结果
ffmpeg -i input 2>&1 | grep Duration | cut -c 13-23
解决方案 16:
啊。忘掉它吧。看来我必须摆脱 C 和 C++ 编程的束缚,改用 C 和 C++。我不知道让它工作的所有 shell 技巧。
这就是我所取得的进展。
ffmpeg -i myfile 2>&1 | grep "" > textdump.txt
然后我可能会用 C++ 应用程序来提取持续时间,而不是通过提取标记。
我没有发布解决方案,因为我现在不是一个好人
更新 - 我有自己的方法来获取该持续时间时间戳
步骤 1 - 将媒体信息保存到文本文件中
ffprobe -i myfile 2>&1 | grep "" > textdump.txt
或者
ffprobe -i myfile 2>&1 | awk '{ print }' > textdump.txt
第 2 步 - 找到所需信息并提取出来
cat textdump.txt | grep "Duration" | awk '{ print $2 }' | ./a.out
注意 a.out。这是我的 C 代码,用于截断结果逗号,因为输出类似于00:00:01.331,
以下是使用 stdin 并输出所需正确信息的 C 代码。我必须将大于号和小于号取出来以供查看。
#include stdio.h
#include string.h
void main()
{
//by Admiral Smith Nov 3. 2016
char time[80];
int len;
char *correct;
scanf("%s", &time);
correct = (char *)malloc(strlen(time));
if (!correct)
{
printf("
memory error");
return;
}
memcpy(correct,&time,strlen(time)-1);
correct[strlen(time)]='/0';
printf("%s", correct);
free(correct);
}
现在输出格式正确00:00:01.33
解决方案 17:
我只需使用 C++ 和文本文件执行此操作并提取标记即可。为什么?我不像其他人一样是 Linux 终端专家。
为了进行设置,我将在 Linux 中执行此操作
ffmpeg -i <file> 2>&1 | grep "" > mytext.txt
然后运行一些 C++ 应用程序来获取所需的数据。也许提取所有重要的值并使用令牌重新格式化以便进一步处理。我只需要自己动手解决,人们会取笑我,因为我是 Linux 新手,而且我不太喜欢编写脚本。
解决方案 18:
你可以尝试这个:
/*
* Determine video duration with ffmpeg
* ffmpeg should be installed on your server.
*/
function mbmGetFLVDuration($file){
//$time = 00:00:00.000 format
$time = exec("ffmpeg -i ".$file." 2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,//");
$duration = explode(":",$time);
$duration_in_seconds = $duration[0]*3600 + $duration[1]*60+ round($duration[2]);
return $duration_in_seconds;
}
$duration = mbmGetFLVDuration('/home/username/webdir/video/file.mov');
echo $duration;
解决方案 19:
ffmpeg 已被 avconv 取代:只需将 avconb 替换为 Louis Marascio 的答案即可。
avconv -i file.mp4 2>&1 | grep Duration | sed 's/Duration: (.*), start.*//g'
注:开始后需另加.*才能单独获取时间!!
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件