如何从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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 01:02:01  来源:igfitidea点击:

How to extract duration time from ffmpeg output?

linuxbashffmpeg

提问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 Durationoutputs 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 stderrto stdout: 2>&1

注意重定向stderrstdout2>&1

EDIT:

编辑:

Your sedstatement 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 -sexagesimaloption 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 it
cat 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