日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ios nslinkattributename 自定义url_iOS音视频播放指南(二)

發布時間:2025/3/20 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ios nslinkattributename 自定义url_iOS音视频播放指南(二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

沒看第一篇的小伙伴可以先看第一篇wlzz:iOS音視頻播放指南(一)?zhuanlan.zhihu.com本章主要內容
  • 畫中畫支持
  • 后臺音頻播放,鎖屏界面顯示,遠程音頻控制
  • 在耳機插拔、接聽電話等情況下處理音頻業務邏輯
  • 1. 讓你的App支持畫中畫

    畫中畫指可以讓視頻在小窗中播放,可以一邊看視頻一邊刷知乎

    你可以使用AVPlayerViewController或者AVPictureInPictureController來實現畫中畫播放。 其中AVPictureInPictureController支持你自定義一些播放控件

    在支持畫中畫播放之前,確保你按照iOS音視頻播放指南(一) 第三部分(3.音頻設置 )完成相應的設置。

  • AVPlayerViewController
  • 支持畫中畫播放最簡單的方式就是使用 AVPlayerViewController 。如果你的設備支持畫中畫播放,使用AVPlayerViewController點擊按鈕就能看到效果。支持畫中畫播放的設備在視頻播放的時候直接返回桌面,視頻也會以畫中畫形式繼續播放。

    如果你返回桌面的時候視頻不會以畫中畫形式繼續播放,檢測一下設置-通用-畫中畫。查看是否開啟

    但是當你想還原畫中畫視頻的時候,AVKit在默認情況下會停止視頻的播放(系統不知道如何處理你App的用戶界面),我們需要自己實現代理來完成視頻的恢復。

    let controller = AVPlayerViewController()controller.delegate = selfextension ViewController: AVPlayerViewControllerDelegate {//在這里處理App的恢復邏輯func playerViewController(_ playerViewController: AVPlayerViewController, restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void) {//重新present playerViewControllerpresent(playerViewController, animated: true) {//通知系統我們已經完成了視頻的界面恢復completionHandler(true)}} }

    2. 使用AVPictureInPictureController

    當你自定義的播放器需要支持畫中畫的時候,你需要用到AVPictureInPictureController ,它管理著AVPlayerLayer。

    func setupPictureInPicture() { // 判斷設備是否支持畫中畫if AVPictureInPictureController.isPictureInPictureSupported() {//創建AVPlayerLayerplayerLayer = AVPlayerLayer(player: AVPlayer(url: url))playerLayer.frame = CGRect(x: 100, y: 100, width: 100, height: 100)view.layer.addSublayer(playerLayer)playerLayer.player?.play()// 創建AVPictureInPictureControllerpictureInPictureController = AVPictureInPictureController(playerLayer: playerLayer)pictureInPictureController.delegate = self} else {// 不支持畫中畫startButton.isEnabled = falsestopButton.isEnabled = false}}@objc func togglePictureInPictureMode(_ sender: UIButton) {if pictureInPictureController.isPictureInPictureActive {//停止pictureInPictureController.stopPictureInPicture()} else {//開始pictureInPictureController.startPictureInPicture()}}func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void) {//在這里進行用戶視頻播放界面的恢復邏輯print("restore")completionHandler(true)}func pictureInPictureControllerWillStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {//在界面上顯示placeholder,隱藏播放控件等操作print("will start")}func pictureInPictureControllerWillStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {//在界面上隱藏placeholder,恢復播放控件等操作print("will stop")}

    其中AVPictureInPictureController 創建使用到了AVPlayerLayer,但是實際播放的時候PIP不使用AVPlayerLayer進行顯示。當PIP開始使用的時候,系統會自動停止向AVPlayerLayer輸出視頻幀。

    你一定要讓用戶通過操作(點擊按鈕等)來開始畫中畫顯示。 不能直接在代碼中直接startPictureInPicture ,這樣的話你的APP上架審核會被拒絕。

    2. 音頻控制

    后臺播放請參考iOS音視頻播放指南(一)第三部分(3.音頻設置 )

    當你完成后臺播放設置以后,如果你播放的是音頻文件,你退到后臺的時候系統會自動繼續播放。但是當你播放的是視頻文件,默認情況下進入后臺系統會自動停止播放。 如果你想在退到后臺繼續播放聲音,需要在進入后臺時斷開AVPlayer的連接,進入前臺重新連接。

    func sceneWillEnterForeground(_ scene: UIScene) {guard let vc = (scene.delegate as? SceneDelegate)?.window?.rootViewController as? ViewController else {return}if let playerLayer = vc.playerLayer, let player = vc.player {// 進入前臺重新連接playerplayerLayer.player = player}}func sceneDidEnterBackground(_ scene: UIScene) {guard let vc = (scene.delegate as? SceneDelegate)?.window?.rootViewController as? ViewController else {return}if let playerLayer = vc.playerLayer {// 進入后臺斷開與player的連接playerLayer.player = nil}}

    如果你的App支持后臺音頻播放,你可能還需要支持遠程控制(耳機控制等)以及在鎖屏界面的控制。這里我們使用到MediaPlayer 框架中的MPRemoteCommandCenter和MPNowPlayingInfoCenter 這兩個類。

    MPRemoteCommandCenter用于處理遠程控制

    import MediaPlayerfunc setupRemoteTransportControls() {// 獲取 MPRemoteCommandCenterlet commandCenter = MPRemoteCommandCenter.shared()// 播放控制commandCenter.playCommand.addTarget { [unowned self] event inif self.player.rate == 0.0 {self.player.play()return .success}return .commandFailed}// 停止控制commandCenter.pauseCommand.addTarget { [unowned self] event inif self.player.rate == 1.0 {self.player.pause()return .success}return .commandFailed}}

    MPNowPlayingInfoCenter用于鎖屏界面的顯示。其中我們需要注意的是AVPlayerViewController會自動刷新鎖屏界面顯示內容,這里我們關閉自動刷新。

    func setupNowPlaying() {// 由我們自己控制鎖屏界面的顯示,如果設置為false可能會使耳機控制失效playerViewController.updatesNowPlayingInfoCenter = false// 設置顯示內容var nowPlayingInfo = [String : Any]()nowPlayingInfo[MPMediaItemPropertyTitle] = "My Movie"if let image = UIImage(named: "lockscreen") {nowPlayingInfo[MPMediaItemPropertyArtwork] =MPMediaItemArtwork(boundsSize: image.size) { size inreturn image}}nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = playerItem.currentTime().secondsnowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = playerItem.asset.duration.secondsnowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = player.rate// 提交給MPNowPlayingInfoCenterMPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo}

    我們可以在屏幕上看到我們提供顯示的內容

    3. 處理中斷請求

    當用戶觀看視頻的時候,如果有電話打進來,系統會自動暫停視頻播放。當通話結束的時候,系統會自動恢復播放。如果你自定義了播放界面,你可能需要在這種情況下更新界面,對AVPlayer的rate屬性進行KVO可以很方便的處理業務邏輯。

    此外,你也可以通過監聽通知來處理業務邏輯

    func setupInterruptionNotification() {let notificationCenter = NotificationCenter.defaultnotificationCenter.addObserver(self,selector: #selector(handleInterruption),name: AVAudioSession.interruptionNotification,object: nil)}@objc func handleInterruption(notification: Notification) {guard let userInfo = notification.userInfo,let typeValue = userInfo[AVAudioSessionInterruptionTypeKey] as? UInt,let type = AVAudioSession.InterruptionType(rawValue: typeValue) else {return}if type == .began {// 中斷請求觸發,在這里處理你的業務邏輯}else if type == .ended {if let optionsValue = userInfo[AVAudioSessionInterruptionOptionKey] as? UInt {let options = AVAudioSession.InterruptionOptions(rawValue: optionsValue)if options.contains(.shouldResume) {// 系統會自動恢復播放 (通話結束)} else {// 系統不會自動恢復播放}}}}

    AVAudioSession一個比較重要的功能是處理音頻路由變化。 一般情況下,在用戶插入耳機的時候,音頻會繼續播放,在用戶拔出耳機的時候,音頻停止播放,這一切都由系統為你自動完成。你可能需要在App中對這種情況進行一些業務處理。對AVPlayer的rate屬性進行KVO或者使用AVAudioSession.routeChangeNotification進行監聽

    func setupRouteChangeNotification() {let notificationCenter = NotificationCenter.defaultnotificationCenter.addObserver(self,selector: #selector(handleRouteChange),name: AVAudioSession.routeChangeNotification,object: nil)}@objc func handleRouteChange(notification: Notification) {guard let userInfo = notification.userInfo,let reasonValue = userInfo[AVAudioSessionRouteChangeReasonKey] as? UInt,let reason = AVAudioSession.RouteChangeReason(rawValue:reasonValue) else {return}switch reason {case .newDeviceAvailable://耳機插入、藍牙連接等情況let session = AVAudioSession.sharedInstance()//獲取當前路由信息for output in session.currentRoute.outputs where output.portType == AVAudioSession.Port.headphones {//耳機已連接//headphonesConnected = truebreak}case .oldDeviceUnavailable://耳機拔出、藍牙斷開等情況//獲取先前的路由信息if let previousRoute =userInfo[AVAudioSessionRouteChangePreviousRouteKey] as? AVAudioSessionRouteDescription {for output in previousRoute.outputs where output.portType == AVAudioSession.Port.headphones {//耳機已斷開連接//headphonesConnected = falsebreak}}default: ()}}

    第三篇鏈接

    wlzz:iOS音視頻播放指南(三)?zhuanlan.zhihu.com

    Github鏈接

    https://github.com/wlixcc/AVBasicPlayback?github.com

    總結

    以上是生活随笔為你收集整理的ios nslinkattributename 自定义url_iOS音视频播放指南(二)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。