启动和停止 segued AVPlayer 的功能是啥?

Posted

技术标签:

【中文标题】启动和停止 segued AVPlayer 的功能是啥?【英文标题】:what are the functions to start and stop a segued AVPlayer?启动和停止 segued AVPlayer 的功能是什么? 【发布时间】:2016-08-17 12:20:27 【问题描述】:

如何触发 segued ios AVPlayer 开始和停止播放(使用 Swift 2.2)?

我的 Watch Connectivity 正在发送“开始”和“停止”消息命令。如何在此处对函数进行编码以响应玩家并做出反应?

Watch 连接消息正常工作,可以在不同的视图控制器中使用 AudioPlayer 播放音频。我现在正在尝试调整它来控制视频。

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
    let destination = segue.destinationViewController as!
    AVPlayerViewController
    let url = NSURL(string: self.specimen.filmMovieLink)
    destination.player = AVPlayer(URL: url!)


// WATCH CONNECTIVITY MESSAGE TO TRIGGER START AND STOP VIDEO
    func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) 
        var replyValues = Dictionary<String, AnyObject>()
        switch message["command"] as! String 
        case "start" :
            //play video - correct here
           player.Play()
           replyValues["status"] = "Playing"
        case "stop" :
            //stop video - correct here
            player.stopPlay()
            replyValues["status"] = "Stopped"
       case "volume" :
            let level = message["level"] as! Float
            //player.adjustVolume(level)
            replyValues["status"] = "Vol = \(level)"
        default:
            break
       
       replyHandler(replyValues)
    

我收到错误消息“在 player.Play() 和 player.StopPlay() 行上使用了未解析的标识符 'player'。我尝试将 'player' 替换为 'AVPlayer'、'destination' 和 ' AVPlayerViewController' 但它没有修复它。

【问题讨论】:

【参考方案1】:

我可以发布一个示例,展示如何“修复”现有代码,但这对您没有任何好处。您目前尝试实现这一点的方式非常复杂,重新考虑如何在应用的不同部分之间传递数据将有益于您的应用。

视图控制器旨在控制其自己的视图。它不应该试图控制它呈现的 不同 控制器中的某些东西(通过 segue)。

我不建议将 AVPlayer 对象从呈现(源)视图控制器传递到呈现(目标)视图控制器。相反,您可以简单地将url 传递到prepareForSegue

这将允许目标视图控制器实例化它自己的AVPlayer,并让播放器被封装在该视图控制器中。为了与封装保持一致,其他视图控制器不需要知道(或尝试与该对象交互)。

关于从观看会话“控制”播放器,我建议设置一个应用范围的会话管理器。这将会话职责从视图控制器(它实际上不属于)中移出,并消除了试图让一个(非活动的,源)视图控制器代表另一个(活动的,目标)处理WCSession 消息的复杂性视图控制器。

有areseveral 的帖子,以及讨论如何设置WCSession 经理的互联网教程。

将功能分离到单独的模块中还可以更轻松地维护代码(并允许您在单元测试时注入或模拟代码的不同部分)。

李>

如果您以这种方式重新设计您的应用程序,您就可以使用通知来完成您想要的。例如,您的会话管理器可以根据从手表接收到的消息发布适当的通知,您的 AVPlayer 视图控制器可以观察并响应“开始”、“停止”和“音量”通知。

还有其他选择吗?

如果您只是想让复杂的方法工作,您可以尝试设置一个委托(让第二个视图控制器将其播放器的控制委托给第一个视图控制器),或者让第一个视图控制器维护对第二个视图控制器,所以它可以直接操纵它的播放器。

但请记住,您(或其他人)将不得不在以后维护此代码。任何时候你现在试图通过“偷工减料”或使用“快速而肮脏的黑客”来节省时间,以后都会被浪费掉。不要惊讶地发现自己对您(或其他人)编写的旧代码感到震惊,或者试图记住/理解您/他们选择这样做的原因,并希望您不要因为所有这些而无意中破坏了东西卷积。

【讨论】:

谢谢,我正在研究这个,非常有帮助。将 url 传递给 AV 播放器的视图控制器的想法很好,我现在会尝试。此编码用于原型(用于示例/测试目的),因此通过偷工减料的“快速而肮脏的黑客”仍然是有价值的(作为商业决策,当“卡住”时,首先进行原型制作是有价值的快速而肮脏的解决方案/解决方法,同时我会研究您对更可持续解决方案的明智建议)。我将在 watch session manager 中尝试代码并将 url 传递给另一个 VC。再次感谢 没问题!虽然原型制作有价值,但请记住,技术债务会迅速增加!快速而肮脏的代码通常会意外地进入发布版本,因为人们太忙于实现其他功能,并且没有时间来重写 hack。 “哦,好吧,我们会在下一个版本中妥善处理这个问题。”然后他们必须处理交付的应用程序中的错误/崩溃,因为内存泄漏、竞争条件、在更快/更慢的设备/网络上运行等。【参考方案2】:

回答更简单的问题,即什么函数会从 segue 触发播放(实际上是自动播放),我已经解决了代码是:

destination.player!.play()

我试过destination.play()和player.play()都不起作用,因为函数需要destination.player!.play(),如下所示:

  override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
   let destination = segue.destinationViewController as!
   AVPlayerViewController
   let url = NSURL(string: self.specimen.filmMovieLink)
   destination.player = AVPlayer(URL: url!)
   destination.player!.play()

在手表连接函数中调用 'destination.player!.play()' 和 'destination.player!.pause()' 不会带来任何错误。 但是,在按下我的手表按钮以发送“destination.player!.play()”的“开始”消息或暂停消息时,我的手表应用程序崩溃了,所以 - 根据@PetahChristian 的回答/明智的建议,这似乎是与其他代码冲突,“自动播放”只能作为一种快速而肮脏的解决方案。

【讨论】:

play() 方法会有问题。考虑到您在系统 准备 发生转场时调用它。目标视图控制器可能尚未呈现,其视图可能尚未加载,等等。如果您希望视频“自动播放”,更好的方法是让目标视图控制器播放它,它的视图出现之后。

以上是关于启动和停止 segued AVPlayer 的功能是啥?的主要内容,如果未能解决你的问题,请参考以下文章

avplayer 和 wkwebview 视频播放

AVPlayer 和背景音频流

向 AVCaptureSession 添加音频输入会停止 AVPlayer

iOS:如何停止直播 AVPlayer?

AVPlayer seekToTime 导致播放器停止播放

由于间隙,AVPlayer 流在后台停止 [关闭]