如何从 ffmpeg 输出中提取持续时间?

2024-10-12 10:28:00
admin
原创
87
摘要:问题描述:要获取有关媒体文件的大量信息,可以这样做ffmpeg -i <filename> 它会输出很多行,特别是其中一行Duration: 00:08:07.98, start: 0.000000, bitrate: 2080 kb/s 我只想输出00:08:07.98,所以我尝试ffm...

问题描述:

要获取有关媒体文件的大量信息,可以这样做

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'

注意重定向stderrstdout2>&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:

这是我使用ffmpegawk的非常简单的解决方案。 的输出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'

注:开始后需另加.*才能单独获取时间!!

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用