5

我从 coursera.org 下载了一堆视频,并将它们存储在一个特定的文件夹中。特定文件夹中有许多单独的视频(Coursera 将一个讲座分成多个短视频)。我想要一个 python 脚本,它给出特定目录中所有视频的总长度。视频文件为 .mp4 格式。

4

5 回答 5

7

首先,安装ffprobe命令(它是FFmpeg的一部分)

sudo apt install ffmpeg

然后使用subprocess.run()运行这个 bash 命令:

ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 -- <filename>

(我从http://trac.ffmpeg.org/wiki/FFprobeTips#Formatcontainerduration得到),像这样:

from pathlib import Path
import subprocess

def video_length_seconds(filename):
    result = subprocess.run(
        [
            "ffprobe",
            "-v",
            "error",
            "-show_entries",
            "format=duration",
            "-of",
            "default=noprint_wrappers=1:nokey=1",
            "--",
            filename,
        ],
        capture_output=True,
        text=True,
    )
    try:
        return float(result.stdout)
    except ValueError:
        raise ValueError(result.stderr.rstrip("\n"))

# a single video
video_length_seconds('your_video.webm')

# all mp4 files in the current directory (seconds)
print(sum(video_length_seconds(f) for f in Path(".").glob("*.mp4")))

# all mp4 files in the current directory and all its subdirectories
# `rglob` instead of `glob`
print(sum(video_length_seconds(f) for f in Path(".").rglob("*.mp4")))

# all files in the current directory
print(sum(video_length_seconds(f) for f in Path(".").iterdir() if f.is_file()))

此代码需要Python 3.7+text=,因为那capture_output=是添加到subprocess.run. 如果您使用的是较旧的 Python 版本,请检查此答案的编辑历史记录。

于 2014-09-15T07:05:49.370 回答
3
  1. 下载MediaInfo并安装(不要安装捆绑的广告软件)
  2. 转到MediaInfo 源下载并在“源代码,全部包含”行中,选择“libmediainfo”旁边的链接
  3. MediaInfoDLL3.py在下载的存档中查找并将其解压缩到任何地方。示例位置:libmediainfo_0.7.62_AllInclusive.7z\MediaInfoLib\Source\MediaInfoDLL\MediaInfoDLL3.py
  4. 现在在同一目录中制作一个用于测试的脚本(以下来源)。
  5. 执行脚本。

MediaInfo 也适用于 POSIX。唯一的区别是so加载的是 an 而不是 DLL。

测试脚本(Python 3!)

import os

os.chdir(os.environ["PROGRAMFILES"] + "\\mediainfo")
from MediaInfoDLL3 import MediaInfo, Stream

MI = MediaInfo()

def get_lengths_in_milliseconds_of_directory(prefix):
  for f in os.listdir(prefix):
    MI.Open(prefix + f)
    duration_string = MI.Get(Stream.Video, 0, "Duration")

    try:
      duration = int(duration_string)
      yield duration
      print("{} is {} milliseconds long".format(f, duration))
    except ValueError:
      print("{} ain't no media file!".format(f))

    MI.Close()

print(sum(get_lengths_in_milliseconds_of_directory(os.environ["windir"] + "\\Performance\\WinSAT\\"
)), "milliseconds of content in total")
于 2013-02-23T17:38:31.697 回答
2

除了上面Janus Troelsen的回答,我想指出我在实施他的回答时遇到的一个小问题。我一一按照他的指示,但在 windows (7) 和 linux (ubuntu) 上得到了不同的结果。他的指令在 linux 下运行良好,但我必须做一个小技巧才能让它在 Windows 上运行。我在 Windows 上使用 32 位 python 2.7.2 解释器,所以我使用了 MediaInfoDLL.py。但这还不足以让它为我工作,我在这个过程中收到了这个错误:

“WindowsError:[错误 193] %1 不是有效的 Win32 应用程序”。

这意味着我以某种方式使用了不是 32 位的资源,它必须是正在加载的 DLL MediaInfoDLL.py。如果查看 MediaInfo 安装目录,您将看到 3 个 dll MediaInfo.dll 是 64 位的,而 MediaInfo_i386.dll 是 32 位的。由于我的 python 设置,MediaInfo_i386.dll 是我必须使用的。我去了 MediaInfoDLL.py(我已经包含在我的项目中)并更改了这一行:

MediaInfoDLL_Handler = windll.MediaInfo

MediaInfoDLL_Handler = WinDLL("C:\Program Files (x86)\MediaInfo\MediaInfo_i386.dll")

我不需要改变任何东西就可以在 linux 中工作

于 2013-08-07T22:40:56.633 回答
1

如今pymediainfo可用,因此可以简化 Janus Troelsen 的答案。
您需要安装MediaInfopip install pymediainfo. 然后以下代码将打印所有视频文件的总长度:

import os
from pymediainfo import MediaInfo

def get_track_len(file_path):
    media_info = MediaInfo.parse(file_path)
    for track in media_info.tracks:
        if track.track_type == "Video":
            return int(track.duration)
    return 0
    
print(sum(get_track_len(f) for f in os.listdir('directory with video files')))

于 2021-01-06T21:52:56.457 回答
0

此链接显示如何获取视频文件的长度https://stackoverflow.com/a/3844467/735204

import subprocess

def getLength(filename):
  result = subprocess.Popen(["ffprobe", filename],
    stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
  return [x for x in result.stdout.readlines() if "Duration" in x]

如果您正在使用该功能,则可以使用类似的东西将其包装起来

import os

for f in os.listdir('.'):
    print "%s: %s" % (f, getLength(f))
于 2013-02-23T13:59:29.460 回答