同时播放2个videoSwift
我正试图用iPhone上的swift同时播放两个video。 我已经知道AV播放器一次只能传输一个video,但谷歌搜索它我看到它仍然可以同时流式传输不同的轨道。 我也看到了画中画的实现。 真正的问题是,所有这一切都在Objective-c中并且代码很老。 我试图理解它运行代码,但是有错误,一些函数已被弃用。 有人知道如何在swift中做到这一点吗? 此外,我正在播放来自互联网的video,因此在播放前合并它们不是一种选择。 谢谢!
Swift版本
您引用的文章是在iOS中处理多个video播放的有趣方法。 这篇文章似乎与Apple的Stitched Stream Player Sample Project有关 。 作为Swift 2.2中的练习,我重写了iOS Guy文章中的代码。
您可以在我的要点中找到Swift中的视图和视图控制器。 我正在下面复制,因为最好不要在SO上使用仅链接答案。
自定义视图播放器
此自定义视图播放器允许用户换出多个AVPlayerItem
。
import UIKit import AVFoundation class MNGVideoPlayerView: UIView { /* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. override func drawRect(rect: CGRect) { // Drawing code } */ override class func layerClass () -> AnyClass { return AVPlayerLayer.self } func player () -> AVPlayer { return (self.layer as! AVPlayerLayer).player! } func setPlayer(player:AVPlayer) { (self.layer as! AVPlayerLayer).player = player } func setVideoFillMode(fillMode:String) { let playerLayer = (self.layer as! AVPlayerLayer) playerLayer.videoGravity = fillMode } }
多video播放器视图控制器
该控制器管理不同AVPlayerItem
的分发和呈现。 检查我的gist repos以获取更多更新。 (从原始objc源码@iOS Guy移植)
import UIKit import AVFoundation class MNGVideoPlayerViewController: UIViewController { let kTracksKey = "tracks"; let kStatusKey = "status"; let kRateKey = "rate"; let kPlayableKey = "playable"; let kCurrentItemKey = "currentItem"; let kTimedMetadataKey = "currentItem.timedMetadata"; var _URL:NSURL? = nil var player:AVPlayer? = nil var playerItem:AVPlayerItem? = nil var playerView:MNGVideoPlayerView? = nil var AVPlayerDemoPlaybackViewControllerStatusObservationContext = UnsafeMutablePointer() var AVPlayerDemoPlaybackViewControllerCurrentItemObservationContext = UnsafeMutablePointer () var AVPlayerDemoPlaybackViewControllerStatusObservation = UnsafeMutablePointer () override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } // MARK: - Public methods func setURL(url:NSURL) { self._URL = url let asset = AVURLAsset(URL: self._URL!) let requestedKeys = [kTracksKey,kPlayableKey] asset.loadValuesAsynchronouslyForKeys(requestedKeys) { () -> Void in self.prepareToPlayAsset(asset, withKeys: requestedKeys) } } func prepareToPlayAsset(asset:AVURLAsset, withKeys requestedKeys:NSArray) { var error:NSErrorPointer = nil for thisKey in requestedKeys { let keyStatus = asset.statusOfValueForKey(thisKey as! String, error: error) if keyStatus == .Failed { return } } if !asset.playable { return } if (self.playerItem != nil) { self.playerItem?.removeObserver(self, forKeyPath: kStatusKey) NSNotificationCenter.defaultCenter().removeObserver(self, name: AVPlayerItemDidPlayToEndTimeNotification, object: self.playerItem) } self.playerItem = AVPlayerItem(asset: asset) self.playerItem?.addObserver(self, forKeyPath: kStatusKey, options: [.Initial,.New], context: AVPlayerDemoPlaybackViewControllerStatusObservationContext) if (self.player == nil) { self.player = AVPlayer(playerItem: self.playerItem!) self.player?.addObserver(self, forKeyPath: kCurrentItemKey, options: [.Initial,.New], context: AVPlayerDemoPlaybackViewControllerCurrentItemObservationContext) } if self.player?.currentItem! != self.playerItem! { self.player?.replaceCurrentItemWithPlayerItem(self.playerItem!) } } // MARK: - Key Value Observing override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer ) { if context == AVPlayerDemoPlaybackViewControllerStatusObservation { let status:Int = (change![NSKeyValueChangeNewKey]?.integerValue)! if status == AVPlayerStatus.ReadyToPlay.rawValue { self.player?.play() } } else if context == AVPlayerDemoPlaybackViewControllerCurrentItemObservationContext { let newPlayerItem = change![NSKeyValueChangeNewKey] as? AVPlayerItem if newPlayerItem != nil { self.playerView?.setPlayer(self.player!) self.playerView?.setVideoFillMode(AVLayerVideoGravityResizeAspect) } } else { super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context) } } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { // Get the new view controller using segue.destinationViewController. // Pass the selected object to the new view controller. } */ }
看起来http://iosguy.com/2012/01/11/multiple-video-playback-on-ios/是目前最好的解决方案。 没有人试图迅速转换它。
我一次在我的应用中播放多个video,我只使用多个AVPlayer实例。