1

我在 View 控制器中实现了两个功能(setupRemoteTransportControls() 和 setupNowPlaying())并向 AppDelegate 添加了一个功能,但我仍然无法在锁定屏幕上看到我的应用程序的背景音频控件,而且音频中断功能也不是工作。这是来自 url 的实时流,您可以在代码中看到。在常规设置中,我添加了后台播放: 在此处输入图像描述

我想做的是在远程命令中心艺术家、标题和专辑艺术标签和 UIImage 上打印(标签 UIImage 取自我的站 API),但我只显示命令中心就卡住了。这是我的代码:

import UIKit
import AVKit
import MediaPlayer
class ViewController: UIViewController, AVAudioPlayerDelegate {

@IBAction func buttonPressed(_ sender: UIButton){
              if isPlaying {
                   player.pause()
                   sender.setImage(playImage, for: .normal)
              } else {
                   let url = "https://myradio.com/radio.mp3"
                   do {
                        try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [.mixWithOthers, .allowAirPlay])
                        try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, options: [])
                        print("Playback OK")
                        try AVAudioSession.sharedInstance().setActive(true)
                        print("Session is Active")
                   } catch {
                        print(error)
                   }
                   
                   player = AVPlayer(url: URL(string: url)!)
                   player.volume = 1.0
                   player.rate = 1.0
                   player.play()
                sender.setImage(pauseImage, for: .normal)
              }
              
              isPlaying.toggle()
         }


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        overrideUserInterfaceStyle = .light
        setupRemoteTransportControls()
        requestNowPlaying()
        setupNowPlaying()
    }

// Here is the API data downloading part, so i skipped it 


    //Command Center audio controls
    
    func setupRemoteTransportControls() {
        // Get the shared MPRemoteCommandCenter
        let commandCenter = MPRemoteCommandCenter.shared()
        // Add handler for Play Command
        commandCenter.playCommand.addTarget { [unowned self] event in
            if self.player.rate == 1.0 {
                self.player.play()
                return .success
            }
            return .commandFailed
        }

        // Add handler for Pause Command
        commandCenter.pauseCommand.addTarget { [unowned self] event in
            if self.player.rate == 1.0 {
                self.player.pause()
                return .success
            }
            return .commandFailed
        }
    }

    func setupNowPlaying() {
        // Define Now Playing Info
        var nowPlayingInfo = [String : Any]()
        nowPlayingInfo[MPMediaItemPropertyTitle] = "Test"

        if let image = UIImage(named: "Default_albumart") {
            nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: image.size) { size in
                return image
            }
        }
        nowPlayingInfo[MPNowPlayingInfoPropertyIsLiveStream] = true
        

        // Set the metadata
        MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
    }


    func updateNowPlaying(isPause: Bool) {
        // Define Now Playing Info
        let nowPlayingInfo = MPNowPlayingInfoCenter.default().nowPlayingInfo!

        //nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = player.currentTime
        //nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = isPause ? 0 : 1

        // Set the metadata
        MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
    }
    

    
    
//audio interruption
    @objc func handleInterruption(notification: Notification) {
        guard let userInfo = notification.userInfo,
                let typeValue = userInfo[AVAudioSessionInterruptionTypeKey] as? UInt,
                let type = AVAudioSession.InterruptionType(rawValue: typeValue) else {
                    return
            }

            // Switch over the interruption type.
            switch type {

            case .began:
                print("Interruption began")
                

            case .ended:
               // An interruption ended. Resume playback, if appropriate.

                guard let optionsValue = userInfo[AVAudioSessionInterruptionOptionKey] as? UInt else { return }
                let options = AVAudioSession.InterruptionOptions(rawValue: optionsValue)
                if options.contains(.shouldResume) {
                    player.play()
                } else {
                    // An interruption ended. Don't resume playback.
                }

            default: ()
            }
        }
    
            
    
}

这是我在 My AppDelegate.swift 中添加的内容:

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        application.beginReceivingRemoteControlEvents()
     //    Override point for customization after application launch.
       return true
    }
4

2 回答 2

1

.mixWithOthers从您的类别选项中删除。我认为原因是只有主要的 iOS 音频应用程序才能控制远程屏幕。.mixWithOthers用于辅助音频应用程序。

于 2021-09-22T04:57:34.770 回答
0

使用以下代码将自己标识为.longForm音频内容提供者:

try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, mode: AVAudioSessionModeDefault, routeSharingPolicy: .longForm)

有关 AirPlay2 的完整实施,请查看此 Apple WWDC 演示文稿:https ://developer.apple.com/videos/play/wwdc2017/509/

于 2021-09-22T07:14:00.717 回答