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

如何在调用set_mrl(...)函数时避免窗口重新打开?

问题:libvlc调用set_mrl时窗口重复打开,如何保持窗口始终不关闭?

问题详情

我正在使用Python 3.11及最新版libvlc开发共享屏幕自动化应用,调用set_mrl(...)函数时窗口有时会重新打开,需要保持窗口始终不关闭。我已尝试设置--play-and-pause参数,以及执行以下重新设置窗口句柄的代码,但均未解决问题:

win_id = player.get_hwnd()
player.set_hwnd(win_id)

播放器实现代码

import vlc
import typing as t
import logging
import os

_LOG = logging.getLogger("player.vlc_player")

# 关闭VLC错误输出
os.environ['VLC_VERBOSE'] = '-1'

class VlcPlayer:
    def __init__(self, stream_uri: str) -> None:
        self.stream_uri = stream_uri
        self.player: vlc.MediaPlayer = vlc.MediaPlayer(stream_uri, "--play-and-pause")
        self.player.toggle_fullscreen()
    
    def play(self) -> None:
        self.player.play()
        
    def pause(self) -> None:
        self.player.pause()

    def resume(self) -> None:
        self.player.play()
    
    def is_playing(self) -> bool:
        return self.player.is_playing()
    
    def get_stream_uri(self) -> str:
        return self.stream_uri
    
    def set_stream_uri(self, stream_uri: str) -> None:
        self.stream_uri = stream_uri
        self.player.set_mrl(stream_uri)
        self.player.play()

    def get_time(self) -> t.Union[int, t.Any]:
        return self.player.get_time()

    def set_time(self, time: int) -> None:
        self.player.set_time(time)

    def get_length(self) -> t.Union[int, t.Any]:
        return self.player.get_length()

    def get_volume(self) -> t.Union[int, t.Any]:
        return self.player.audio_get_volume()

    def set_volume(self, volume: int) -> None:
        self.player.audio_set_volume(volume)

    def stop(self) -> None:
        self.player.stop()

使用示例代码

import time

player = VlcPlayer("./images/wating.jpg")

time.sleep(10)
player.set_stream_uri("some url")

time.sleep(1000)

解决方案

核心修复:改用Media对象切换流,避免直接调用set_mrl

直接调用set_mrl会触发libvlc销毁当前窗口上下文并重建,导致窗口重启。正确做法是创建新的vlc.Media对象,通过set_media关联到现有播放器,保留原窗口实例:

def set_stream_uri(self, stream_uri: str) -> None:
    self.stream_uri = stream_uri
    # 创建新Media对象
    media = vlc.Media(stream_uri)
    # 关联到现有播放器
    self.player.set_media(media)
    self.player.play()

兜底优化:切换媒体后重新绑定窗口句柄

如果上述方法仍有异常,可在切换前保存窗口句柄,设置新媒体后重新绑定,强制复用原窗口:

def set_stream_uri(self, stream_uri: str) -> None:
    self.stream_uri = stream_uri
    # 保存当前窗口句柄
    win_id = self.player.get_hwnd()
    # 创建并设置新Media
    media = vlc.Media(stream_uri)
    self.player.set_media(media)
    # 重新绑定窗口句柄
    self.player.set_hwnd(win_id)
    self.player.play()

初始化逻辑优化

初始化播放器时,建议先创建空实例再绑定初始媒体,避免启动阶段的窗口异常:

def __init__(self, stream_uri: str) -> None:
    self.stream_uri = stream_uri
    # 先创建空播放器实例并传入参数
    self.player: vlc.MediaPlayer = vlc.MediaPlayer("--play-and-pause")
    # 绑定初始媒体
    initial_media = vlc.Media(stream_uri)
    self.player.set_media(initial_media)
    self.player.toggle_fullscreen()
    self.player.play()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 23:03:07