在python中使用ffmpeg获取视频时长

问题描述 投票:0回答:10

我已经在我的电脑上使用 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)

如果问题有些基本,我们深表歉意。 我所需要的只是能够迭代一组视频文件并获取它们的开始时间和结束时间。

谢谢!

python video ffmpeg
10个回答
23
投票

无需迭代

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)



13
投票

查马斯给出的答案非常接近,但最终对我来说失败了。

请注意,我正在使用 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)) 获取视频或音频文件的路径。

    


13
投票
https://pypi.org/project/ffmpeg-python/

import ffmpeg duration = ffmpeg.probe(local_file_path)["format"]["duration"]

其中 
local_file_path

是文件的相对或绝对路径。

    


3
投票
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

ffmpeg
输出不适用于机器解析和 被认为是脆弱的。

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

)和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

    


2
投票

作为一个评论,对于你正在做的事情,你也可以尝试

MoviePy

,它像你一样解析 ffmpeg 输出(但也许将来我会使用 Chamath 的 ffprobe 方法,它看起来更干净): import moviepy.editor as mp duration = mp.VideoFileClip("my_video.mp4").duration



0
投票

#!/usr/bin/env python # -*- coding: utf-8 -*-



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


0
投票
ffmpeg.probe

返回的元数据错误的情况。如果您遇到同样的问题,请使用以下命令获取真实的持续时间:

probe = ffmpeg.probe(filepath, show_packets=None)
duration = float(probe['packets'][-1]['dts_time'])



-1
投票

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



-2
投票

要安装 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'])

	
© www.soinside.com 2019 - 2024. All rights reserved.