PyQt5 – вместо видео в QWebEngineView/QMediaPlayer вижу только серый прямоугольник (Win 10)

Рейтинг: 1Ответов: 1Опубликовано: 19.07.2025

Пилю "настольную ОС" на PyQt5. Есть два способа показать mp4‑файл:

HTML‑плеер на Chromium (QWebEngineView) - гружу локальный файл через <video>

Нативный плеер (QMediaPlayer + QVideoWidget)

Оба варианта дают одинаковый результат - серое полотно, звук молчит. Код максимально упрощён; путь к файлу 100 % верный, файл играет в обычном VLC.

VIDEO_EXTS = (".mp4", ".mov", ".avi", ".mkv")

class HTMLVideoPlayer(QWidget):
    def __init__(self, path):
        super().__init__(None, Qt.FramelessWindowHint | Qt.Tool)
        self.resize(900, 560)
        view = QWebEngineView(self)
        html = f"""
        <video controls autoplay style="width:100%;height:100%">
            <source src="file:///{path.replace('\\', '/')}" type="video/mp4">
        </video>"""
        view.setHtml(html)

А вот нативный вариант (тот же эффект):

player   = QMediaPlayer()
widget   = QVideoWidget()
player.setVideoOutput(widget)
player.setMedia(QMediaContent(QUrl.fromLocalFile(path)))
player.play()

Логи, когда использую QMediaPlayer:

DirectShowPlayerService::doRender: Unresolved error code 0x80040266 (IDispatch error #102)

В QWebEngineView ошибок нет - только серое «тело» video‑тега.

Что пробовал

Кодеки K‑Lite / LAV Filters - не помогло.

Конвертировал видео - H.264/AAC (HandBrake, CRF 20) - без изменений.

Смотрел через ffprobe - файл валиден.

Пробовал PyQt 6.7 - та же история.

Как заставить хотя бы один из плееров нормально декодировать mp4?

Ответы

▲ 1Принят

Попробуй вот так:

from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtCore import Qt, QUrl
import os

class HTMLVideoPlayer(QWidget):
    def __init__(self, path):
        super().__init__(None, Qt.FramelessWindowHint | Qt.Tool)
        self.resize(900, 560)
        self.setWindowTitle("Video Player")

        # Сохраняем ссылку на view как self.view
        self.view = QWebEngineView(self)
        self.view.setGeometry(0, 0, self.width(), self.height()) # Важно задать геометрию

        video_url = QUrl.fromLocalFile(path).toString()

        html = f"""
        <!DOCTYPE html>
        <html>
        <head>
            <style>
                body {{ margin: 0; overflow: hidden; }}
                video {{ width: 100%; height: 100%; object-fit: contain; background-color: black; }}
            </style>
        </head>
        <body>
            <video controls autoplay>
                <source src="{video_url}" type="video/mp4">
                Ваш браузер не поддерживает тег video.
            </video>
        </body>
        </html>"""
        
        self.view.setHtml(html)

if __name__ == '__main__':
    app = QApplication([])
    
    # Замените это на реальный путь к вашему видеофайлу
    # Для примера:
    video_file_path = "C:/Users/YourUser/Videos/my_video.mp4"
    
    if not os.path.exists(video_file_path):
        print(f"Предупреждение: Видеофайл не найден по пути {video_file_path}")
        app.quit() 
    
    player = HTMLVideoPlayer(video_file_path)
    player.show()
    app.exec_()