iOSアプリでカメラの映像をプレビューして、リアルタイムで画面のフレームレートやカメラのシャッタースピ―ド、iso値を変更できるアプリを作成しました。
swift
1import UIKit 2import AVFoundation 3 4class ViewController: UIViewController{ 5 // デバイスからの入力と出力を管理するオブジェクトの作成 6 var captureSession = AVCaptureSession() 7 8 // カメラの画質の設定 9 func setupCaptureSession() { 10 captureSession.sessionPreset = AVCaptureSession.Preset.photo 11 } 12 // カメラデバイスそのものを管理するオブジェクトの作成 13 // メインカメラの管理オブジェクトの作成 14 var mainCamera: AVCaptureDevice? 15 // インカメの管理オブジェクトの作成 16 var innerCamera: AVCaptureDevice? 17 // 現在使用しているカメラデバイスの管理オブジェクトの作成 18 var currentDevice: AVCaptureDevice? 19 20 // デバイスの設定 21 func setupDevice() { 22 // カメラデバイスのプロパティ設定 23 let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera], mediaType: AVMediaType.video, position: AVCaptureDevice.Position.unspecified) 24 // プロパティの条件を満たしたカメラデバイスの取得 25 let devices = deviceDiscoverySession.devices 26 27 for device in devices { 28 if device.position == AVCaptureDevice.Position.back { 29 mainCamera = device 30 } else if device.position == AVCaptureDevice.Position.front { 31 innerCamera = device 32 } 33 } 34 // 起動時のカメラを設定 35 currentDevice = mainCamera 36 do{ 37 try currentDevice!.lockForConfiguration() // デバイスへのアクセス権を取得。 38 } catch let error { 39 print(error) 40 } 41 configureDevice(device: currentDevice!) 42 } 43 // キャプチャーの出力データを受け付けるオブジェクト 44 var photoOutput : AVCapturePhotoOutput? 45 46 // 入出力データの設定 47 func setupInputOutput() { 48 do { 49 // 指定したデバイスを使用するために入力を初期化 50 let captureDeviceInput = try AVCaptureDeviceInput(device: currentDevice!) 51 // 指定した入力をセッションに追加 52 captureSession.addInput(captureDeviceInput) 53 // 出力データを受け取るオブジェクトの作成 54 photoOutput = AVCapturePhotoOutput() 55 // 出力ファイルのフォーマットを指定 56 photoOutput!.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey : AVVideoCodecType.jpeg])], completionHandler: nil) 57 captureSession.addOutput(photoOutput!) 58 } catch { 59 print(error) 60 } 61 } 62 // プレビュー表示用のレイヤ 63 var cameraPreviewLayer : AVCaptureVideoPreviewLayer? 64 65 // カメラのプレビューを表示するレイヤの設定 66 func setupPreviewLayer() { 67 // 指定したAVCaptureSessionでプレビューレイヤを初期化 68 self.cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession) 69 // プレビューレイヤがカメラのキャプチャーの縦横比を維持した状態で表示するように設定 70 self.cameraPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill 71 // プレビューレイヤの表示の向きを設定 72 self.cameraPreviewLayer?.connection?.videoOrientation = AVCaptureVideoOrientation.portrait 73 74 self.cameraPreviewLayer?.frame = view.frame 75 self.view.layer.insertSublayer(self.cameraPreviewLayer!, at: 0) 76 } 77 78 // 画質、シャッタースピード、isoの設定 79 func configureDevice(device: AVCaptureDevice) { 80 if device.isFocusModeSupported(.continuousAutoFocus) { 81 device.focusMode = .continuousAutoFocus 82 } 83 let shutterSpeed = CMTimeMake(value: 1, timescale: Int32(slider_value_speed)) 84 device.setExposureModeCustom(duration: shutterSpeed, iso: Float(slider_value_iso), completionHandler: nil) 85 do{ 86 try device.lockForConfiguration() 87 // フレームレート設定 88 device.activeVideoMinFrameDuration = CMTimeMake(value: 1, timescale: Int32(slider_value_frame)) 89 device.activeVideoMaxFrameDuration = CMTimeMake(value: 1, timescale: 10) 90 device.unlockForConfiguration() 91 }catch{} 92 } 93 94 @IBOutlet weak var label_frame: UILabel! 95 @IBOutlet weak var label_speed: UILabel! 96 @IBOutlet weak var label_iso: UILabel! 97 98 var slider_value_frame = 10 99 var slider_value_speed = 100 100 var slider_value_iso = 100 101 102 override func viewDidLoad() { 103 super.viewDidLoad() 104 setupCaptureSession() 105 setupDevice() 106 setupInputOutput() 107 setupPreviewLayer() 108 captureSession.startRunning() 109 } 110 111 @IBAction func slider_change_frame(_ sender: UISlider) { 112 let sliderValueFrame:Int = Int(sender.value) 113 label_frame.text = String(sliderValueFrame) 114 slider_value_frame = sliderValueFrame 115 print(slider_value_frame) 116 configureDevice(device: currentDevice!) 117 } 118 119 @IBAction func slider_change_speed(_ sender: UISlider) { 120 let sliderValueSpeed:Int = Int(sender.value) 121 label_speed.text = String(sliderValueSpeed) 122 slider_value_speed = sliderValueSpeed 123 print(slider_value_speed) 124 configureDevice(device: currentDevice!) 125 } 126 127 @IBAction func slider_change_iso(_ sender: UISlider) { 128 let sliderValueIso:Int = Int(sender.value) 129 label_iso.text = String(sliderValueIso) 130 slider_value_iso = sliderValueIso 131 print(slider_value_iso) 132 configureDevice(device: currentDevice!) 133 } 134} 135
現在、このアプリのandroid対応を検討しているのですが、メンテナンス性などを考慮して、cordovaやreact nativeなどのクロスプラットフォームで、iOSとAndroidの両方に対応するカメラアプリを作成したいと考えています。
カメラの映像を画面にプレビューしながら、その画面のフレームレートやカメラのシャッタースピード、iso値などをリアルタイムで変更できるアプリを開発したいと考えています。
(以下のiOSアプリがイメージに近いです。)
https://apps.apple.com/jp/app/video-tachometer/id1492583587
このようなアプリをクロスプラットフォームで開発しようと思うのですが、調査したところcordovaにもreact nativeにもフレームレートやシャッタースピードなどを変更するためのプラグインなどが存在しないように見受けられました。
以下、調査したサイトの一部を掲載しておきます。
https://github.com/cordova-plugin-camera-preview/cordova-plugin-camera-preview
こちらはcordoaのカメラプラグインですが、露出やフォーカスの設定は可能ですがフレームレートの設定はできないように見受けられました。
https://qiita.com/sugasaki/items/64111a0c316bfbb51e3f
こちらはreact nativeでのカメラ機能の実装についてですが、同様に該当する機能の設定項目は見受けられませんでした。
上記の機能をもったアプリを実現することのできるクロスプラットフォームやプラグインは存在するのでしょうか。
調査の段階ですので、やってみた項目を示すことが難しい状態にあります。
(調査した全てのURLを掲載することも現実的ではありません。)
そのため、情報をお持ちの方がいらっしゃいましたら共有いただけると非常にありがたいです。
よろしくお願いいたします。
あなたの回答
tips
プレビュー