【问题标题】:Apply Core Image Filter to Video on OS X using Swift使用 Swift 将核心图像过滤器应用于 OS X 上的视频
【发布时间】:2015-08-11 17:22:41
【问题描述】:

我计划使用 SWIFT 为 OS X 应用程序构建一个 NSOpenGLView,它可用于将核心图像过滤器和效果应用于视频,到目前为止,我已经编写了视频控制器的代码以添加视频播放,但是我不确定如何将过滤器应用于视频:

class VideoMediaViewController: NSViewController {

    weak var mainView : DTMainViewController?

    @IBOutlet weak var aVPlayerView: AVPlayerView!

    var  url:NSURL?{
        didSet{
            // this is the setter 


        }
    }


    var observer:AnyObject?

    var player:AVPlayer?

    var videoOutput:AVPlayerItemVideoOutput?

    var  ciContext:CIContext?

    var loadStatus:NSNumber?



    override func viewDidLoad() {

        aVPlayerView.controlsStyle = AVPlayerViewControlsStyle.None

    }

   func loadMedia() {

    unloadMedia()


    //Create AVPlayerItem

    player = AVPlayer.playerWithURL(url) as? AVPlayer

    //Create VideoOutput

    videoOutput = AVPlayerItemVideoOutput(pixelBufferAttributes: [kCVPixelBufferPixelFormatTypeKey:kCVPixelFormatType_32ARGB])


    //Get notifications for status

    player?.addObserver(self, forKeyPath: "status", options:.New, context: nil)


   //looping logic start 

    player?.actionAtItemEnd = AVPlayerActionAtItemEnd.None

    NSNotificationCenter.defaultCenter().addObserver(self,
        selector: "playerItemDidReachEnd:",
        name: AVPlayerItemDidPlayToEndTimeNotification,
        object: player?.currentItem)


    //looping logic end

    observer =  player?.addPeriodicTimeObserverForInterval(CMTimeMake(150, 600),
        queue: dispatch_get_main_queue(),
        usingBlock: {[unowned self](CMTime) in

            self.updateSliderProgress()
            self.updateStartAndEndTimes()
        })


    //Set videoOutput to player

    player?.currentItem.addOutput(videoOutput)

    aVPlayerView.player = player

    aVPlayerView.player.play()

    }

    func playerItemDidReachEnd(notification: NSNotification) {
        let aVPlayerItem: AVPlayerItem = notification.object as! AVPlayerItem
        aVPlayerItem.seekToTime(kCMTimeZero)
    }


    func scrubberSliderChanged(sender: AnyObject){
        var duration:Float64 = CMTimeGetSeconds(player!.currentItem.duration)

        var sliderValue:Float64  =  Float64(mainView!.scrubberSlider!.floatValue)

        var seekToTime = CMTimeMakeWithSeconds(((sliderValue * duration)/100.00), 1)

        player?.seekToTime(seekToTime, completionHandler: { (Bool) -> Void in


        })


    }

    func secondsToHoursMinutesSeconds (seconds : Int) -> (Int, Int, Int) {

        return (seconds / 3600, (seconds % 3600) / 60, (seconds % 3600) % 60)



    }


    func getStringFromHoursMinutesSeconds(h:Int, m:Int, s:Int) -> (String){

        let formatter = NSNumberFormatter()
        formatter.minimumIntegerDigits = 2

        let hours = formatter.stringFromNumber(h) //"00"
        let minutes = formatter.stringFromNumber(m) //"01"
        let seconds = formatter.stringFromNumber(s) //"10"


        var timerString  = hours! + ":" + minutes! + ":" + seconds!

        return timerString

    }



