使用ffmpeg获取python

时间:2015-06-24 11:09:59

标签: python video ffmpeg

我已经在我的电脑上使用pip ffprobe命令安装了ffprobe,并从here安装了ffmpeg。

但是,我仍然无法运行列出的代码here

我尝试使用以下代码失败。

  

SyntaxError:文件GetVideoDurations.py中的非ASCII字符'\ xe2'   在第12行,但没有声明编码;看到   http://python.org/dev/peps/pep-0263/了解详情

有谁知道什么是错的?我没有正确引用目录吗?我是否需要确保.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 个答案:

答案 0 :(得分:10)

无需迭代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]

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

希望这有帮助!

答案 1 :(得分:7)

我建议使用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))获取视频或音频文件的路径。

答案 2 :(得分:2)

基于@llogan指南并使用尖的link,使用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输出而导致的脆弱解决方案:

stderr的{​​{1}}输出不用于机器解析和 被认为是脆弱的。

我从以下文档(https://codingwithcody.com/2014/05/14/get-video-duration-with-ffmpeg-and-python/)和https://stackoverflow.com/a/6239379/2402577中获得帮助

实际上,不需要sed:ffmpeg


您可以使用以下方法以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()

答案 3 :(得分:0)

我认为Chamath的第二条评论回答了这个问题:你的剧本中有一个奇怪的角色,要么是因为你使用的是'而不是',要么你有一个非英语口音的单词,就像这样。

作为一个评论,对于你正在做的事情,你也可以尝试MoviePy解析ffmpeg输出,就像你一样(但是将来我会使用Chamath的ffprobe方法看起来更干净):

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

答案 4 :(得分:0)

我们也可以使用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']

答案 5 :(得分:0)

Python代码

      {
        val cleanF = sc.clean(f)
        new MapPartitionsRDD[U, T](this, (context, pid, iter) => iter.flatMap(cleanF))
      }

答案 6 :(得分:0)

您是否尝试添加编码?正如Chamath所说,这种错误是典型的。 将utf-8编码添加到脚本头中:

NewsCategory

答案 7 :(得分:0)

我喜欢用 ffmpeg 构建一个共享库,并在 python 中加载它。
C++代码:

#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 程序中运行良好。