如何在 iOS 中播放视频 PHAsset?

Posted

技术标签:

【中文标题】如何在 iOS 中播放视频 PHAsset?【英文标题】:How to Play Videos PHAsset in iOS? 【发布时间】:2017-01-13 23:12:28 【问题描述】:

我想播放来自PHAsset 的视频,这些视频是从 ios 照片中收集的。 PHAsset 视频 nsurl (https://***.com/a/35099857/1084174) 对我自己的应用程序有效,比如说 MyPlayer 片刻/块。当我将图像/视频复制到 MyPlayers 自己的沙箱中时,nsurl 才会始终有效。在我看来,

我需要将每个视频从临时 PHAsset nsurl 复制到 MyPlayers 沙盒(应用程序组/文档),然后我才能播放视频 沙盒相对 nsurl。

如果是这种情况,所有其他播放器如何即时播放长视频?如果有其他方法可以在不复制到应用沙箱的情况下播放视频,请告诉我方法。

【问题讨论】:

【参考方案1】:

在 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()
                
            
        
    

【讨论】:

您的解决方案无法在某些设备上运行,并在此“让资产 = 资产为!AVURLAsset”上崩溃,并显示消息:“无法将 'AVComposition' (0x1ed8ebd88) 类型的值转换为 'AVURLAsset' ( 0x1ed8eb680)" 你能指导我解决这个错误吗? 我也试过这个但同样的错误 PHImageManager.default().requestAVAsset(forVideo: phAsset, options: nil, resultHandler: (asset: AVAsset?, audioMix: AVAudioMix?, info: [AnyHashable : Any]?) -> Void in【参考方案2】:

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

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()
            
        
    

【讨论】:

【参考方案3】:

@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【参考方案4】:

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

导入文件

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()
                
            )
        )
    

来自 AppLocalUrl

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()
            
        )
    

【讨论】:

我已经测试了这段代码,它不适用于慢动作视频。所以我修改了这个解决方案。 ***.com/a/60292456/397915

以上是关于如何在 iOS 中播放视频 PHAsset?的主要内容,如果未能解决你的问题,请参考以下文章

FFmpeg学习6:视音频同步

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

需要iOS教程在我的应用程序中播放视频文件[关闭]

.NET下的视频播放器,视频截取功能

如何在ios中播放视频播放器

如何在 iOS 的 UITableViewCell 中播放视频(自动播放)