iOS - 使用AVPlayer

时间:2018-02-19 12:13:29

标签: ios swift notifications avplayer avplayeritem

在我的代码中,从url播放的内容如下:

private func play() {
    let streamUrl = ...        
    let playerItem = AVPlayerItem(url: streamURL)
    radioPlayer = AVPlayer(playerItem: playerItem)
    radioPlayer.volume = 1.0
    do {
         try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, with: AVAudioSessionCategoryOptions.mixWithOthers)
         try AVAudioSession.sharedInstance().setActive(true)
         UIApplication.shared.beginReceivingRemoteControlEvents()
     } catch {
         print("Error deactivating audio session.")
     }
     radioPlayer.play()
     startListeningForStreamFail()
     stopStartButton.setImage(#imageLiteral(resourceName: "pause_btn"), for: .normal)
}

就像上面解释的代码片段一样,在调用.play()函数之后,我正在调用startListeningForStreamFail(),它在主线程上将当前viewcontroller注册为两种类型的通知。

private func startListeningForStreamFail() {
    DispatchQueue.main.async { [weak self] in
        NotificationCenter.default.addObserver(self as Any, selector: #selector(self?.playerItemFailedToPlay), name: NSNotification.Name.AVPlayerItemPlaybackStalled, object: self?.radioPlayer?.currentItem)
        NotificationCenter.default.addObserver(self as Any, selector: #selector(self?.playerItemFailedToPlay), name: NSNotification.Name.AVPlayerItemFailedToPlayToEndTime, object: self?.radioPlayer?.currentItem)
    }
}

选择器功能如下:

@objc private func playerItemFailedToPlay(notification: Notification) {
    print("playerItemFailedToPlay")
}

因为现在工作很好,我试图通过添加一些加字符来测试失败。但playerItemFailedToPlay()函数不会被调用,不会打印任何东西。

是否应该调用此选择器,即使只更改了网址?

任何帮助将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:3)

我尝试在Github上构建一个项目以便于检查

我按照以下步骤操作:

  1. 将NSAppTransportSecurity添加到info.plist,如this answer中所示,以允许http

  2. 修剪提供的网址以删除任何空格

    let urlString = urlString.trimmingCharacters(in: .whitespacesAndNewlines)

  3. 检查字符串是否提供有效链接

    guard let url = URL(string: urlString) else { return complete(.unvalidURL) }

  4. 检查链接是否可播放

    AVAsset(url: url).isPlayable

  5. 如果之前的任何步骤未成功,则表示该网址无效

    我还在启动可播放链接后添加了一个观察者来解决错误

    NotificationCenter.default.addObserver(self, selector: #selector(itemFailedToPlayToEndTime(_:)), name: .AVPlayerItemFailedToPlayToEndTime, object: nil)
    
    NotificationCenter.default.addObserver(self, selector: #selector(itemNewErrorLogEntry(_:)), name: .AVPlayerItemNewErrorLogEntry, object: nil)
    
    NotificationCenter.default.addObserver(self, selector: #selector(itemPlaybackStalled(_:)), name: .AVPlayerItemPlaybackStalled, object: nil)