在 ViewController 中调用自动播放视频的控制器

Posted

技术标签:

【中文标题】在 ViewController 中调用自动播放视频的控制器【英文标题】:Call Controller of an autoplayed video in ViewController 【发布时间】:2020-11-02 23:06:42 【问题描述】:

我已经进行了设置,以便在显示 ViewController 时,视频会自动开始,最后会切换到不同的 ViewController。

问题是,如果在观看时将应用程序置于后台,视频会冻结,您必须重新启动应用程序。

我想过设置经典的暂停/播放控制器,以便在您按下屏幕时出现,以便您继续观看,但我不知道该怎么做。

或者您有其他解决方案来防止视频冻结?

import UIKit
import AVKit
import AVFoundation

class View8BaController: UIViewController 

    func setupAVPlayer() 

        let videoURL = Bundle.main.url(forResource: "8B-A", withExtension: "mp4") // Get video url
        let avAssets = AVAsset(url: videoURL!) // Create assets to get duration of video.
        let avPlayer = AVPlayer(url: videoURL!) // Create avPlayer instance
        let avPlayerLayer = AVPlayerLayer(player: avPlayer) // Create avPlayerLayer instance
        avPlayerLayer.frame = self.view.bounds // Set bounds of avPlayerLayer
        self.view.layer.addSublayer(avPlayerLayer) // Add avPlayerLayer to view's layer.
        
        avPlayer.play() // Play video

        // Add observer for every second to check video completed or not,
        // If video play is completed then redirect to desire view controller.
        avPlayer.addPeriodicTimeObserver(forInterval: CMTime(seconds: 1, preferredTimescale: 1) , queue: .main)  [weak self] time in

            if time == avAssets.duration 
                let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SCENA7") as! SCENA7ViewController
                self?.navigationController?.pushViewController(vc, animated: false)
            
        
    

    //------------------------------------------------------------------------------

    override func viewDidLoad() 
        super.viewDidLoad()
        
        
    

    //------------------------------------------------------------------------------

    override func viewDidAppear(_ animated: Bool) 
        super.viewDidAppear(animated)
        self.setupAVPlayer()  // Call method to setup AVPlayer & AVPlayerLayer to play video
    

【问题讨论】:

【参考方案1】:

您是否尝试过让视频在 sceneDelegate 中播放?

添加到类,在 func setupAVPlayer() 的正上方,

var avPlayer: AvPlayer!

然后在你的场景中委托任何函数之外

let view8Ba = View8BaController()

创建视图控制器的实例。然后您可以访问以下属性:

func sceneWillEnterForeground(_ scene: UIScene) 
    if view8Ba.viewIfLoaded?.window != nil 
     view8Ba.avPlayer.play()
    
 

这将告诉您的视频在应用从后台返回时重新开始播放。

如果您想在点击屏幕时添加播放/暂停,您可以将点击手势识别器和另一个视图添加到当前视图控制器并将背景设置为清除(在情节提要中将新视图拖到视图控制器的顶部)

然后调用

   override func viewDidLayoutSubviews() 
        super.viewDidLayoutSubviews()
        pauseScreenView.frame = View8BaController.bounds
    

这告诉您添加的新视图在 viewController 上的位置。

在点击手势识别器的 IBAction 中

@IBAction func screenTapped(_ sender: Any) 

View8BaController.addSubview(pauseScreenView)
DispatchQueue.main.asyncAfter(deadline: .now() + 10.0) 
    self.pauseScreenView.removeFromSuperview()
    

这会将新视图添加到 viewController 的顶部,然后在 10 秒后将其移除。

在新视图中,您可以添加一个按钮来播放/暂停您的视频

@IBAction func pauseVideo(_ sender: UIButton) 
    if avPlayer.timeControlStatus == .playing 
        avPlayer.pause()
        pauseButton.setImage(playImage, for: .normal)
    else 
        avPlayer.play()
        pauseButton.setImage(pauseImage, for: .normal)
    

【讨论】:

我尝试了第一个可能适合我的选项。但是,如果我在 SceneDelegate 中输入您的代码,则会收到错误消息:Instance member 'avPlayer' cannot be used on type 'View8BaController';您的意思是改用这种类型的值吗? 对不起。您需要添加视图控制器的实例才能访问属性。我在上面编辑过。 感谢您的更改。我按照您的指示做了,但是在打开应用程序 1 秒后崩溃并出现以下错误:线程 1:致命错误:在隐式展开可选值时意外发现 nil。 -------- 错误发生在 Scenedelegate.swift 中的字符串: func sceneWillEnterForeground (_ scene: UIScene) // 当场景从背景过渡到前景时调用。 // 使用此方法撤消进入后台时所做的更改。 view8Ba.avPlayer.play () 您需要检查 view8Ba 视图是否为活动视图。否则,它会尝试播放应用程序进入前台时从未实例化的视频。查看新编辑 我试图在场景委托中插入修改后的字符串,但是:if view8Ba? .window! = nil ---- 给了我一个错误 -------- 不能对类型的非可选值使用可选链接'View8BbController' ;消除 '?'和----'View8BbController'类型的值没有成员'window

以上是关于在 ViewController 中调用自动播放视频的控制器的主要内容,如果未能解决你的问题,请参考以下文章

准备好后如何使视频视图不自动启动

快速从另一个 ViewController 调用函数

FFmpeg学习6:视音频同步

如何在WKWebView中禁用YouTube视频的自动播放?

关闭 MPMoviePlayerViewController 后自动旋转 ViewController

FFmpeg学习5:多线程播放视音频