    func updateStartAndEndTimes(){

        var time = CMTimeGetSeconds(player!.currentItem.duration) - CMTimeGetSeconds(player!.currentItem.currentTime())

        var (hours,minutes,seconds) = secondsToHoursMinutesSeconds(Int(time))

        let timeRemainingString = getStringFromHoursMinutesSeconds(hours, m: minutes, s: seconds)

         mainView!.videoTimeRemaing.stringValue = timeRemainingString

         time = CMTimeGetSeconds(player!.currentItem.currentTime())

         (hours,minutes,seconds) = secondsToHoursMinutesSeconds(Int(time))

        let timePassedString = getStringFromHoursMinutesSeconds(hours, m: minutes, s: seconds)

         mainView?.videoTimePassed.stringValue = timePassedString


//         mainView!.videoTimeRemaing.stringValue = "\(CMTimeGetSeconds(player!.currentItem.duration) - CMTimeGetSeconds(player!.currentItem.currentTime()))!"


//        mainView?.videoTimePassed.stringValue = "\(CMTimeGetSeconds(player!.currentItem.currentTime()))!"
    }

    func updateSliderProgress(){

        var currentTime  = CMTimeGetSeconds(player!.currentItem.currentTime())

        var duration = CMTimeGetSeconds(player!.currentItem.duration)

        var progress = currentTime/duration*100

        mainView!.scrubberSlider!.doubleValue = progress
    }


   func unloadMedia() {

    //Cancel Prerolls and Notifications

    player?.cancelPendingPrerolls

    player?.removeTimeObserver(observer)

    player?.removeObserver(self, forKeyPath: "status")

    NSNotificationCenter.defaultCenter().removeObserver(self, name: AVPlayerItemDidPlayToEndTimeNotification, object: nil)

    //dispose of assets and players, etc

    //...

    }

    override func viewWillDisappear() {

        unloadMedia()
    }


    //Get Status updates and log success or failure

    override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {


        if ( (object as! NSObject) == player && keyPath == "status") {

            if (player?.status == .ReadyToPlay) {

                NSLog("Status - Loaded")

            } else if (player?.status == .Failed) {

                NSLog("Status - Failed")

            } else {

                NSLog("Status - Unknown")

            }

        }
    }

但我不明白在哪里以及如何应用核心图像过滤器。我在网上搜索过,但找不到一个完整的例子来做到这一点。

任何帮助将不胜感激,上帝保佑,我很快就能解决:)

【问题讨论】:

    标签: swift cocoa avfoundation core-image core-video


    【解决方案1】:

    其实我想通了..这是一个需要 OS X El Capitan 或更高版本的解决方案..

    let url = NSBundle.mainBundle().URLForResource("skies", withExtension: "mp4”)!
    
    
            let avAsset =  AVAsset(URL: url)
            
           
            
            let vidComp = AVVideoComposition(asset: avAsset,
                applyingCIFiltersWithHandler: {
                
                request in
    
                self.image = request.sourceImage.imageByClampingToExtent();
                    
             
                    
               self.image = (self.image!.imageByApplyingFilter("CIGaussianBlur”,  withInputParameters: [kCIInputRadiusKey: self.blurTestSlider.integerValue])
                
                self.image = self.image!.imageByCroppingToRect(request.sourceImage.extent)
                            
                request.finishWithImage(self.image!, context: self.context)
                
                })
            
            
            let playerItem = AVPlayerItem(asset: avAsset)
            playerItem.videoComposition = vidComp
             player = AVPlayer(playerItem: playerItem)
            
            
            dTMediaViewControllerA?.player = player
             dTMediaViewControllerA?.player.play()
    

    【讨论】:

    • 我自己还没有尝试过,但是您应该能够创建AVVideoCompositing 协议的自定义实现,并将其设置为您的customVideoCompositorClass 上的customVideoCompositorClass,这将使您可以在较旧的操作系统上执行此操作。
    猜你喜欢
    • 2012-04-06
    • 1970-01-01
    • 1970-01-01
    • 2015-11-25
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    • 2017-05-10
    • 1970-01-01
    相关资源
    最近更新 更多