1. 程式人生 > >iOS GPUImage研究五:短視訊拍攝(濾鏡、檔案寫入)

iOS GPUImage研究五:短視訊拍攝(濾鏡、檔案寫入)

希望這個Demo,可以給大家在視訊濾鏡製作上帶來一些靈感、避免重複造輪子。也希望大家轉載的時候帶上原文地址,算是對原創的鼓勵。

最下方有Demo地址
執行環境Xcode7.3.1

這個Demo應該是對GPUImage的總結吧,包含了視訊寫入,濾鏡資訊讀取。前面幾篇文章也分別對GPUImage中常用的功能進行了分別介紹。雖說GPUImage是開源的,但對初學者來講上手還是有一定難度的,希望可以幫助大家。

在GPUImage的探索的道路上依舊還未停止。

這裡寫圖片描述

需求:

序號 描述
1. 實現畫面獲取:使用GPUImageMovieCamera
2. 實現畫面呈現:使用GPUImageView
3. 實現美顏濾鏡:包含讀取影象顏色矩陣,以及GPUImage自帶濾鏡組合和網上流傳的美顏濾鏡
4. 實現實時濾鏡視訊處理:使用GPUImageMovieWriter
5. 實現儲存到相簿,並播放。
6. 簡單地切換動畫,讓過程看起來更自然。

效果如圖 :

這裡寫圖片描述偏微黃濾鏡![這裡寫圖片描述]

Demo目錄:

這裡寫圖片描述

相關類 說明:
Frameworks 是使用GPUImage的必須依賴庫。
GPUImageCustomLookupFilter 是將讀取圖片資訊並將之轉化為濾鏡 的關鍵類。也包含一些我自己的濾鏡組合,包含魚眼濾鏡、水晶球濾鏡、放行濾鏡、浮雕、反魚眼等。
FSKVideoFilterVc 是主控制器,包含切換攝像頭、視訊濾鏡寫入、視訊錄製播放、儲存相簿、切換濾鏡、以及組合濾鏡的使用方法。
SkVideoFilterView 是濾鏡的檢視,繼承collectionview,一共包含大概30種組合濾鏡。
FilterModel 是濾鏡Model,處理濾鏡名稱定義,以及濾鏡列表的初始化。
SSGPUImageBeautyFilter 就是GPUImageBeautifulFilter,只是換了個名字而已。
MyLayout 是一個繼承UICollectionViewFlowLayout的佈局類,一個是擁有縮放效果的佈局方式,後來我把縮放效果調成了0,因為綜合效果的原因。
 CGFloat distance = offset - attribute.center.x;
        // 越往中心移動,值越小,那麼縮放就越小,從而顯示就越大
        // 同樣,超過中心後,越往左、右走,縮放就越大,顯示就越小
        CGFloat scaleForDistance = distance / self.itemSize.height;
        // 可調整,值越大,顯示就越大
        CGFloat scaleForCell = 1 + 0 * (1 - fabs(scaleForDistance));

        // only scale y-axis
        attribute.transform3D = CATransform3DMakeScale(1, scaleForCell, 1);
        attribute.zIndex = 1;

可通過調節0 * (1 - fabs(scaleForDistance));來改變效果。

StoryBoard說明:

這裡寫圖片描述

storyboard具備快速開發的優點,除了實時變化相對於程式碼差一點,其他的他已經很成熟、也是偉大的開發模式、在這裡也希望那些老傢伙們別固執與程式碼佈局,緊隨時代吧!
特別提示:注意Mylayout的位置 很重要

這裡寫圖片描述

初始化相機和GPUImageview:

func setNewCameraAndGPUViewAndStart() {
        videoCamera = GPUImageVideoCamera.init(sessionPreset: AVCaptureSessionPreset640x480, cameraPosition: AVCaptureDevicePosition.Front)
        videoCamera.outputImageOrientation = UIInterfaceOrientation.Portrait
        videoCamera.horizontallyMirrorFrontFacingCamera = true
        videoCamera.horizontallyMirrorRearFacingCamera = true

        filter = SSGPUImageBeautyFilter.init()

        filterView = self.view as! GPUImageView
        filterView.fillMode = kGPUImageFillModePreserveAspectRatioAndFill
        videoCamera.addTarget(filter as GPUImageInput)
        filter.addTarget(filterView)

        videoCamera.startCameraCapture()

    }

初始化寫入物件:

