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)
})
})
}
}