ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

【 iOS】音视频

【 iOS】音视频 文章目录第一部分基础概念与权限配置1. 核心类介绍2. 后台播放权限配置第二部分实战代码 —— 本地音频播放第三部分实战代码 —— 网络视频播放第四部分实战代码 —— 锁屏媒体控制第五部分进阶最佳实践与坑点提示总结流程学习 iOS 的音视频开发AVFoundation是绝对的核心框架。而MediaPlayer框架在现代开发中主要用来与 iOS 系统的锁屏媒体控制中心进行交互。为了让你少走弯路我们先理清三个框架的定位AVFoundation核心引擎。负责音频播放、视频播放、录制、编辑等底层操作。AVKit系统 UI 层。提供现成的视频播放器界面带播放/暂停条、进度条等底层调用的还是 AVFoundation。MediaPlayer系统交互层。负责把你的 App 正在播放的音乐展示在 iOS 锁屏界面和控制中心并接收用户的耳机按键、锁屏按键事件。下面我将为你提供一份从零到实战的完整教程。第一部分基础概念与权限配置1. 核心类介绍AVAudioSession管理 App 与系统其他音频的交互方式比如静音模式是否有效、是否打断其他音乐。AVAudioPlayer用于播放本地音频文件mp3, wav 等。简单易用。AVPlayer用于播放网络或本地音视频流。功能强大支持视频。AVPlayerViewController(AVKit)系统提供的现成视频播放器 UI。2. 后台播放权限配置如果你的 App 要在退到后台后继续播放音乐必须开启后台模式点击项目文件 -Signing Capabilities- 左上角 Capability。搜索并添加Background Modes。勾选Audio, AirPlay, and Picture in Picture。第二部分实战代码 —— 本地音频播放我们创建一个AudioPlayerManager来管理本地音频播放并配置正确的音频会话。importAVFoundationclassAudioPlayerManager:NSObject{staticletsharedAudioPlayerManager()varaudioPlayer:AVAudioPlayer?privateoverrideinit(){super.init()setupAudioSession()}// 1. 配置 AudioSession (非常重要)privatefuncsetupAudioSession(){do{letsessionAVAudioSession.sharedInstance()// .playback: 仅用于播放静音键不会影响它适合音乐类 Apptrysession.setCategory(.playback,mode:.default,options:[])trysession.setActive(true)}catch{print(AudioSession 配置失败:\(error))}}// 2. 播放本地音频funcplayLocalAudio(fileName:String,fileExtension:String){guardleturlBundle.main.url(forResource:fileName,withExtension:fileExtension)else{print(找不到音频文件)return}do{audioPlayertryAVAudioPlayer(contentsOf:url)audioPlayer?.prepareToPlay()// 预加载减少延迟audioPlayer?.play()}catch{print(播放失败:\(error))}}funcpause(){audioPlayer?.pause()}funcresume(){audioPlayer?.play()}}调用方法AudioPlayerManager.shared.playLocalAudio(fileName:my_song,fileExtension:mp3)第三部分实战代码 —— 网络视频播放播放网络视频如 HLS 的.m3u8流或.mp4链接我们需要使用AVPlayer和AVKit。importAVKitimportAVFoundationclassVideoPlayerManager{staticletsharedVideoPlayerManager()privateinit(){}// 在当前的 ViewController 上展示视频funcplayVideo(urlString:String,on viewController:UIViewController){guardleturlURL(string:urlString)else{return}// 1. 创建 AVPlayerletplayerAVPlayer(url:url)// 2. 创建系统提供的视频播放器视图控制器letplayerViewControllerAVPlayerViewController()playerViewController.playerplayer// 3. 弹出播放器并开始播放viewController.present(playerViewController,animated:true){player.play()}}}调用方法letvideoURLhttps://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_ts/master.m3u8VideoPlayerManager.shared.playVideo(urlString:videoURL,on:self)第四部分实战代码 —— 锁屏媒体控制这是MediaPlayer框架的现代用法。当你的 App 播放音乐退到后台时用户在锁屏界面看到的封面、标题、进度条以及点击锁屏的“暂停/播放”按钮都需要通过MediaPlayer来实现。我们将之前的AudioPlayerManager扩展加入MediaPlayer的支持。importAVFoundationimportMediaPlayer// 导入 MediaPlayerclassAudioPlayerManager:NSObject{// ... 前面的代码保持不变 ...funcplayLocalAudio(fileName:String,fileExtension:String){guardleturlBundle.main.url(forResource:fileName,withExtension:fileExtension)else{return}do{audioPlayertryAVAudioPlayer(contentsOf:url)audioPlayer?.delegateselfaudioPlayer?.prepareToPlay()audioPlayer?.play()// 播放时配置锁屏信息setupNowPlayingInfoCenter()// 配置远程控制事件锁屏按钮点击setupRemoteCommandCenter()}catch{print(播放失败:\(error))}}// MARK: - MediaPlayer 配置锁屏展示信息privatefuncsetupNowPlayingInfoCenter(){letcenterMPNowPlayingInfoCenter.default()varinfo:[String:Any][:]info[MPMediaItemPropertyTitle]歌曲名称info[MPMediaItemPropertyArtist]歌手名称info[MPMediaItemPropertyAlbumTitle]专辑名称// 时间相关ifletplayeraudioPlayer{info[MPMediaItemPropertyPlaybackDuration]player.duration// 总时长info[MPNowPlayingInfoPropertyElapsedPlaybackTime]player.currentTime// 当前播放时间info[MPNowPlayingInfoPropertyPlaybackRate]player.isPlaying?1.0:0.0// 播放速率}// 封面图 (如果有)// info[MPMediaItemPropertyArtwork] MPMediaItemArtwork(boundsSize: CGSize(width: 100, height: 100)) { _ in// return UIImage(named: cover)!// }center.nowPlayingInfoinfo}// MARK: - MediaPlayer 处理锁屏按键事件privatefuncsetupRemoteCommandCenter(){letcommandCenterMPRemoteCommandCenter.shared()// 处理播放按钮commandCenter.playCommand.addTarget{[weakself]eventinself?.resume()self?.updatePlaybackRate(isPlaying:true)return.success}// 处理暂停按钮commandCenter.pauseCommand.addTarget{[weakself]eventinself?.pause()self?.updatePlaybackRate(isPlaying:false)return.success}// 处理进度条拖动事件 (可选)commandCenter.changePlaybackPositionCommand.addTarget{[weakself]eventinguardleteventeventas?MPChangePlaybackPositionCommandEvent,letplayerself?.audioPlayerelse{return.commandFailed}player.currentTimeevent.positionTimeself?.setupNowPlayingInfoCenter()// 更新锁屏进度return.success}}// 更新锁屏界面的播放状态privatefuncupdatePlaybackRate(isPlaying:Bool){ifvarinfoMPNowPlayingInfoCenter.default().nowPlayingInfo{info[MPNowPlayingInfoPropertyPlaybackRate]isPlaying?1.0:0.0MPNowPlayingInfoCenter.default().nowPlayingInfoinfo}}}// 监听播放结束更新锁屏状态extensionAudioPlayerManager:AVAudioPlayerDelegate{funcaudioPlayerDidFinishPlaying(_player:AVAudioPlayer,successfully flag:Bool){ifflag{updatePlaybackRate(isPlaying:false)}}}第五部分进阶最佳实践与坑点提示模拟器测试限制AVFoundation 的音视频播放可以在模拟器上完美运行但有些复杂功能如 DRM 加密视频、系统级的画中画最好在真机上测试。MPNowPlayingInfoCenter 必须实时更新当你的 App 退到后台播放时锁屏的进度条是系统自动走的不需要你每秒去更新。但是当用户暂停、播放、拖动进度条时你必须重新调用MPNowPlayingInfoCenter.default().nowPlayingInfo ...来更新否则锁屏界面的 UI 会卡住或与实际播放不同步。AVPlayer 的状态观察 (KVO)AVPlayer播放网络视频是异步的。如果你想在视频准备好播放时显示一个 Loading 指示器你需要使用 KVOKey-Value Observing或者 Combine 来观察player.currentItem?.status和player.timeControlStatus这是网络视频开发中最容易踩坑的地方。AVAudioSession的重要性如果你没有调用setActive(true)或者 Category 设置成了.ambient环境音那么手机切到静音模式时你的音乐就不响了且退到后台可能会被系统挂起。音乐播放类 App 务必使用.playback。总结流程播放本地音乐- 用AVAudioPlayer 配置AVAudioSession。播放网络视频- 用AVPlayerAVPlayerViewController(AVKit)。退到后台/锁屏控制- 开启Background Modes 使用MediaPlayer的MPNowPlayingInfoCenter和MPRemoteCommandCenter。
返回列表