func getNewMovieWriter() {

        let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory,
                                                        .UserDomainMask, true)
        let documentsDirectory = paths[0] as String
        let filePath : String? = "\(documentsDirectory)/DBLiveTest\(currentTimeStamp()).mp4"
        movieURL = NSURL(fileURLWithPath: filePath!)


        movieWriter = GPUImageMovieWriter.init(movieURL: movieURL, size: CGSizeMake(480.0, 640.0))
        movieWriter.encodingLiveVideo = true
        if groupFilter == nil {
            filter.addTarget(movieWriter)

        }else{
            self.groupFilter?.addTarget(movieWriter)

        }
        videoCamera.audioEncodingTarget = movieWriter

    }

切換濾鏡

//換濾鏡
    func switchFilter(index: Int) {
        self.filter?.removeAllTargets()
        self.groupFilter?.removeAllTargets()
        self.currentFilterIndex = index
        let lookupImageName = self.filterModel.filterList[index].lookupImageName

        self.lookupFilter = GPUImageCustomLookupFilter.init(lookupImageName: lookupImageName)
        self.setUpGroupFilters(self.lookupFilter!)
        self.groupFilter?.addTarget(filterView)



        self.groupFilter?.addTarget(movieWriter)

    }

    func setUpGroupFilters(lookupFilter: GPUImageCustomLookupFilter) {
        self.groupFilter = GPUImageFilterGroup.init()
        self.groupFilter?.addTarget(filter)
        self.filter?.addTarget(lookupFilter)
        self.groupFilter?.initialFilters = [self.filter!]
        self.groupFilter?.terminalFilter = lookupFilter
    }

播放視訊

func playVideoAndAddPreView() {
        dispatch_async(dispatch_get_main_queue()) {

            let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory,.UserDomainMask, true)
            let documentsDirectory = paths[0] as String
            let filePath1 : String? = "\(documentsDirectory)/DBLiveTest\(currentTimeStamp()).jpg";

            UIImagePNGRepresentation(getFirstImageFromVideo(self.movieURL))?.writeToFile(filePath1!, atomically: true);

            self.thumbURL = NSURL(fileURLWithPath: filePath1!)

            animationFlipFromRight(self.filterView)
            self.videoCamera.stopCameraCapture()

            self.playerItem = AVPlayerItem(URL: self.movieURL)
            // 建立 AVPlayer 播放器
            self.player = AVPlayer(playerItem: self.playerItem)
            // 將 AVPlayer 新增到 AVPlayerLayer 上
            self.playerLayer = AVPlayerLayer(player: self.player)
            // 設定播放頁面大小
            self.playerLayer.frame = self.view.frame
            // 設定畫面縮放模式
            self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
            // 在檢視上新增播放器
            self.view.layer.addSublayer(self.playerLayer)
            // 開始播放
            self.player.play()
            self.addPreViewToSufureView()
        }
    }

儲存到相簿:

func doYouWantSaveItToAlbum(bool:Bool) {
        if bool == true {
            let library = ALAssetsLibrary()

            if library.videoAtPathIsCompatibleWithSavedPhotosAlbum(movieURL) {
                library.writeVideoAtPathToSavedPhotosAlbum(movieURL, completionBlock: { (assetURL, error) in
                    dispatch_async(dispatch_get_main_queue(), {
                        if error == nil{
                            let alert = UIAlertView.init(title: "提示訊息", message: "儲存成功", delegate: nil, cancelButtonTitle: "確定")
                            alert.show()
                        }else{
                            let alert = UIAlertView.init(title: "提示訊息", message: "儲存失敗", delegate: nil, cancelButtonTitle: "確定")
                            alert.show()
                        }
                    })
                })
            }

        }
    }

用到的全域性方法:

//翻轉動畫
func animationFlipFromLeft(view:UIView) {
    UIView.beginAnimations(nil, context: nil)
    UIView.setAnimationCurve(UIViewAnimationCurve.EaseInOut)
    UIView.setAnimationDuration(0.5)
    UIView.setAnimationTransition(UIViewAnimationTransition.FlipFromLeft, forView: view, cache: false)
    UIView.commitAnimations()
}

//翻轉動畫
func animationFlipFromRight(view:UIView) {
    UIView.beginAnimations(nil, context: nil)
    UIView.setAnimationCurve(UIViewAnimationCurve.EaseInOut)
    UIView.setAnimationDuration(0.5)
    UIView.setAnimationTransition(UIViewAnimationTransition.FlipFromRight, forView: view, cache: false)
    UIView.commitAnimations()
}

