使用 AVPlayer 在 UIView 中播放时间流逝

Posted

技术标签:

【中文标题】使用 AVPlayer 在 UIView 中播放时间流逝【英文标题】:using AVPlayer to play a time lapse within a UIView 【发布时间】:2015-12-19 12:17:02 【问题描述】:

我正在使用自定义图像/视频选择器来选择时间流逝,一旦选择器视图被关闭,我想在 UIView 中播放时间流逝,该 UIView 已放在界面构建器中的视图控制器上。我目前拥有的这段代码在下面,但问题是在选择时间间隔时它没有播放。

查看视频播放器的插座和变量

@IBOutlet var videoView: UIView!
let ipc = QBImagePickerController()
var playerItem: AVPlayerItem?
var videoPlayer: AVPlayer?
var playerLayer: AVPlayerLayer?

已完成选择资产代码

func qb_imagePickerController(imagePickerController: QBImagePickerController, didFinishPickingAssets assets: [AnyObject]) 
    for asset in assets as! [PHAsset] 
        PHImageManager.defaultManager().requestAVAssetForVideo(asset, options: nil, resultHandler: (avAsset: AVAsset?, audioMix: AVAudioMix?, info: [NSObject : AnyObject]?) -> Void in
            self.playerItem = AVPlayerItem(asset: avAsset!)
            self.videoPlayer = AVPlayer(playerItem: self.playerItem!)
            self.playerLayer = AVPlayerLayer(player: self.videoPlayer)
            self.playerLayer!.frame = self.videoView.bounds
        )
    
    self.dismissViewControllerAnimated(true, completion:  self.play() )

play() 函数代码

func play()

    videoPlayer!.play()

打开可选值时意外发现 nil

【问题讨论】:

【参考方案1】:

我不太了解您正在使用的库,但它似乎有完成块。这些在后台线程中运行。

实际上有一个问题:您在分配变量(播放器、项目等)之前关闭了视图控制器。

假设您是 Swift 新手,我将详细介绍您的代码在运行时的行为方式:

• 当您的用户选择照片时,代理会调用函数

• 视图控制器被关闭,播放器开始播放

• 然后运行你的 for 循环并为玩家分配一个要播放的项目(为时已晚)

您想要实现的是分配一个要播放的项目,然后关闭 VC。由于 UI 代码只能在前台(主线程)运行,您不能只在完成块中移动关闭函数,而是需要在 for 循环完成后使用 Grand Central Dispatch 在主线程中运行代码。

我建议你在 GitHub 上下载 Async library,它是 GCD 的一个包装器(下载后浏览到 Sources 文件夹并将 Async.swift 文件拖到你的 Xcode 项目中)。

然后您将需要编辑“完成选择资产”功能以播放您的视频:

   func qb_imagePickerController(imagePickerController: QBImagePickerController, didFinishPickingAssets assets: [AnyObject]) 

       let photoAssets = assets as! [PHAsset]  

        PHImageManager.defaultManager().requestAVAssetForVideo(photoAssets[0], options: nil, resultHandler: (avAsset: AVAsset?, audioMix: AVAudioMix?, info: [NSObject : AnyObject]?) -> Void in

            self.playerItem = AVPlayerItem(asset: avAsset!)
            self.videoPlayer = AVPlayer(playerItem: self.playerItem!)
            self.playerLayer = AVPlayerLayer(player: self.videoPlayer)
            self.playerLayer!.frame = self.videoView.bounds

            Async.main  self.dismissViewControllerAnimated(true, completion:  self.play() ) 

        )


顺便说一句,我删除了 for 循环,因为我发现您只是愿意选择数组中的第一个资产。 (如果错了告诉我!)

去试试这个,告诉我它是否有效

(更多关于 GCD here!)

【讨论】:

我现在没有时间对此进行测试,但这看起来很完美。你也对 for 循环是正确的。非常感谢! 我刚刚尝试过,但它仍然无法正常工作,要么应用程序崩溃,要么控制台在解开可选值时意外发现 nil,或者根本没有任何反应。有什么想法吗? 能否重现该问题并将内存堆栈发送给我? (让应用程序崩溃,然后在调试窗格中选择方法并在控制台的左窗格中告诉我哪个变量等于 nil) 我在帖子末尾添加了一张图片,我想这是你想要的吗?

以上是关于使用 AVPlayer 在 UIView 中播放时间流逝的主要内容,如果未能解决你的问题,请参考以下文章

在视图中使用 AVPlayer 播放多个视频

使用 AVPlayer 播放的视频在 swift3 中从其容器视图中消失

avplayer播放视频时没有声音

知道 AVPlayer 对象何时准备好播放

UIView 中的 AVPlayer 视图缺少控件

AVPlayer 没有播放本地保存的视频文件