我已经在我的电脑上使用 pip ffprobe 命令安装了 ffprobe,并从这里安装了 ffmpeg。
但是,我在运行here列出的代码时仍然遇到问题。
我尝试使用以下代码未成功。
SyntaxError: Non-ASCII character '\xe2' in file GetVideoDurations.py
on line 12, but no encoding declared; see
http://python.org/dev/peps/pep-0263/ for details
有谁知道出了什么问题吗? 我没有正确引用目录吗? 我需要确保
.py
和视频文件位于特定位置吗?
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]
fileToWorkWith = 'C:\Users\PC\Desktop\Video.mkv'
getLength(fileToWorkWith)
如果问题有些基本,我们深表歉意。 我所需要的只是能够迭代一组视频文件并获取它们的开始时间和结束时间。
谢谢!
无需迭代
FFprobe
的输出。有一个简单的命令,它仅返回输入文件的持续时间:
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 <input_video>
您可以使用以下方法来获取持续时间:
def get_length(input_video):
result = subprocess.run(['ffprobe', '-v', 'error', '-show_entries', 'format=duration', '-of', 'default=noprint_wrappers=1:nokey=1', input_video], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
return float(result.stdout)
查马斯给出的答案非常接近,但最终对我来说失败了。
请注意,我正在使用 Python 3.5 和 3.6,这对我有用。
import subprocess
def get_duration(file):
"""Get the duration of a video using ffprobe."""
cmd = 'ffprobe -i {} -show_entries format=duration -v quiet -of csv="p=0"'.format(file)
output = subprocess.check_output(
cmd,
shell=True, # Let this run in the shell
stderr=subprocess.STDOUT
)
# return round(float(output)) # ugly, but rounds your seconds up or down
return float(output)
如果您想将此函数放入类中并在 Django (1.8 - 1.11) 中使用它,只需更改一行并将此函数放入您的类中,如下所示:
def get_duration(file):
至:
def get_duration(self, file):
在本地使用相对路径对我有用,但生产服务器需要绝对路径。您可以使用 os.path.abspath(os.path.dirname(file))
获取视频或音频文件的路径。
ffprobe
链接:
import subprocess
def get_duration(input_video):
cmd = ["ffprobe", "-i", input_video, "-show_entries", "format=duration",
"-v", "quiet", "-sexagesimal", "-of", "csv=p=0"]
return subprocess.check_output(cmd).decode("utf-8").strip()
stderr
https://codingwithcody.com/2014/05/14/get-video-duration-with-ffmpeg-and-python/stderr
的
输出不适用于机器解析和 被认为是脆弱的。 我从以下文档中获得帮助(ffmpeg
)和https://stackoverflow.com/ a/6239379/2402577
其实sed是不必要的:ffmpeg -i file.mp4 2>&1 | grep -o -P "(?<=Duration: ).*?(?=,)"
您可以使用以下方法获取HH:MM:SS
格式的持续时间:
import subprocess
def get_duration(input_video):
# cmd: ffmpeg -i file.mkv 2>&1 | grep -o -P "(?<=Duration: ).*?(?=,)"
p1 = subprocess.Popen(['ffmpeg', '-i', input_video], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
p2 = subprocess.Popen(["grep", "-o", "-P", "(?<=Duration: ).*?(?=,)"], stdin=p1.stdout, stdout=subprocess.PIPE)
p1.stdout.close()
return p2.communicate()[0].decode("utf-8").strip()
两者的输出示例:
01:37:11.83
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#ifdef __WIN32__
#define LIB_CLASS __declspec(dllexport)
#else
#define LIB_CLASS
#endif
extern "C" {
#define __STDC_CONSTANT_MACROS
#include "libavformat/avformat.h"
}
extern "C" LIB_CLASS int64_t getDur(const char* url) {
AVFormatContext* pFormatContext = avformat_alloc_context();
if (avformat_open_input(&pFormatContext, url, NULL, NULL)) {
avformat_free_context(pFormatContext);
return -1;
}
int64_t t = pFormatContext->duration;
avformat_close_input(&pFormatContext);
avformat_free_context(pFormatContext);
return t;
}
然后使用gcc编译,得到共享库。Python代码:
from ctypes import *
lib = CDLL('/the/path/to/your/library')
getDur = lib.getDur
getDur.restype = c_longlong
duration = getDur('the path/URL to your file')
它在我的Python程序中运行良好。
ffmpeg.probe
返回的元数据错误的情况。如果您遇到同样的问题,请使用以下命令获取真实的持续时间:
probe = ffmpeg.probe(filepath, show_packets=None)
duration = float(probe['packets'][-1]['dts_time'])
<code>
cmnd = ['/root/bin/ffmpeg', '-i', videopath]
process = subprocess.Popen(cmnd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout, stderr = process.communicate()
#This matches regex to get the time in H:M:S format
matches = re.search(r"Duration:\s{1}(?P<hours>\d+?):(?P<minutes>\d+?):(?P<seconds>\d+\.\d+?),", stdout, re.DOTALL).groupdict()
t_hour = matches['hours']
t_min = matches['minutes']
t_sec = matches['seconds']
t_hour_sec = int(t_hour) * 3600
t_min_sec = int(t_min) * 60
t_s_sec = int(round(float(t_sec)))
total_sec = t_hour_sec + t_min_sec + t_s_sec
#This matches1 is to get the frame rate of a video
matches1 = re.search(r'(\d+) fps', stdout)
frame_rate = matches1.group(0) // This will give 20fps
frame_rate = matches1.group(1) //It will give 20
</code>
要安装 ffmpeg,请按照此
链接
import subprocess
import re
process = subprocess.Popen(['ffmpeg', '-i', path_of_video_file], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout, stderr = process.communicate()
matches = re.search(r"Duration:\s{1}(?P<hours>\d+?):(?P<minutes>\d+?):(?P<seconds>\d+\.\d+?),", stdout, re.DOTALL).groupdict()
print (matches['hours'])
print (matches['minutes'])
print (matches['seconds'])