//時間戳
func currentTimeStamp()->String {
    let now = NSDate()
    let dformatter = NSDateFormatter()
    dformatter.dateFormat = "yyyy年MM月dd日 HH:mm:ss"
    print("當前日期時間:\(dformatter.stringFromDate(now))")



    //當前時間的時間戳
    let timeInterval:NSTimeInterval = now.timeIntervalSince1970
    let timeStamp = Int(timeInterval)

    return String(timeStamp)

}
//獲取視訊第一幀
func getFirstImageFromVideo(videoUrl:NSURL)->(UIImage){


    let asset = AVURLAsset(URL:videoUrl)

    let generator = AVAssetImageGenerator(asset: asset)

    generator.appliesPreferredTrackTransform=true

    let time = CMTimeMakeWithSeconds(0.0,600)

    var actualTime:CMTime = CMTimeMake(0,0)

    var image:CGImageRef!

    do{
        image = try generator.copyCGImageAtTime(time, actualTime: &actualTime)
    }catch let error as NSError{
        print(error)
    }

    return UIImage(CGImage: image)


}

模糊效果:

//新增模糊效果
    func addVisualEffectView() {
        self.effectView = UIVisualEffectView.init(effect: UIBlurEffect.init(style: UIBlurEffectStyle.Light));
        self.view.addSubview(self.effectView)
        self.effectView.frame = self.view.bounds
    }

相關推薦

iOS GPUImage研究短視拍攝(檔案寫入)

希望這個Demo,可以給大家在視訊濾鏡製作上帶來一些靈感、避免重複造輪子。也希望大家轉載的時候帶上原文地址,算是對原創的鼓勵。 最下方有Demo地址 執行環境Xcode7.3.1 這個Demo應該是對GPUImage的總結吧,包含了視訊寫入,濾鏡資訊讀取。

iOS GPUImage研究為視訊檔案新增

本文介紹,在GPUImage中為新增視訊檔案使用GPUImageMovieWriter的方法。 情況 內容 情況一 實時濾鏡處理 情況二 視訊檔案處理 情況一:實時濾鏡處理 上篇文章程式

短視開發短視原始碼可結合全鏈路的視訊雲服務一站式解決

實際上,網際網路的內容行業正在進階,從文字、圖片到視訊、直播,再到能填補使用者碎片時間的短視訊開發,這是一個趨於互動性、實時性的迭代。從4G普及、資費下調、編解碼技術進步和移動硬體的品質提升,也為短視訊的發展提供了良好客觀因素。從產品形態層面看,短視訊本身也擁有創作門檻低、內容精煉、易於發酵等屬性,更易於傳播

必做作業三短視原型化系統

原型化系統線上執行地址:https://modao.cc/app/BIndp3p636lx9GS6bbQEF28EIqzyKq5 硬體要求 :chrome 68版 1     產品設計思路   該原型主要是五個部分,分別是首頁、關注、拍攝、訊息、我。基本完成MVP(Minimum Viable Produc

短視訊APP開發短視特效SDK功能火爆來襲!

為什麼短視訊這麼火呢?因為它符合了使用者碎片化時間的需求,既娛樂了大眾,又不會浪費使用者太多時間。短視訊APP開發以網際網路技術為核心,在原有的基礎上不斷進行創新,進而擁有多種強大的拍攝功能,讓使用者可以快速拍攝出視訊。短視訊APP開發製作功能優勢介紹:1、基礎功能小視訊拍攝

Zabbix()高級應用-web方案被動監控基於snmp協議被動監控proxy配置測試實例

zabbix proxy1.web方案web scenario:web監控方案,web場景;web scenarios指的是監控指定的web站點的資源下載及頁面響應時間等數據指標;(1)創建web監控需要先定義一個web scenario(方案):一個web方案包括一個或多個HTTP請求或步驟(steps)

Android中的自繪View的那些事兒()之 遮罩BlurMaskFilter 和 EmbossMaskFilter 的簡介

MaskFilter MaskFilter翻譯過來叫遮罩濾鏡,它可以為Paint邊緣的alpha通道應用轉換。目前有兩個子類:BlurMaskFilter 和 EmbossMaskFilter。它們分別可實現出模糊效果和浮雕效果。 BlurMaskFilter BlurM

圖像編程混合模式遮罩

