[iOS][Swift 3] 超簡単にカメラ及びビデオの撮影機能が実装可能なSwiftyCam

1 はじめに

SwiftyCamは、超簡単にアプリに写真とビデオの撮影機能を組み込むことができるフレームワークです。

https://github.com/Awalz/SwiftyCam

SwiftyCamは、AVFoundationAVCaptureSessionを中心に作成されており、カメラ撮影にについてはAVCaptureStillImageOutput、ビデオ撮影については、AVCaptureMovieFileOutputで実装されています。

(1) 動作要件及びバージョン

動作要件
iOS 8.0+
Swift 3.0+

2017年4月現在、最新バージョンは、2.2.1です。

(2) CocoaPods

SwiftyCamは、BSD licenseで公開されており、CocoaPodsで簡単にインストールが可能です。

pod "SwiftyCam"

参考:CocoaPodsによる、外部ライブラリの利用と作成

ライブラリの導入後は、下記のインポートで利用可能になります。

import SwiftyCam

(3) info.plist

iOS 10以降では、info.plistにカメラとマイクの使用理由を記載する必要があります。

<key>NSCameraUsageDescription</key>
<string>カメラを使用する理由</string>
<key>NSMicrophoneUsageDescription</key>
<string>マイクを使用する理由</string>

(4) 検証環境

今回検証した環境は、以下のとおりです。

Version
Xcode 8.3
Swift 3.1
CocoaPods 1.2.0
iOS 10.3.1

2 導入

機能を組み込みたいビューコントローラーで、基底クラスをUIViewControllerからSwiftyCamViewControllerに置き換えます。

以下は、Single View Applicationで新規に作成したアプリケーションのトップページとなるViewControllerを置き換えている例です。

class ViewController: SwiftyCamViewController {

ビューは、これだけの作業でカメラのプレビュー画面になります。

また、SwiftyCamViewControllerには、UIPinchGestureRecognizerや、UITapGestureRecognizerが設定されており、下記の操作で、動作する機能があらかじめ実装されています。

操作 機能
シングルタップ ピントフォーカス
ダブルタップ 前後のカメラ切替え
ピッチ ズーム

001 002

2 操作

SwiftyCamで写真や、ビデオを撮影するのは、非常に簡単です。

(1) 写真の撮影

// シャッター音が鳴り、写真の撮影を行います
takePhoto()

撮影した画像の取得は、後述するdelegateメソッドで行います。

(2) ビデオの撮影開始・終了

// ビデオの撮影を開始します
startVideoRecording()

// ビデオの撮影を終了します
stopVideoRecording()

こちらも、撮影したビデオの処理は、後述のdelegateメソッドで行います。

3 delegate

撮影した写真やビデオを取得するには、SwiftyCamViewControllerDelegateを実装し、cameraDelegateに設定する必要があります。

class ViewController : SwiftyCamViewController, SwiftyCamViewControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        cameraDelegate = self
    }
    ...
}

SwiftyCamViewControllerDelegateで処理できるメソッドは以下のとおりです。

func swiftyCam(_ swiftyCam: SwiftyCamViewController, didTake photo: UIImage) {
     // takePhoto()で写真撮影をした時に、このメソッドが呼ばれます
     // 撮影データは、(photo: UIImage)で受け取ることができます
}

func swiftyCam(_ swiftyCam: SwiftyCamViewController, didBeginRecordingVideo camera: SwiftyCamViewController.CameraSelection) {
     // startVideoRecording()で、ビデオ撮影を開始した時に、このメソッドが呼ばれます
}

func swiftyCam(_ swiftyCam: SwiftyCamViewController, didFinishRecordingVideo camera: SwiftyCamViewController.CameraSelection) {
     // stopVideoRecording()で、ビデオ撮影を終了した時に、このメソッドが呼ばれます
}

func swiftyCam(_ swiftyCam: SwiftyCamViewController, didFinishProcessVideoAt url: URL) {
     // ビデオ撮影を終了し、ビデオの処理が終わった時に、このメソッドが呼ばれます
     // 撮影データは、(url: URL)で受け取ることができます
}

func swiftyCam(_ swiftyCam: SwiftyCamViewController, didFocusAtPoint point: CGPoint) {
     // プレビュー画面でタップジェスチャーを開始したときに呼ばれます
     // タップ位置は、(point:CGPoint)で受け取ることができます
}

