1

我正在使用自定义图像/视频选择器来选择时间流逝,一旦选择器视图被关闭,我想在 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 在此处输入图像描述

4

1 回答 1

2

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

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

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

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

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

• 然后你的for循环运行,玩家被分配了一个项目来玩(太晚了)

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

我建议你在 GitHub 上下载Async 库,它是 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的信息!)

于 2015-12-21T16:47:58.953 回答