2015-06-24 123 views
2

我已经在PC上使用pip ffprobe命令安装了ffprobe,并从here安装了ffmpeg。使用ffmpeg获取python中的视频持续时间

但是,我仍然无法运行列出的代码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) 

道歉,如果问题是有点基本。我所需要的就是能够遍历一组视频文件并获得它们的开始时间和结束时间。

谢谢!

回答

8

有没有必要迭代FFprobe的输出。有一个简单的命令只导致输入文件的持续时间。

ffprobe -i input_audio -show_entries format=duration -v quiet -of csv="p=0" 

您可以使用下面的方法来获得持续时间。

def getLength(input_video): 
    result = subprocess.Popen('ffprobe -i input_video -show_entries format=duration -v quiet -of csv="p=0"', stdout=subprocess.PIPE,stderr=subprocess.STDOUT) 
    output = result.communicate() 
    return output[0] 

此外,您需要提供每个文件的绝对路径。

希望这有助于!

+0

谢谢Chamath。我会在哪里使用第一个命令?另外,当我运行你的方法时,我仍然遇到同样的错误。 – OSK

+1

第一条命令是我们在python中用'Popen'执行的命令行FFprobe命令。你的错误令人困惑。你的命令中的“第12行”在哪里?您需要包含完整的python脚本。还要记住反斜杠是一个转义字符,您可能需要使用\\而不是\\ – Chamath

+0

第二行应该是'result = subprocess.Popen(['ffprobe -i%s -show_entries format = duration -v quiet -of csv =“p = 0”'%input_video],stdout = subprocess.PIPE,stderr = subprocess.STDOUT)',它会给出一个没有方括号的错误。 –

0

我认为Chamath的第二个评论回答了这样一个问题:你的脚本中某处存在一个奇怪的角色,或者是因为你使用了'而不是'或者你有一个非英语口音的词,就像这样。

这样的话,你正在做的,你也可以尝试MoviePy其分析ffmpeg的输出像你这样(但也许将来我会用Chamath的ffprobe方法,它看起来更清洁)什么:

import moviepy.editor as mp 
duration = mp.VideoFileClip("my_video.mp4").duration 
1

我们也可以使用ffmpeg来获取任何视频或音频文件的持续时间。

要安装的ffmpeg按照这个link

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'] 
+0

解析来自'ffmpeg'的输出是脆弱的,不能被脚本使用。如[Chamath的答案](http://stackoverflow.com/a/31025482/1109017)中所示,使用'ffprobe'来代替。 – LordNeckbeard

1

Python代码

<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> 
+0

解析来自'ffmpeg'的输出是脆弱的,不能被脚本使用。如[Chamath的答案](http://stackoverflow.com/a/31025482/1109017)中所示,使用'ffprobe'来代替。 – LordNeckbeard

1

我建议使用FFprobe(自带FFmpeg的)。

Chamath给出的答案非常接近,但最终失败了。

就像一个笔记,我使用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))获取视频或音频文件的路径。

相关问题