【发布时间】:2018-05-07 08:23:45
【问题描述】:
[更新:] 是的,有可能,现在大约 20 个月后。请参阅下面的更新 3! [/更新]
这真的不可能吗?我能找到的只是调用 FFmpeg(或其他软件)的变体。我当前的解决方案如下所示,但我真正想要的可移植性是一个纯 Python 解决方案,不需要用户安装额外的软件。
毕竟,我可以使用 PyQt 的 Phonon 轻松播放视频,但我不能简单地获得视频的尺寸或持续时间等信息?
我的解决方案使用 ffmpy (http://ffmpy.readthedocs.io/en/latest/ffmpy.html),它是 FFmpeg 和 FFprobe (http://trac.ffmpeg.org/wiki/FFprobeTips) 的包装器。比其他产品更流畅,但仍需要额外安装 FFmpeg。
import ffmpy, subprocess, json
ffprobe = ffmpy.FFprobe(global_options="-loglevel quiet -sexagesimal -of json -show_entries stream=width,height,duration -show_entries format=duration -select_streams v:0", inputs={"myvideo.mp4": None})
print("ffprobe.cmd:", ffprobe.cmd) # printout the resulting ffprobe shell command
stdout, stderr = ffprobe.run(stderr=subprocess.PIPE, stdout=subprocess.PIPE)
# std* is byte sequence, but json in Python 3.5.2 requires str
ff0string = str(stdout,'utf-8')
ffinfo = json.loads(ff0string)
print(json.dumps(ffinfo, indent=4)) # pretty print
print("Video Dimensions: {}x{}".format(ffinfo["streams"][0]["width"], ffinfo["streams"][0]["height"]))
print("Streams Duration:", ffinfo["streams"][0]["duration"])
print("Format Duration: ", ffinfo["format"]["duration"])
输出结果:
ffprobe.cmd: ffprobe -loglevel quiet -sexagesimal -of json -show_entries stream=width,height,duration -show_entries format=duration -select_streams v:0 -i myvideo.mp4
{
"streams": [
{
"duration": "0:00:32.033333",
"width": 1920,
"height": 1080
}
],
"programs": [],
"format": {
"duration": "0:00:32.064000"
}
}
Video Dimensions: 1920x1080
Streams Duration: 0:00:32.033333
Format Duration: 0:00:32.064000
更新 经过几天的实验:下面 Nick 提出的 hachoire 解决方案确实有效,但会给您带来很多麻烦,因为 hachoire 的响应太不可预测了。不是我的选择。
使用 opencv 编码再简单不过了:
import cv2
vid = cv2.VideoCapture( picfilename)
height = vid.get(cv2.CAP_PROP_FRAME_HEIGHT) # always 0 in Linux python3
width = vid.get(cv2.CAP_PROP_FRAME_WIDTH) # always 0 in Linux python3
print ("opencv: height:{} width:{}".format( height, width))
问题是它在 Python2 上运行良好,但在 Py3 上却不行。引用:“重要提示:MacOS 和 Linux 软件包不支持视频相关功能(未使用 FFmpeg 编译)” (https://pypi.python.org/pypi/opencv-python)。
除此之外,opencv 似乎需要在运行时存在 FFmeg 的二进制包 (https://docs.opencv.org/3.3.1/d0/da7/videoio_overview.html)。
好吧,如果我仍然需要安装 FFmpeg,我可以坚持上面显示的原始 ffmpy 示例:-/
感谢您的帮助。
UPDATE2: master_q(见下文)建议 MediaInfo。虽然这无法在我的 Linux 系统上运行(请参阅我的 cmets),但使用 pymediainfo(MediaInfo 的 py 包装器)的替代方法确实有效。使用简单,但是比我最初的 ffprobe 方法获取时长、宽度和高度的时间要长 4 倍,并且仍然需要外部软件,即 MediaInfo:
from pymediainfo import MediaInfo
media_info = MediaInfo.parse("myvideofile")
for track in media_info.tracks:
if track.track_type == 'Video':
print("duration (millisec):", track.duration)
print("width, height:", track.width, track.height)
UPDATE3: OpenCV 终于可用于 Python3,并声称可以在 Linux、Win 和 Mac 上运行!它真的很容易,而且我证实不需要外部软件 - 特别是 ffmpeg!
首先通过 Pip 安装 OpenCV:
pip install opencv-python
在 Python 中运行:
import cv2
cv2video = cv2.VideoCapture( videofilename)
height = cv2video.get(cv2.CAP_PROP_FRAME_HEIGHT)
width = cv2video.get(cv2.CAP_PROP_FRAME_WIDTH)
print ("Video Dimension: height:{} width:{}".format( height, width))
framecount = cv2video.get(cv2.CAP_PROP_FRAME_COUNT )
frames_per_sec = cv2video.get(cv2.CAP_PROP_FPS)
print("Video duration (sec):", framecount / frames_per_sec)
# equally easy to get this info from images
cv2image = cv2.imread(imagefilename, flags=cv2.IMREAD_COLOR )
height, width, channel = cv2image.shape
print ("Image Dimension: height:{} width:{}".format( height, width))
我还需要视频的第一帧作为图像,并为此使用 ffmpeg 将图像保存在文件系统中。使用 OpenCV 也更容易:
hasFrames, cv2image = cv2video.read() # reads 1st frame
cv2.imwrite("myfilename.png", cv2image) # extension defines image type
但更好的是,由于我只需要内存中的图像才能在 PyQt5 工具包中使用,我可以直接将 cv2-image 读入 Qt-image:
bytesPerLine = 3 * width
# my_qt_image = QImage(cv2image, width, height, bytesPerLine, QImage.Format_RGB888) # may give false colors!
my_qt_image = QImage(cv2image.data, width, height, bytesPerLine, QImage.Format_RGB888).rgbSwapped() # correct colors on my systems
由于 OpenCV 是一个庞大的程序,我担心时间问题。事实证明,OpenCV 从未落后于替代方案。我需要大约 100 毫秒来阅读一张幻灯片,其余的时间加起来不会超过 10 毫秒。
我在 Ubuntu Mate 16.04、18.04 和 19.04 以及两个不同的 Windows 10 Pro 安装上成功测试了这一点。 (没有可用的 Mac)。我对 OpenCV 感到非常高兴!
您可以在我的 SlideSorter 程序中看到它的运行情况,该程序允许对图像和视频进行排序、保留排序顺序并以幻灯片形式呈现。在这里可用:https://sourceforge.net/projects/slidesorter/
【问题讨论】:
-
你是说不想使用pyqt4?你可以使用Phonon.MediaObject.metaData
-
如果您使用的是 Windows,请参阅this question。
-
我在 Linux 上,但希望看到一些跨平台的东西。
-
我已经在使用 PyQt4,所以自然会利用它。但就可以看到元数据有很多,嗯,元数据,但没有像宽度、高度和持续时间那样平凡(xiph.org/vorbis/doc/v-comment.html)。 'Phonon.VideoPlayer()' 易于使用且运行良好,但我找不到任何我正在寻找的信息。
标签: python opencv video ffmpeg pyqt5