やることは Objective-c でやる内容を Swift で書くだけではあります。100 行くらいでできましたのでメモ。最後にコードを一式貼り付けています。
やること
- 必要な framework の追加
- Session, Device の準備
- プレビュー画面の生成
- 録画ボタンで録画開始
- 停止ボタンで録画停止、ライブラリに保存
必要な framework の追加
AVFoundation と AssetsLibrary を追加します。
Session, Device の準備
iOS では録画時のメディアは AVCaptureSession というクラスが管理します。AVCaptureSession に入力、出力情報を渡します。
参考:AVCaptureSession
https://developer.apple.com/library/ios/documentation/avfoundation/reference/AVCaptureSession_Class/index.html
映像はデフォルトのカメラ(iPhone6 だと背面カメラでした)、音声もデフォルトのマイクを使用します。
ファイルとして保存するので AVCaptureMovieFileOutput を使います。
ここでは default device を使いましたが前面カメラを使う、カメラの切り替えを行いたい場合は Device の列挙などから選択する必要があります。
let captureSession = AVCaptureSession()
let videoDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
let audioDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeAudio)
let fileOutput = AVCaptureMovieFileOutput()
生成した Device から AVCaptureDeviceInput を生成して AVCaptureSession に追加します。
出力先となる AVCaptureMovieFileOutput も追加します。
let videoInput = AVCaptureDeviceInput.deviceInputWithDevice(self.videoDevice, error: nil) as AVCaptureDeviceInput
self.captureSession.addInput(videoInput)
let audioInput = AVCaptureDeviceInput.deviceInputWithDevice(self.audioDevice, error: nil) as AVCaptureInput
self.captureSession.addInput(audioInput);
self.captureSession.addOutput(self.fileOutput)
#. プレビュー画面の生成
カメラからの映像を ViewController に表示するのに AVCaptureVideoPreviewLayer を使います。
ここでは画面いっぱいに表示しています。
let videoLayer : AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer.layerWithSession(self.captureSession) as AVCaptureVideoPreviewLayer
videoLayer.frame = self.view.bounds
videoLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
self.view.layer.addSublayer(videoLayer)
#. 録画ボタンで録画開始
ViewController 上に配置した録画ボタンを押されたら録画開始処理を行います(ボタンを設置するコードなどは最後に載せています)。
録画データを保存するパスを決めて、 startRecordingToOutputFileURL を呼び出します。
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)
#. 停止ボタンで録画停止、ライブラリに保存
録画を停止する時は stopRecording を呼び出します。
fileOutput.stopRecording()
録画が停止した時は AVCaptureFileOutputRecordingDelegate の下記メソッドが呼ばれるのでその中でライブラリへ保存する処理を行います。
func captureOutput(captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAtURL
outputFileURL: NSURL!, fromConnections connections: [AnyObject]!, error: NSError!) {
let assetsLib = ALAssetsLibrary()
assetsLib.writeVideoAtPathToSavedPhotosAlbum(outputFileURL, completionBlock: nil)
}
ソースコード
プロジェクトを作って、ViewController のクラスに下記を貼り付けるとそのまま動くと思います。
環境:XCode 6.1, iOS 8.1 で確認
import UIKit
import AVFoundation
import AssetsLibrary
class CaputureViewController: UIViewController, AVCaptureFileOutputRecordingDelegate {
var index = 2
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 = AVCaptureDeviceInput.deviceInputWithDevice(self.videoDevice, error: nil) as AVCaptureDeviceInput
self.captureSession.addInput(videoInput)
let audioInput = AVCaptureDeviceInput.deviceInputWithDevice(self.audioDevice, error: nil) as AVCaptureInput
self.captureSession.addInput(audioInput);
self.captureSession.addOutput(self.fileOutput)
let videoLayer : AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer.layerWithSession(self.captureSession) as AVCaptureVideoPreviewLayer
videoLayer.frame = self.view.bounds
videoLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
self.view.layer.addSublayer(videoLayer)
self.setupButton()
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("start", 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: "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("stop", 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: "onClickStopButton:", forControlEvents: .TouchUpInside)
self.view.addSubview(self.startButton);
self.view.addSubview(self.stopButton);
}
func onClickStartButton(sender: UIButton){
if !self.isRecording {
// start recording
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!) {
let assetsLib = ALAssetsLibrary()
assetsLib.writeVideoAtPathToSavedPhotosAlbum(outputFileURL, completionBlock: nil)
}
}