同时播放2个视频Swift

时间:2015-11-05 12:12:58

标签: ios swift video-streaming

我试图用iphone快速同时播放两个视频。我已经知道AV播放器一次只能传输一个视频,但谷歌搜索它我看到它仍然可以同时流式传输不同的音轨。我也看到了画中画的实现。真正的问题是,所有这些都是客观的,而且代码很老。我试图理解它按原样运行代码,但是有错误,有些函数已被弃用。 有人知道如何在swift中做到这一点吗?此外,我从互联网流式传输视频,因此在播放前合并它们不是一种选择。 谢谢!

3 个答案:

答案 0 :(得分:2)

Swift版本

您引用的article是一种在iOS中处理多个视频播放的有趣方法。这篇文章似乎与Apple的Stitched Stream Player Sample Project有关。作为Swift 2.2中的练习,我在iOS Guy文章中重写了代码。

您可以在my gist上的Swift中找到视图和视图控制器。我正在下面复制,因为最好不要在SO上使用仅链接答案。

自定义视图播放器

此自定义视图播放器允许用户换出多个AVPlayerItem(s)。

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
    }

}

多个视频播放器视图控制器

此控制器管理不同AVPlayerItem(s)的分发和呈现。检查my 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<Void>()
    var AVPlayerDemoPlaybackViewControllerCurrentItemObservationContext = UnsafeMutablePointer<Void>()
    var AVPlayerDemoPlaybackViewControllerStatusObservation = UnsafeMutablePointer<Void>()

    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<Void>) {

        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.
    }
    */

}

答案 1 :(得分:1)

我一次在我的应用中播放多个视频,我只使用多个AVPlayer实例。

答案 2 :(得分:0)

目前看来http://iosguy.com/2012/01/11/multiple-video-playback-on-ios/是最佳解决方案。没有人试图快速转换它。