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

iOS通知栏自定义音频播放器控件:URL流式播放及通知控制实现

我来帮你搞定iOS通知栏的媒体控件问题!要实现像Gaana、Saavn那样的通知栏播放控制,你需要用到Apple的几个核心框架:AVFoundation(处理音频播放)和MediaPlayer(负责通知栏控件和远程命令响应)。下面是一步步的实现指南:

1. 先配置音频会话,确保后台播放权限

iOS需要知道你的App的音频用途,才能允许后台播放并显示通知控件。首先要做这两步:

  • 导入AVFoundation框架,然后在App启动或者播放前配置音频会话:
import AVFoundation

func setupAudioSession() {
    let audioSession = AVAudioSession.sharedInstance()
    do {
        // 设置类别为.playback,支持后台播放、锁屏播放
        try audioSession.setCategory(.playback, mode: .default)
        try audioSession.setActive(true)
    } catch {
        print("音频会话配置失败: \(error.localizedDescription)")
    }
}
  • 修改Info.plist添加后台模式:添加Required background modes项,勾选App plays audio or streams audio/video using AirPlay,这样App在后台也能持续播放音频。
2. 用MPRemoteCommandCenter处理通知栏的控制命令

这个类专门负责处理通知栏、锁屏甚至耳机线控的播放指令,你需要给每个操作(播放、暂停、下一曲、快退)绑定响应逻辑:

  • 导入MediaPlayer框架,然后初始化命令中心并添加事件监听:
import MediaPlayer

func setupRemoteCommands() {
    let commandCenter = MPRemoteCommandCenter.shared()
    
    // 播放命令响应
    commandCenter.playCommand.addTarget { [weak self] _ in
        self?.audioPlayer?.play()
        self?.updateNowPlayingInfo() // 更新通知栏状态
        return .success
    }
    
    // 暂停命令响应
    commandCenter.pauseCommand.addTarget { [weak self] _ in
        self?.audioPlayer?.pause()
        self?.updateNowPlayingInfo()
        return .success
    }
    
    // 下一曲命令响应
    commandCenter.nextTrackCommand.addTarget { [weak self] _ in
        self?.playNextTrack() // 这里替换成你的下一曲逻辑
        self?.updateNowPlayingInfo()
        return .success
    }
    
    // 快退/上一曲命令响应:这里做快退10秒的示例,你也可以改成跳转到上一曲
    commandCenter.previousTrackCommand.addTarget { [weak self] _ in
        guard let player = self?.audioPlayer else { return .commandFailed }
        player.currentTime = max(player.currentTime - 10, 0) // 快退10秒,避免负数
        self?.updateNowPlayingInfo()
        return .success
    }
    
    // 可选:添加快进命令(比如快进10秒)
    commandCenter.skipForwardCommand.preferredIntervals = [10]
    commandCenter.skipForwardCommand.addTarget { [weak self] _ in
        guard let player = self?.audioPlayer else { return .commandFailed }
        player.currentTime = min(player.currentTime + 10, player.duration)
        self?.updateNowPlayingInfo()
        return .success
    }
}

注意用[weak self]避免循环引用,处理完命令后一定要调用updateNowPlayingInfo()同步通知栏状态。

3. 更新MPNowPlayingInfoCenter显示歌曲信息

这个类负责在通知栏和锁屏展示歌曲的封面、标题、艺术家、播放进度等内容,每次播放状态变化或切换歌曲都要更新它:

func updateNowPlayingInfo() {
    guard let player = audioPlayer else { return }
    
    var nowPlayingInfo = [String: Any]()
    
    // 填充歌曲基本信息
    nowPlayingInfo[MPMediaItemPropertyTitle] = "当前歌曲标题"
    nowPlayingInfo[MPMediaItemPropertyArtist] = "艺术家名称"
    
    // 添加封面图:如果是网络图片,先下载转成UIImage再传入
    if let coverImage = UIImage(named: "song_cover") {
        nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: coverImage.size) { size in
            return coverImage
        }
    }
    
    // 同步播放进度和状态
    nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = player.currentTime
    nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = player.duration
    nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = player.isPlaying ? 1.0 : 0.0
    
    // 刷新通知栏信息
    MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
}

如果是流式音频,一开始duration可能是NaN,等音频加载完成后再更新即可。

4. 生命周期和内存管理注意事项
  • 后台播放保持:只要音频会话配置正确、后台模式开启,AVPlayer默认支持后台播放,通知栏控件会自动显示。
  • 清理资源:在App退出或停止播放时,记得移除命令监听避免内存泄漏:
func cleanupRemoteCommands() {
    let commandCenter = MPRemoteCommandCenter.shared()
    commandCenter.playCommand.removeTarget(nil)
    commandCenter.pauseCommand.removeTarget(nil)
    commandCenter.nextTrackCommand.removeTarget(nil)
    commandCenter.previousTrackCommand.removeTarget(nil)
}
5. 测试要点
  • 必须用真机测试:模拟器的通知栏媒体控件有时候不会正常显示。
  • 流式播放初始化:用AVPlayer加载音频URL很简单:
guard let audioURL = URL(string: "你的音频流地址") else { return }
audioPlayer = AVPlayer(url: audioURL)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:32:30