我从 coursera.org 下载了一堆视频,并将它们存储在一个特定的文件夹中。特定文件夹中有许多单独的视频(Coursera 将一个讲座分成多个短视频)。我想要一个 python 脚本,它给出特定目录中所有视频的总长度。视频文件为 .mp4 格式。
5 回答
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 版本,请检查此答案的编辑历史记录。
- 下载MediaInfo并安装(不要安装捆绑的广告软件)
- 转到MediaInfo 源下载并在“源代码,全部包含”行中,选择“libmediainfo”旁边的链接
MediaInfoDLL3.py
在下载的存档中查找并将其解压缩到任何地方。示例位置:libmediainfo_0.7.62_AllInclusive.7z\MediaInfoLib\Source\MediaInfoDLL\MediaInfoDLL3.py
- 现在在同一目录中制作一个用于测试的脚本(以下来源)。
- 执行脚本。
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")
除了上面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 中工作
如今pymediainfo可用,因此可以简化 Janus Troelsen 的答案。
您需要安装MediaInfo和pip 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')))
此链接显示如何获取视频文件的长度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))