代碼 net lan mat 濾鏡 color 圖層混合模式 來源 src 濾鏡 濾鏡是對圖片中每個像素進行裝換的過程。例如,遊戲中的濾鏡經常是這樣的: var colorMatrix = [ 0.3,0.6,0,0,0, 0.3,0.6,0,0,0,

[Swift通天遁地]四網路和執行緒-(10)處理圖片壓縮縮放圓角CoreImage快取

本文將演示在第三方類庫中,用來處理圖片的一些強大功能。 首先確保在專案中已經安裝了所需的第三方庫。 點選【Podfile】,檢視安裝配置檔案。 1 platform :ios, ’12.0’ 2 use_frameworks! 3 4 target 'DemoApp' do 5

ps例項二使用高斯製作圖片陰影效果?

例項二:使用高斯濾鏡製作圖片陰影效果 1、ctrl+單擊圖層,選中圖片選區; 2、在該圖層下面,新建一圖層; 3、填充灰色:alt+delete(如果快捷鍵不行,就用油漆桶填充也行) 4、ctrl+Del:取消選區; 5、選中灰色圖層,濾鏡-》高斯濾鏡; 6、移動圖層到合適

iOS二十種超酷時尚藝術彙總【附原始碼】

本文總結了20種ios濾鏡都是基於GPUImage的,有3種濾鏡是GPUImage庫中包含的,還有17種是Instagram中的經典濾鏡,整合在一個專案中。使用GPUImage可以非常容易建立我們自己的濾鏡效果總會有你想要的效果吧。在文章下面附原始碼下載   相信你也在

positionrelative解決filter問題

一、解決背景自動拉伸帶來的連結失效的問題。 ­     比如在表格中使用style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='背景圖片地址', sizingMethod='scale')"可

ffdshow 原始碼分析 5 點陣圖覆蓋(總結)

=====================================================ffdshow原始碼分析系列文章列表:=====================================================前面寫了三篇文章,介紹了 

LIVE555研究RTPServer(二)

tpch live555 循環調用 family 每一個 函數 計算 ack close LIVE555研究之五:RTPServer(二) 接上文,main函數的幾行代碼創建了RTSPSe

有獎科大飛AI研究

href dfs .cn zju pos logs hvm amp log m690mk銥孜喚蛋賭倩http://blog.sina.com.cn/s/blog_17daf74b80102xo2t.htmljbi1bu欠咎撈濫堵墩http://blog.sina.com.c

研究到應用AI Lab的自然語言理解和生成

智能語言 AI 3月16日在騰訊AILab第二屆學術論壇上,騰訊AI Lab高級研究員李菁博士介紹了實驗室目前在NLP方面重點關註的兩大方向——如何理解和生成自然語言,並介紹了實驗室的相關研究和應用成果。自然語言的理解自然語言理解的目標是使得機器能夠像人一樣進行閱讀。機器不能像人一樣通過直覺和感知來理

科學研究設計實驗設計

說明 這是Bangor University 2007年School of Sport Health & Exercise Sciences的教學講義,大家可以在這裡檢視原課程的講義 課程目錄 1.什麼是科學? 2.定量分析和定性分析 3.抽樣

131群毆還不贏,騰短視真是扶不起來的阿斗?

馬化騰在短視訊領域的野心,人盡皆知。 前不久騰訊經歷了歷史上第三次調整架構,調整後有一個有趣的點,“不要以騰訊的名義去做短視訊,同時儘量不要依賴騰訊過去的社交關係網路推進新產品運營。”騰訊這次是360°大變樣,最引以為傲的社交關係網卻不再借助社交,這葫蘆裡賣的是什麼藥呢? 一切還要從

文獻綜述十基於b/s中小型超市進銷存管理系統的研究與設計

一、基本資訊   標題:基於b/s中小型超市進銷存管理系統的研究與設計   時間:2015   出版源:湘西財經大學   檔案分類:對超市管理系統的研究 二、研究背景   在競爭日益激烈的行業中,儘可能降低運營成本,逐步擴大超市經營規模,並帶動銷售増長。 三、具體內容   論文的內容分為6個部分。分別是緒論、

原始碼中iOS短視開發Android短視開發的視訊上傳功能只需要這段原始碼

在原始碼中上傳視訊功能是iOS短視訊開發和Android短視訊開發中不可忽視的中心,看成是APP程式原始碼存在的意義。相信朋友們也能夠理解它在APP開發中的地位,現在這段程式碼就免費提供給大家了。 /*上傳視訊*/   @Override   pu