如何在Metal with Swift中显示实时流媒体视频(m3u8)?

时间:2015-12-22 09:05:00

标签: swift metal

我得出结论,视频必须在矩形上呈现为纹理。

为了达到这个目的,我来到了这些步骤:

  1. 我需要从视频中获取当前帧:
    • 我使用过AVPlayerItemVideoOutput,然后调用copyPixelBufferForItemTime
  2. 这是一个简单的ViewController,我已经习惯了这个(我可以看到它正在工作,虽然imageview没有刷新 - 我想我没有正确使用它。)

    class ViewController: UIViewController {
    
    var player: AVPlayer!
    var playerItem: AVPlayerItem!
    var output: AVPlayerItemVideoOutput!
    var displayLink : CADisplayLink!
    var context: CIContext!
    
    @IBOutlet weak var image: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
    
        context = CIContext()
        let asset = AVURLAsset( URL:NSURL(string: "http://vevoplaylist-live.hls.adaptive.level3.net/vevo/ch1/appleman.m3u8")!, options:nil)
        asset.loadValuesAsynchronouslyForKeys(["tracks"]){
    
            var error: NSError?
            let status = asset.statusOfValueForKey("tracks", error: &error)
    
            if (status == AVKeyValueStatus.Loaded)
            {
                let settings: [String: AnyObject] = [kCVPixelBufferPixelFormatTypeKey as String : Int(kCVPixelFormatType_32BGRA)]
                let output = AVPlayerItemVideoOutput(pixelBufferAttributes: settings)
                let playerItem = AVPlayerItem(asset: asset)
                playerItem.addOutput(output)
                let  player = AVPlayer(playerItem: playerItem)
    
                self.player = player
                self.playerItem = playerItem
                self.output = output
    
                self.displayLink = CADisplayLink(target: self, selector: Selector("handleTimer"))
                self.displayLink.frameInterval = 1
                self.displayLink.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)
            }
            else
            {
                print("%@ Failed to load the tracks.")
            }
        }
    
    }
    func handleTimer() {
        let buffer = output.copyPixelBufferForItemTime(playerItem.currentTime(), itemTimeForDisplay:nil)
        if let bufferUnwrapped = buffer{
            let image = CIImage(CVPixelBuffer: bufferUnwrapped)
            let cgiImage = context.createCGImage(image, fromRect: image.extent)
            dispatch_async(dispatch_get_main_queue()){
                self.image.image = UIImage(CGImage: cgiImage)
                self.image.setNeedsDisplay()
            }
        }
    }
    

    }

    1. 第二步是使用pixelBuffer生成纹理 这一步涉及大量代码,我发现的最佳样本来自raywenderlich http://www.raywenderlich.com/93997/ios-8-metal-tutorial-swift-part-3-adding-texture(对于swift 1.2)和来自Waren Moore的代码示例https://github.com/warrenm/slug-swift-metal/tree/master/SwiftMetalDemo
    2. 我没有找到另一种方法(在Metal中的矩形上显示实时流式视频)。有更好的方法吗?

0 个答案:

没有答案