我想知道远处视频文件(比如 mp4)的持续时间。
我已经知道如何获取本地视频文件的时长:
import xml.etree.ElementTree as eltt, subprocess as spr
def size_from_fn(file_name):
size = eltt.fromstring(
spr.run(["ffprobe",
"-i", file_name,
"-show_format", "-output_format", "xml"
], stdout = spr.PIPE, stderr = spr.STDOUT).stdout.decode()
).find("format").get("duration")
return size
def size_from_fd(file_descriptor):
size = eltt.fromstring(
spr.run(["ffprobe",
"-i", "pipe:0",
"-show_format", "-output_format", "xml"
], stdin = file_descriptor, stdout = spr.PIPE, stderr = spr.STDOUT).stdout.decode()
).find("format").get("duration")
return size
def size_from_data(file_name):
size = eltt.fromstring(
spr.run(["ffprobe",
"-i", "pipe:0",
"-show_format", "-output_format", "xml"
], input = data, stdout = spr.PIPE, stderr = spr.STDOUT).stdout.decode()
).find("format").get("duration")
return size
一切运行正常
我还知道如何将 HTTP 请求作为文件描述符获取:
import requests as rq
def url_to_fd(url):
req = rq.get(url, stream = True)
return req.raw
它也有效
然而,两者的结合失败,并显示以下消息ffprobe
:Invalid data found when processing input
我不知道为什么,我只知道从 URL 返回的文件描述符的区别在于不可搜索(单向读取),但是通过替换普通文件描述符的这种方法:
with open("test.mp4", "rb") as f:
f.seek = None
size_of_fd(f)
这是有效的,因此表明ffprobe
不需要任何寻求
这样做也是可行的,所以我不知道发生了什么:
def get_duration(url):
complete_data = url_to_fd(url).read()
return size_of_data(complete_data)
我的问题是视频文件可能非常大,所以我无法下载整个视频。