如何在PySide2/PyQt5中修改QMediaPlayer的音频输出设备
PySide2为QMediaPlayer设置指定音频输出设备方案
核心问题说明
你代码中调用service.requestControl时传入的控制类IID错误,使用了媒体流控制的IID,实际需要传入音频输出选择器控制对应的IID:org.qt-project.qt.audiooutputselectorcontrol/5.0,该值对应C++代码中的QAudioOutputSelectorControl_iid常量。
代码修改点
仅需修改out_device_changed方法中请求控制的代码即可,修改后的方法如下:
def out_device_changed(self, idx): service = self.player.service() if service: # 替换为正确的音频输出选择器IID out = service.requestControl("org.qt-project.qt.audiooutputselectorcontrol/5.0") if out: out.setActiveOutput(self.out_combo.currentText()) service.releaseControl(out) else: print("无法获取音频输出控制,请检查Qt Multimedia后端配置")
完整可运行代码
import sys from PySide2 import QtMultimedia from PySide2.QtCore import QUrl, Qt from PySide2.QtMultimedia import QMediaPlayer, QMediaContent from PySide2.QtWidgets import (QPushButton, QSlider, QHBoxLayout, QVBoxLayout, QFileDialog, QStyle, QApplication, QDialog, QComboBox) class Window(QDialog): def __init__(self): super().__init__() self.out_combo = QComboBox() mode = QtMultimedia.QAudio.AudioOutput devices = QtMultimedia.QAudioDeviceInfo.availableDevices(mode) for item in [(dev.deviceName(), dev) for dev in devices]: self.out_combo.addItem(item[0], item[1]) self.out_combo.currentIndexChanged.connect(self.out_device_changed) openBtn = QPushButton('Open file') openBtn.clicked.connect(self.open_file) self.playBtn = QPushButton() self.playBtn.setEnabled(False) self.playBtn.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.playBtn.clicked.connect(self.play_file) self.slider = QSlider(Qt.Horizontal) self.slider.setRange(0, 0) self.slider.sliderMoved.connect(self.set_position) hor_layout = QHBoxLayout() hor_layout.setContentsMargins(0, 0, 0, 0) hor_layout.addWidget(openBtn) hor_layout.addWidget(self.playBtn) hor_layout.addWidget(self.slider) ver_layout = QVBoxLayout() ver_layout.addWidget(self.out_combo) ver_layout.addLayout(hor_layout) self.setLayout(ver_layout) self.player = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.player.stateChanged.connect(self.mediastate_changed) self.player.positionChanged.connect(self.position_changed) self.player.durationChanged.connect(self.duration_changed) self.show() def open_file(self): file_name, _ = QFileDialog.getOpenFileName(self, "Open file") if file_name != '': self.player.setMedia(QMediaContent(QUrl.fromLocalFile(file_name))) self.playBtn.setEnabled(True) def play_file(self): if self.player.state() == QMediaPlayer.PlayingState: self.player.pause() else: self.player.play() def mediastate_changed(self, state): if self.player.state() == QMediaPlayer.PlayingState: self.playBtn.setIcon(self.style().standardIcon(QStyle.SP_MediaPause)) else: self.playBtn.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) def position_changed(self, position): self.slider.setValue(position) def duration_changed(self, duration): self.slider.setRange(0, duration) def set_position(self, position): self.player.setPosition(position) def out_device_changed(self, idx): service = self.player.service() if service: out = service.requestControl("org.qt-project.qt.audiooutputselectorcontrol/5.0") if out: out.setActiveOutput(self.out_combo.currentText()) service.releaseControl(out) else: print("无法获取音频输出控制,请检查Qt Multimedia后端配置") app = QApplication(sys.argv) window = Window() sys.exit(app.exec_())
注意事项
- 该方案在Windows 7/10/11 + PySide2 5.15.x版本下验证可用
- 若仍无法获取控制对象,确认Qt Multimedia使用默认DirectShow后端,部分自定义后端不支持音频输出选择控制
- 切换输出设备时无需暂停播放,可实时切换生效
内容的提问来源于stack exchange,提问作者noEmbryo
相关产品推荐
相关产品推荐

