You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySide6 中如何使用 Qt Multimedia 6.2 实现无间隙循环视频播放

Qt 6.2 QML 平滑视频循环播放解决方案

Qt6 已正式移除 Qt5 时期的 flushMode 属性,针对你遇到的重播清屏间隙问题,以下两种纯 QML 实现方案均兼容 PySide6 环境,无需修改 Python 层逻辑。


方案1:双播放器预加载切换(效果最优)

原理为两个 MediaPlayer 轮流预加载待命,当前播放器即将结束时直接切换到已缓冲好第一帧的备用播放器,完全规避清屏间隙。

import QtQuick
import QtMultimedia

Rectangle {
    id: playVid2
    anchors.fill: parent

    property string videoSource: "media/video/2.mp4"
    property int activePlayer: 1 // 标记当前活跃的播放器

    // 播放器1
    MediaPlayer {
        id: mp1
        audioOutput: AudioOutput{}
        source: videoSource
        onPlaybackStateChanged: {
            if (playbackState == MediaPlayer.EndOfMedia) {
                stop()
                position = 0 // 重置到开头待命
            }
        }
        // 播放到剩余100ms时触发切换,阈值可根据视频实际情况调整
        onPositionChanged: {
            if (duration > 0 && position >= duration - 100 && activePlayer == 1) {
                activePlayer = 2
                mp2.play()
            }
        }
    }

    // 播放器2
    MediaPlayer {
        id: mp2
        audioOutput: AudioOutput{}
        source: videoSource
        onPlaybackStateChanged: {
            if (playbackState == MediaPlayer.EndOfMedia) {
                stop()
                position = 0
            }
        }
        onPositionChanged: {
            if (duration > 0 && position >= duration - 100 && activePlayer == 2) {
                activePlayer = 1
                mp1.play()
            }
        }
    }

    VideoOutput {
        id: voVid2
        anchors.fill: parent
        fillMode: VideoOutput.PreserveAspectCrop
        source: activePlayer == 1 ? mp1 : mp2 // 动态绑定活跃播放器输出
    }

    Component.onCompleted: {
        // 初始化时预加载两个播放器到首帧
        mp1.position = 0
        mp2.position = 0
        mp1.play()
    }
}

该方案仅会增加少量内存占用,对常规背景视频场景无性能压力。


方案2:单播放器手动跳转(资源占用低)

原理为禁用自带的循环属性,在视频播放到末尾前手动触发跳转,避免进入 EndOfMedia 状态触发清屏逻辑。

import QtQuick
import QtMultimedia

Rectangle {
    id: playVid2
    anchors.fill: parent

    MediaPlayer {
        id: mpVid2
        audioOutput: AudioOutput{}
        videoOutput: voVid2
        source: "media/video/2.mp4"
        loops: 1 // 不要使用自带的无限循环属性
        // 剩余50ms时跳转到开头重播,阈值可调整
        onPositionChanged: {
            if (duration > 0 && position >= duration - 50) {
                position = 0
                play()
            }
        }
    }

    VideoOutput {
        id: voVid2
        anchors.fill: parent
        fillMode: VideoOutput.PreserveAspectCrop
    }

    Component.onCompleted: mpVid2.play()
}

使用该方案需注意两点:

  • 视频首帧需设置为关键帧,避免跳转后出现短暂花屏
  • 跳转阈值可根据视频帧率调整,推荐范围10-100ms,不要等视频完全播放结束再操作

内容的提问来源于stack exchange,提问作者Seifu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 13:15:04