用于多个视图控制器的 AVPlayer 类

问题描述

我正在使用 AVPlayer 项目来播放直播流(广播应用程序)。一切似乎都在工作,但是,整个代码都在一个视图控制器下,即 PlayerViewController : UIViewController. 因为我将向应用程序添加更多功能并且不想重复用于 AVPlayer 的所有方法。如何使用所有必需的方法Swift Class 创建 AVPlayer 并继续在我应用的多个页面(未来的视图控制器)上使用该类实例

这是加载到 ViewDid Load()代码。稍后将添加 Remote Commands 之类的功能。我不想为执行相同任务的单独视图控制器重复代码

   func configurePlayer(){
        do {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback)
            print("AVAudioSession Category Playback OK")
            do {
                try AVAudioSession.sharedInstance().setActive(true)
                print("AVAudioSession is Active")

            } catch let error as NSError {
                print(error.localizedDescription)
            }
        } catch let error as NSError {
            print(error.localizedDescription)
        }
        guard let url = URL(string: station!.url!) else {return}
        let playerItem = AVPlayerItem(url: url)
        player = AVPlayer(playerItem: playerItem)  

    }
 

该类的一些其他方法将是

func togglePlayer() {
    if player?.rate != 0 {
        player?.pause()
        self.playButton.setBackgroundImage(UIImage(systemName: "play.circle"),for: .normal)
    } else {
        player?.play()
        self.playButton.setBackgroundImage(UIImage(systemName: "stop"),for: .normal)
    }
}

//Method 1{...}
//Method 2 {...}

解决方法

您不需要从 AVPlayer 继承您的类,因为您可能不会使用所有它必须提供的功能,因此只需创建一个普通类即可。

此外,这会因您的用例或实现而有很大差异,因此我只会提供一个示例供您试验。

class UniversalAVPlayer {
    
    var player: AVPlayer?
    
    init(url: URL?) {
        configurePlayer(url: url)
        allFeatureConfigs()
    }
    
    func configurePlayer(url: URL?) {
        do {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback)
            print("AVAudioSession Category Playback OK")
            do {
                try AVAudioSession.sharedInstance().setActive(true)
                print("AVAudioSession is Active")
                
            } catch let error as NSError {
                print(error.localizedDescription)
            }
        } catch let error as NSError {
            print(error.localizedDescription)
        }
        guard let url = url else {return}
        let playerItem = AVPlayerItem(url: url)
        player = AVPlayer(playerItem: playerItem)
        
    }
    
    func allFeatureConfigs() {
        //add any configurations you want to add in the future here.
    }
    
}

并且您应该创建一个委托来帮助您使用诸如 togglePlayer 方法之类的方法:

func togglePlayer() {
    if player?.rate != 0 {
        player?.pause()
        self.delegate?.changeImageForPlayStatus(image : UIImage(systemName: "play.circle"))
    } else {
        player?.play()
        self.delegate?.changeImageForPlayStatus(image: UIImage(systemName: "stop"))
    }
}

例如,当使用它提供的图像调用委托方法时,更改 VC 中的背景图像。

由于您不会将这些函数设置为私有,因此您将能够从您创建的实例中使用它们:

let player = UniversalAVPlayer(url: url) //imagine url is an actual URL
//your config methods will run instantly when you create this instance since they are called at initialization

//Call your methods like this when ever you need.
player.togglePlayer()