Swift 視頻錄製之調用網路攝影機錄影,並儲存到系統相簿例子

來源:互聯網
上載者:User

1,技術介紹

(1)AVFoundation.framework 架構提供了 AVCaptureSession 類。使用它可以實現視頻捕獲功能。
(2)使用 AVCaptureVideoPreviewLayer 可以將網路攝影機拍攝的畫面即時顯示在 ViewController 上。
(3)對於捕獲到的視頻,我們使用 AVCaptureMovieFileOutput 將其輸出到檔案中。

2,下面實現一個錄影功能

(1)點擊“開始”按鈕,開始錄製視頻。預設先儲存到 Documents 目錄下,命名為 temp.mp4。
(2)點擊“停止”按鈕,停止視頻錄製。將錄製好的錄影再轉存到系統照片庫中。

3,效果圖如下:


4,範例代碼

import UIKit
import AVFoundation
import Photos
 
class ViewController: UIViewController , AVCaptureFileOutputRecordingDelegate {
    
    //視頻捕獲會話。它是input和output的橋樑。它協調著intput到output的資料轉送
    let captureSession = AVCaptureSession()
    //視頻輸入裝置
    let videoDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
    //音訊輸入裝置
    let audioDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeAudio)
    //將捕獲到的視頻輸出到檔案
    let fileOutput = AVCaptureMovieFileOutput()
    
    //開始、停止按鈕
    var startButton, stopButton : UIButton!
    //表示當時是否在錄影中
    var isRecording = false
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //添加視頻、音訊輸入裝置
        let videoInput = try! AVCaptureDeviceInput(device: self.videoDevice)
        self.captureSession.addInput(videoInput)
        let audioInput = try! AVCaptureDeviceInput(device: self.audioDevice)
        self.captureSession.addInput(audioInput);
        
        //添加視頻捕獲輸出
        self.captureSession.addOutput(self.fileOutput)
        
        //使用AVCaptureVideoPreviewLayer可以將網路攝影機的拍攝的即時畫面顯示在ViewController上
        let videoLayer = AVCaptureVideoPreviewLayer(session: self.captureSession)
        videoLayer.frame = self.view.bounds
        videoLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
        self.view.layer.addSublayer(videoLayer)
        
        //建立按鈕
        self.setupButton()
        //啟動session會話
        self.captureSession.startRunning()
    }
    
    //建立按鈕
    func setupButton(){
        //建立開始按鈕
        self.startButton = UIButton(frame: CGRectMake(0,0,120,50))
        self.startButton.backgroundColor = UIColor.redColor();
        self.startButton.layer.masksToBounds = true
        self.startButton.setTitle("開始", forState: .Normal)
        self.startButton.layer.cornerRadius = 20.0
        self.startButton.layer.position = CGPoint(x: self.view.bounds.width/2 - 70,
                                                  y:self.view.bounds.height-50)
        self.startButton.addTarget(self, action: #selector(onClickStartButton(_:)),
                                   forControlEvents: .TouchUpInside)
        
        //建立停止按鈕
        self.stopButton = UIButton(frame: CGRectMake(0,0,120,50))
        self.stopButton.backgroundColor = UIColor.grayColor();
        self.stopButton.layer.masksToBounds = true
        self.stopButton.setTitle("停止", forState: .Normal)
        self.stopButton.layer.cornerRadius = 20.0
        
        self.stopButton.layer.position = CGPoint(x: self.view.bounds.width/2 + 70,
                                                 y:self.view.bounds.height-50)
        self.stopButton.addTarget(self, action: #selector(onClickStopButton(_:)),
                                  forControlEvents: .TouchUpInside)
        
        //添加按鈕到視圖上
        self.view.addSubview(self.startButton);
        self.view.addSubview(self.stopButton);
    }
    
    //開始按鈕點擊,開始錄影
    func onClickStartButton(sender: UIButton){
        if !self.isRecording {
            //設定錄影的儲存地址(在Documents目錄下,名為temp.mp4)
            let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory,
                                                            .UserDomainMask, true)
            let documentsDirectory = paths[0] as String
            let filePath : String? = "\(documentsDirectory)/temp.mp4"
            let fileURL : NSURL = NSURL(fileURLWithPath: filePath!)
            //啟動視頻編碼輸出
            fileOutput.startRecordingToOutputFileURL(fileURL, recordingDelegate: self)
            
            //選項組:錄影中...
            self.isRecording = true
            //開始、結束按鈕顏色改變
            self.changeButtonColor(self.startButton, color: UIColor.grayColor())
            self.changeButtonColor(self.stopButton, color: UIColor.redColor())
        }
    }
    
    //停止按鈕點擊,停止錄影
    func onClickStopButton(sender: UIButton){
        if self.isRecording {
            //停止視頻編碼輸出
            fileOutput.stopRecording()
            
            //選項組:錄影結束
            self.isRecording = false
            //開始、結束按鈕顏色改變
            self.changeButtonColor(self.startButton, color: UIColor.redColor())
            self.changeButtonColor(self.stopButton, color: UIColor.grayColor())
        }
    }
    
    //修改按鈕的顏色
    func changeButtonColor(target: UIButton, color: UIColor){
        target.backgroundColor = color
    }
    
    //錄影開始的代理方法
    func captureOutput(captureOutput: AVCaptureFileOutput!,
                       didStartRecordingToOutputFileAtURL fileURL: NSURL!,
                       fromConnections connections: [AnyObject]!) {
    }
    
    //錄影結束的代理方法
    func captureOutput(captureOutput: AVCaptureFileOutput!,
                       didFinishRecordingToOutputFileAtURL outputFileURL: NSURL!,
                       fromConnections connections: [AnyObject]!, error: NSError!) {
        var message:String!
        //將錄製好的錄影儲存到照片庫中
        PHPhotoLibrary.sharedPhotoLibrary().performChanges({
            PHAssetChangeRequest.creationRequestForAssetFromVideoAtFileURL(outputFileURL)
            }, completionHandler: { (isSuccess: Bool, error: NSError?) in
                if isSuccess {
                    message = "儲存成功!"
                } else{
                    message = "儲存失敗:\(error!.localizedDescription)"
                }
                
                dispatch_async(dispatch_get_main_queue(), {
                    //彈出提示框
                    let alertController = UIAlertController(title: message,
                        message: nil, preferredStyle: .Alert)
                    let cancelAction = UIAlertAction(title: "確定", style: .Cancel, handler: nil)
                    alertController.addAction(cancelAction)
                    self.presentViewController(alertController, animated: true, completion: nil)
                })
        })
    }
}

 

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.