如何从ffmpeg输出中提取持续时间?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6239350/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to extract duration time from ffmpeg output?
提问by Louise
To get a lot of information about a media file one can do
要获取有关媒体文件的大量信息,可以这样做
ffmpeg -i <filename>
where it will output a lot of lines, one in particular
它将输出很多行,特别是一行
Duration: 00:08:07.98, start: 0.000000, bitrate: 2080 kb/s
I would like to output only 00:08:07.98
, so I try
我只想输出00:08:07.98
,所以我尝试
ffmpeg -i file.mp4 | grep Duration| sed 's/Duration: \(.*\), start//g'
But it prints everything, and not just the length.
但它打印所有内容,而不仅仅是长度。
Even ffmpeg -i file.mp4 | grep Duration
outputs everything.
甚至ffmpeg -i file.mp4 | grep Duration
输出一切。
How do I get just the duration length?
我如何获得持续时间长度?
采纳答案by Louis Marascio
ffmpeg is writing that information to stderr
, not stdout
. Try this:
ffmpeg 正在将该信息写入 ,而stderr
不是stdout
。尝试这个:
ffmpeg -i file.mp4 2>&1 | grep Duration | sed 's/Duration: \(.*\), start//g'
Notice the redirection of stderr
to stdout
: 2>&1
注意重定向stderr
到stdout
:2>&1
EDIT:
编辑:
Your sed
statement isn't working either. Try this:
你的sed
说法也不行。尝试这个:
ffmpeg -i file.mp4 2>&1 | grep Duration | awk '{print }' | tr -d ,
回答by ManawatuHonky
You could try this:
你可以试试这个:
/*
* 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;
回答by gemelen
In case of one request parameter it is simplier to use mediainfo and its output formatting like this (for duration; answer in milliseconds)
在一个请求参数的情况下,使用 mediainfo 及其输出格式更简单(持续时间;以毫秒为单位回答)
mediainfo --Output="General;%Duration%" ~/work/files/testfiles/+h263_aac.avi
outputs
产出
24840
回答by digitalfootmark
For those who want to perform the same calculations with no additional software in Windows, here is the script for command line script:
对于那些想要在 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
Same answer posted here: How to crop last N seconds from a TS video
此处发布的相同答案:如何从 TS 视频中裁剪最后 N 秒
回答by Ivan Neeson
You can use ffprobe
:
您可以使用ffprobe
:
ffprobe -i <file> -show_entries format=duration -v quiet -of csv="p=0"
It will output the duration in seconds, such as:
它将以秒为单位输出持续时间,例如:
154.12
Adding the -sexagesimal
option will output duration as hours:minutes:seconds.microseconds:
添加该-sexagesimal
选项将输出持续时间为hours:minutes:seconds.microseconds:
00:02:34.12
回答by Saucier
From my experience many tools offer the desired data in some kind of a table/ordered structure and also offer parameters to gather specific parts of that data. This applies to e.g. smartctl, nvidia-smi and ffmpeg/ffprobe, too. Simply speaking - often there's no need to pipe data around or to open subshells for such a task.
根据我的经验,许多工具以某种表/有序结构提供所需的数据,并提供参数来收集该数据的特定部分。这也适用于例如 smartctl、nvidia-smi 和 ffmpeg/ffprobe。简单地说 - 通常不需要为这样的任务传输数据或打开子外壳。
As a consequence I'd use the right tool for the job - in that case ffprobe would return the raw duration value in seconds, afterwards one could create the desired time format on his own:
因此,我会使用正确的工具来完成这项工作 - 在这种情况下, ffprobe 将以秒为单位返回原始持续时间值,之后可以自己创建所需的时间格式:
$ ffmpeg --version
ffmpeg version 2.2.3 ...
The command may vary dependent on the version you are using.
该命令可能因您使用的版本而异。
#!/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"
An explanation:
一个解释:
"-v quiet": Don't output anything else but the desired raw data value
"-print_format": Use a certain format to print out the data
"compact=": Use a compact output format
"print_section=0": Do not print the section name
":nokey=1": do not print the key of the key:value pair
":escape=csv": escape the value
"-show_entries format=duration": Get entries of a field named duration inside a section named format
“-v quiet”:除了所需的原始数据值外,不输出任何其他内容
“-print_format”:使用某种格式打印出数据
"compact=": 使用紧凑的输出格式
“print_section=0”:不打印节名称
":nokey=1": 不打印键值对的键
":escape=csv": 转义值
“-show_entries format=duration”:获取名为格式的部分中名为持续时间的字段的条目
Reference: ffprobe man pages
参考:ffprobe 手册页
回答by muralisc
ffmpeg has been substituted by avconv: just substitute avconb to Louis Marascio's answer.
ffmpeg 已被 avconv 取代:只需将 avconb 替换为 Louis Marascio 的答案。
avconv -i file.mp4 2>&1 | grep Duration | sed 's/Duration: \(.*\), start.*//g'
Note: the aditional .* after start to get the time alone !!
注意:开始后的附加 .* 以获得单独的时间!
回答by AdmiralSmith
I would just do this in C++ with a text file and extract the tokens. Why? I am not a linux terminal expert like the others.
To set it up I would do this in Linux..
我只会在 C++ 中使用文本文件执行此操作并提取令牌。为什么?我不像其他人那样是 linux 终端专家。
要设置它,我会在 Linux 中执行此操作。
ffmpeg -i 2>&1 | grep "" > mytext.txt
ffmpeg -i 2>&1 | grep "" > mytext.txt
and then run some C++ app to get the data needed. Maybe extract all the important values and reformat it for further processing by using tokens. I will just have to work on my own solution and people will just make fun of me because I am a linux newbie and I do not like scripting too much.
然后运行一些 C++ 应用程序来获取所需的数据。也许提取所有重要值并重新格式化以使用令牌进行进一步处理。我只需要开发我自己的解决方案,人们就会取笑我,因为我是 Linux 新手,我不太喜欢编写脚本。
回答by AdmiralSmith
Argh. Forget that. It looks like I have to get the cobwebs out of my C and C++ programming and use that instead. I do not know all the shell tricks to get it to work.
This is how far I got.
啊。忘记吧。看起来我必须从我的 C 和 C++ 编程中清除蜘蛛网并使用它。我不知道让它工作的所有 shell 技巧。这是我走了多远。
ffmpeg -i myfile 2>&1 | grep "" > textdump.txt
ffmpeg -i myfile 2>&1 | grep "" > textdump.txt
and then I would probably extract the duration with a C++ app instead by extracting tokens.
然后我可能会使用 C++ 应用程序而不是通过提取令牌来提取持续时间。
I am not posting the solution because I am not a nice person right now
我没有发布解决方案,因为我现在不是一个好人
Update - I have my approach to getting that duration time stamp
更新 - 我有获取持续时间时间戳的方法
Step 1 - Get the media information on to a text file`ffprobe -i myfile 2>&1 | grep "" > textdump.txt`
OR`ffprobe -i myfile 2>&1 | awk '{ print }' > textdump.txt`
步骤 1 - 将媒体信息获取到文本文件`ffprobe -i myfile 2>&1 | grep "" > textdump.txt`
或`ffprobe -i myfile 2>&1 | awk '{ print }' > textdump.txt`
Step 2 - Home in on the information needed and extract itcat textdump.txt | grep "Duration" | awk '{ print $2 }' | ./a.out
Notice the a.out. That is my C code to chop off the resulting comma because the output is something like 00:00:01.33,
Here is the C code that takes stdin and outputs the correct information needed. I had to take the greater and less than signs out for viewing.
第 2 步 - 找到所需的信息并提取它cat textdump.txt | grep "Duration" | awk '{ print $2 }' | ./a.out
注意 a.out。这是我的 C 代码,用于截断结果逗号,因为输出类似于 00:00:01.33,
这是采用 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("\nmemory error");
return;
}
memcpy(correct,&time,strlen(time)-1);
correct[strlen(time)]='/0';
printf("%s", correct);
free(correct);
}
#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("\nmemory error");
return;
}
memcpy(correct,&time,strlen(time)-1);
correct[strlen(time)]='/0';
printf("%s", correct);
free(correct);
}
Now the output formats correctly like 00:00:01.33
现在输出格式正确,如 00:00:01.33
回答by sparsh turkane
ffmpeg -i abc.mp4 2>&1 | grep Duration | cut -d ' ' -f 4 | sed s/,//
gives output
给出输出
HH:MM:SS.milisecs
HH:MM:SS.milisecs