python - 如何使用 Python 和 PyQt5 制作 VLC 缩放视频以填充窗口?
问题描述
所以我在 MacOS 上为 VLC 使用 python 绑定模块,使用 PyQt5 来渲染窗口。
当我使用 VLC GUI 时,它完全符合您在扩展窗口时所期望的功能,缩放视频以适应窗口,即使视频的分辨率低于窗口也是如此。
使用 python-vlc 模块,没有那么多。即使它是用--autoscale
选项实例化的。
在全屏模式下,视频仅占窗口左下角屏幕的 1/4 左右。在非全屏模式下,视频只有在手动调整窗口大小后才会缩放到窗口,然后最终恢复为非缩放。
我的目标是让视频窗口保留原始视频的纵横比并拉伸以填充屏幕,并在必要时进行裁剪。
我错过了什么选项或神秘方法?该文档似乎不存在。或者这实际上是我缺少的 pyqt 选项?
原谅冗长的代码摘录。vlc 和 pyqt 实例化有很多特殊之处,我看不到另一种方法可以向您展示我在做什么。
"""
This module contains a bare-bones VLC player class to play videos.
Adapted from an example by Saveliy Yusufov, Columbia University, sy2685@columbia.edu
"""
import os
import sys
import platform
from PyQt5 import QtWidgets, QtGui, QtCore
import vlc
class Player(QtWidgets.QMainWindow):
"""Stripped-down PyQt5-based media player class
"""
def __init__(self, master=None):
QtWidgets.QMainWindow.__init__(self, master)
self.media_files = [
"data/Tv Static Noise HD 720p.mp4",
"data/070_SHARP_Titles_Flower_Titles.mp4",
"data/072_SHARP_Footage_Shantyboat_Flyby_Titles.mp4",
"data/1900 Victorian Time Machine - Parade with Brass Bands (Speed Corrected w_ Sound).mp4"
]
self.current_index = 0
# PyQy prep stuff
#
# set fullscreen mode (we could do this after the object, but let's do this early)
#
# in fullscreen mode, videos show up in the bottom left corner
self.showFullScreen()
#
# in this window, videos are scaled only when window is manually resized
#self.resize(680, 420)
#
self.init_ui()
# VLC prep stuff
#
# VLC Options
vlc_options = [
"--embedded-video",
"--no-audio",
"--autoscale",
"--fullscreen",
"--video-on-top",
"--no-video-title-show",
"--random",
"--verbose -1",
"--canvas-aspect 3:4",
"--no-canvas-padd"
]
# Create a basic vlc instance
self.instance = vlc.Instance(" ".join(vlc_options))
# later used to store media object, for now blank
self.media = None
# Create an empty vlc media player
self.player = self.instance.media_player_new()
# self.mediaplayer = vlc.MediaPlayer()
# Set to fullscreen
#self.player.set_fullscreen(True)
#
# The media player has to be 'connected' to the QFrame (otherwise the
# video would be displayed in it's own window). This is platform
# specific, so we must give the ID of the QFrame (or similar object) to
# vlc. Different platforms have different functions for this
if platform.system() == "Linux": # for Linux using the X Server
self.player.set_xwindow(int(self.videoframe.winId()))
elif platform.system() == "Windows": # for Windows
self.player.set_hwnd(int(self.videoframe.winId()))
elif platform.system() == "Darwin": # for MacOS
self.player.set_nsobject(int(self.videoframe.winId()))
# load media
self.open_file(self.media_files[self.current_index])
# create a timer to refresh video
self.timer = QtCore.QTimer(self)
self.timer.setInterval(5000)
self.timer.timeout.connect(self.next_video)
self.timer.start()
def init_ui(self):
"""Set up the user interface
"""
if platform.system() == "Darwin": # for MacOS
self.videoframe = QtWidgets.QMacCocoaViewContainer(0)
else:
self.videoframe = QtWidgets.QFrame()
# set videoframe color
self.palette = self.videoframe.palette()
self.palette.setColor(QtGui.QPalette.Window, QtGui.QColor(0, 0, 0))
self.videoframe.setPalette(self.palette)
self.videoframe.setAutoFillBackground(True)
self.setCentralWidget(self.videoframe)
def open_file(self, filename):
"""Open a media file in a MediaPlayer
"""
if not filename:
return
# getOpenFileName returns a tuple, so use only the actual file name
self.media = self.instance.media_new(filename)
# Put the media in the media player
self.player.set_media(self.media)
# Parse the metadata of the file
self.media.parse()
# Start playing the video as soon as it loads
self.player.play()
def next_video(self):
self.current_index += 1
if self.current_index >= len(self.media_files):
self.current_index = 0
self.open_file(self.media_files[self.current_index])
return
def main():
"""Entry point for our simple vlc player
"""
app = QtWidgets.QApplication(sys.argv)
player = Player()
player.show()
# _ = Client("localhost", 10000, data_queue)
sys.exit(app.exec_())
if __name__ == "__main__":
main()
理想情况下,我想制作一个从不调整大小以填充窗口/屏幕的全屏播放器。
如果您可以对 pyqt 代码进行调整以消除对 vboxlayout 的需求,则可以加分。编辑:固定。谢谢@alec
这是我在播放视频时看到的内容:
解决方案
推荐阅读
- spring-boot - thymeleaf 2.5.6 版本中使用变量表达式的方法是什么
- authentication - ADFS 作为某些 IDP 的代理
- reactjs - 我的反应网站有问题。我想在点击特定产品时弹出描述页面。但我的改变反映在所有的卡片上
- flutter - 颤振冻结基类
- windows - 如何在 Windows Subsystem for Android(WSA) 环境下将文件添加到 /sdcard/Android/obb 这个文件夹中?
- python - 如何从 JSON 文件中提取单个键值?
- sqlite - “ __conform__() 不是有效的 Streamlit 命令。”
- c++ - 使用元组和自定义排序功能从集合中删除元组
- html - 如何在html中正确缩进表格?
- c - 为什么我不能保存用户的输入?试图通过 3 双打并更新它们的尺寸