如何在iOS中播放PHAsset视频?

24

我想播放从iOS相册收集的PHAsset视频。对于我的应用程序,比如说MyPlayerPHAsset视频nsurlhttps://dev59.com/-18e5IYBdhLWcg3wJnyl#35099857)在短时间/块内是有效的。当我将图像/视频复制到MyPlayers自己的沙盒中时,nsurl才始终有效。 对我来说似乎需要将每个视频从临时的PHAsset nsurl复制到MyPlayers沙盒(appgroup / documents),然后我才能使用沙盒相对nsurl播放视频。

如果事实如此,其他播放器是如何进行动态播放长视频的? 如果有其他方法可以在不复制到应用程序沙箱的情况下播放视频,请告诉我该方法。

4个回答

28

经过几天的实验,最终我找到了一个解决方案。

导入文件

import AVKit

来自 PHAsset

static func playVideo (view:UIViewController, asset:PHAsset) {

        guard (asset.mediaType == PHAssetMediaType.Video)

            else {
                print("Not a valid video media type")
                return
        }

        PHCachingImageManager().requestAVAssetForVideo(asset, options: nil, resultHandler: {(asset: AVAsset?, audioMix: AVAudioMix?, info: [NSObject : AnyObject]?) in

            let asset = asset as! AVURLAsset

            dispatch_async(dispatch_get_main_queue(), {

                let player = AVPlayer(URL: asset.URL)
                let playerViewController = AVPlayerViewController()
                playerViewController.player = player
                view.presentViewController(playerViewController, animated: true) {
                    playerViewController.player!.play()
                }
            })
        })
    }

来自App本地链接

static func playVideo (view:UIViewController, appLocalUrl:NSURL) {

        dispatch_async(dispatch_get_main_queue(), {

            let player = AVPlayer(URL: appLocalUrl)
            let playerViewController = AVPlayerViewController()
            playerViewController.player = player
            view.presentViewController(playerViewController, animated: true) {
                playerViewController.player!.play()
            }
        })
    }

我已经测试了这段代码,发现它不能用于慢动作视频。因此,我对这个解决方案进行了修改。https://dev59.com/hlkS5IYBdhLWcg3w456B#60292456 - iCoder

7

@Sazzad Hissain Khan在Swift 3中提供的解决方案:

从PHAsset开始:

func playVideo (view: UIViewController, videoAsset: PHAsset) {

    guard (videoAsset.mediaType == .video) else {
        print("Not a valid video media type")
        return
    }

    PHCachingImageManager().requestAVAsset(forVideo: videoAsset, options: nil) { (asset, audioMix, args) in
        let asset = asset as! AVURLAsset

        DispatchQueue.main.async {
            let player = AVPlayer(url: asset.url)
            let playerViewController = AVPlayerViewController()
            playerViewController.player = player
            view.present(playerViewController, animated: true) {
                playerViewController.player!.play()
            }
        }
    }
}

来自 AppLocalUrl:

func playVideo (view: UIViewController, appLocalUrl: URL) {

    DispatchQueue.main.async {

        let player = AVPlayer(url: appLocalUrl)
        let playerViewController = AVPlayerViewController()
        playerViewController.player = player
        view.present(playerViewController, animated: true) {
            playerViewController.player!.play()
        }
    }
}

一定要注意AVComposition资源。它们就像慢动作视频之类的东西。如果你遇到了这样的资源,就用它创建一个AVPlayerItem,然后将该播放项传递给AVPlayer - Mr Rogers

5

以下解决方案同样适用于慢动作视频。

func playVideo(asset: PHAsset) {
    guard asset.mediaType == .video else {
        // Handle if the asset is not a video.
        return
    }

    let options = PHVideoRequestOptions()
    options.isNetworkAccessAllowed = true

    PHCachingImageManager().requestPlayerItem(forVideo: asset, options: options) { (playerItem, info) in
        DispatchQueue.main.async {
            let playerViewController = AVPlayerViewController()
            playerViewController.player = AVPlayer(playerItem: playerItem)
            present(playerViewController, animated: true) {
                playerViewController.player?.play()
            }
        }
    }
}

2
在Swift 5中
func playVideo(view:UIViewController, asset:PHAsset) {

        guard (asset.mediaType == PHAssetMediaType.video)

            else {
                print("Not a valid video media type")
                return
        }

        PHCachingImageManager().requestAVAsset(forVideo: asset, options: nil) { (assets, audioMix, info) in
            let asset = assets as! AVURLAsset
            DispatchQueue.main.async {

                let player = AVPlayer(url: asset.url)
                let playerViewController = AVPlayerViewController()
                playerViewController.player = player
                view.present(playerViewController, animated: true) {
                    playerViewController.player!.play()
                }
            }
        }
    }

你的解决方案不能在某些设备上正常工作,并出现了以下错误:“let asset = assets as! AVURLAsset”,并且显示了这样的消息:"Could not cast value of type 'AVComposition' (0x1ed8ebd88) to 'AVURLAsset' (0x1ed8eb680)"。你能指导我如何解决这个问题吗? - Muhammad Danish Qureshi
我也试过这个,但是错误一样。PHImageManager.default().requestAVAsset(forVideo: phAsset, options: nil, resultHandler: {(asset: AVAsset?, audioMix: AVAudioMix?, info: [AnyHashable : Any]?) -> Void in - Muhammad Danish Qureshi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接