如何在调用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
相关产品推荐
相关产品推荐