func swiftyCam(_ swiftyCam: SwiftyCamViewController, didChangeZoomLevel zoom: CGFloat) {
     // プレビュー画面でピンチジェスチャーを開始したときに呼ばれます
     // ズームレベルは、(zoom: CGFloat)で受け取ることができます
}

func swiftyCam(_ swiftyCam: SwiftyCamViewController, didSwitchCameras camera: SwiftyCamViewController.CameraSelection) {
    // カメラを切り替えた時、呼ばれます
    // 現在のカメラ選択は、(SwiftyCamViewController.CameraSelectionで受け取ることができます
}

4 設定

公開されている変数には、下記のようなものがあります。

SwiftyCamButtonが使用されている場合の最大ビデオ時間

public var maximumVideoDuration : Double     = 0.0

ビデオのクオリティ

public var videoQuality : VideoQuality       = .high

フラッシュの有効・無効

public var flashEnabled                      = false

ピッチ操作によるズームの有効・無効

public var pinchToZoom                       = true

ピッチ操作によるズームの最大値

public var maxZoomScale                      = CGFloat(4.0)

タップ操作によるフォーカスの有効・無効

public var tapToFocus                        = true

低照度時の自動調整の有効・無効(iPhone 5 及び iPhone 5Cのみ)

public var lowLightBoost                     = true

他のアプリケーションのバックグラウンドオーディオを許可するかどうか

public var allowBackgroundAudio              = true

ダブルタップによるカメラ切り替えの有効・無効

public var doubleTapCameraSwitch            = true

デフォルトのカメラ(前後)

public var defaultCamera                   = CameraSelection.rear

撮影データをデバイスの向きに合わせるかどうかの設定

public var shouldUseDeviceOrientation      = false

以下は、読み込み専用です。

撮影中かどうか

private(set) public var isVideoRecording      = false

AVCaptureSessionがRun状態かどうか

private(set) public var isSessionRunning     = false

現在使用中のカメラセッション

private(set) public var currentCamera        = CameraSelection.rear

5 SwiftyCamButton

SwiftyCamでは、タップで撮影、長押しでビデオ撮影が可能になるSwiftyCamButtonというボタンが提供されています。

SwiftyCamButtonは、UIButtonのサブクラスですので、ストーリーボードでUIButtonを配置して、Custom Classを変更することで利用できます。 なお、配置しただけでは、カメラのプレビューの下になって見えないので、ビューの一番上に移動しておきます。

003 004

ということで、SwiftyCamを使用して、カメラとビデオを実装するコードは、以下のようになります。

import UIKit
import SwiftyCam

class ViewController: SwiftyCamViewController, SwiftyCamViewControllerDelegate {

    @IBOutlet weak var swiftyCamButton: SwiftyCamButton!

    override func viewDidLoad() {
        super.viewDidLoad()

        cameraDelegate = self

        swiftyCamButton.delegate = self
        view.bringSubview(toFront: swiftyCamButton) // カメラのプレビューより上に配置する
    }

    func swiftyCam(_ swiftyCam: SwiftyCamViewController, didTake photo: UIImage) {
        print("写真が撮影されました")
    }

    func swiftyCam(_ swiftyCam: SwiftyCamViewController, didFinishProcessVideoAt url: URL) {
        print("ビデオが撮影されました")
    }

}

6 最後に

今回は、Swift 3から利用可能な、カメラ及びビデオ撮影のフレームワークを試してみました。 もちろん、軽易に撮影機能を組み込めるのもありますが、フラッシュやズームなど一通りの機能が実装されており、コードを覗かせて頂いて非常に勉強になりました。AVCaptureSession周りの学習用にもお薦めです。

7 参考リンク

https://github.com/Awalz/SwiftyCam
API Reference AVCaptureSession

  • MCまっす〜

    SwiftyCam2.4.0だとbringSubviewToFrontでボタンが前に来なくなりました。。。2.2.xに戻すと表示出来たので、謎です。残念ですね。

    • しょーの

      2.6.0で解消されています。bringSubview呼ばなくても前面表示されるようになっていますね。
      https://github.com/Awalz/SwiftyCam/releases

      • MCまっす〜

        先日GitHubで一気に更新がありましたね。良さそうです。