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

Swift中用UISlider+MPVolumeView调音量遇[MediaRemote]错误求助

自定义UISlider调节YouTube视频音量问题排查

我在ViewController中尝试用自定义UISlider调节YouTube视频的音量,采用MPVolumeView方案后,调试区出现[MediaRemote] No local output device available错误,以下是我的代码,求找出问题:

lazy var soundSlider: UISlider = {
    let slider = UISlider()
    slider.minimumTrackTintColor = .white
    slider.maximumTrackTintColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 0.7)
    slider.setThumbImage(UIImage(named: "Round_Thumb_VolumeBar"), for: .normal)
    slider.translatesAutoresizingMaskIntoConstraints = false
    
    slider.addTarget(self, action: #selector(handleVolumeSliderChange), for: .valueChanged)
    
    return slider
}()

@objc func handleVolumeSliderChange() {
    print(soundSlider.value)
    
    MPVolumeView.setVolume(soundSlider.value)
}

override func viewDidLoad() {
    super.viewDidLoad()

    view.addSubview(soundSlider)

    soundSlider.leadingAnchor.constraint(equalTo: soundMinButton.trailingAnchor, constant: 10).isActive = true
    soundSlider.trailingAnchor.constraint(equalTo: soundMaxButton.leadingAnchor, constant: -10).isActive = true
    soundSlider.topAnchor.constraint(equalTo: pausePlayButton.bottomAnchor, constant: 43).isActive = true
}

extension MPVolumeView {
static func setVolume(_ volume: Float) {
    
    let volumeView = MPVolumeView()
    let volumeSlider = volumeView.subviews.first(where: { $0 is UISlider }) as? UISlider
    
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.01) {
        volumeSlider?.value = volume
    }
    
}
}

问题原因及修复方案

1. MPVolumeView使用错误

你在静态方法中每次创建新的MPVolumeView实例,但从未将其添加到视图层级。MPVolumeView需要被添加到视图(即使隐藏)才能让系统正确识别音频输出设备,否则会抛出设备不可用的错误。

修复代码:

// 在ViewController中添加全局MPVolumeView实例
private let volumeView = MPVolumeView()

lazy var soundSlider: UISlider = {
    let slider = UISlider()
    slider.minimumTrackTintColor = .white
    slider.maximumTrackTintColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 0.7)
    slider.setThumbImage(UIImage(named: "Round_Thumb_VolumeBar"), for: .normal)
    slider.translatesAutoresizingMaskIntoConstraints = false
    
    slider.addTarget(self, action: #selector(handleVolumeSliderChange), for: .valueChanged)
    
    return slider
}()

@objc func handleVolumeSliderChange() {
    print(soundSlider.value)
    // 使用已初始化的volumeView实例获取滑块
    if let systemVolumeSlider = volumeView.subviews.first(where: { $0 is UISlider }) as? UISlider {
        systemVolumeSlider.value = soundSlider.value
    }
}

override func viewDidLoad() {
    super.viewDidLoad()

    // 将MPVolumeView添加到视图并隐藏
    volumeView.isHidden = true
    view.addSubview(volumeView)
    
    view.addSubview(soundSlider)
    // 原有约束代码不变
    soundSlider.leadingAnchor.constraint(equalTo: soundMinButton.trailingAnchor, constant: 10).isActive = true
    soundSlider.trailingAnchor.constraint(equalTo: soundMaxButton.leadingAnchor, constant: -10).isActive = true
    soundSlider.topAnchor.constraint(equalTo: pausePlayButton.bottomAnchor, constant: 43).isActive = true
}

// 移除原有的MPVolumeView扩展

2. 优先使用YouTube播放器原生API

如果你使用的是官方YTPlayerView,直接调节系统音量并非最优解,应该调用播放器自身的音量控制方法,这样更贴合YouTube视频的播放逻辑:

// 假设你有YTPlayerView实例
@IBOutlet weak var youtubePlayer: YTPlayerView!

@objc func handleVolumeSliderChange() {
    // 将UISlider的0-1值转为YTPlayer的0-100音量范围
    let targetVolume = Int(soundSlider.value * 100)
    youtubePlayer.setVolume(targetVolume)
}

3. 额外注意点

  • 模拟器可能会出现设备检测错误,建议用真机测试。
  • iOS 13+系统中,直接修改系统音量可能受系统限制,若需调节系统音量,也可考虑使用AVAudioSession的相关API,但需注意权限配置。

内容的提问来源于stack exchange,提问作者iOS Swift-man Junior

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 20:48:19