iOS/AVCaptureMultiCamSession
をテンプレートにして作成
開始行:
[[FrontPage]]
*概要 [#s17f6516]
-iOS13より複数のカメラで同時撮影するAPIが追加された
-ズームレンズよりもメインレンズのほうが低照度環境でもノイ...
-結論: iPhone15ProMaxにおいて複数カメラのビデオ撮影では4K...
*コード [#icd019d8]
-最大撮影フォーマットを調べるためのコード
#highlightjs(swift)
import AVFoundation
import UIKit
import Photos
class ViewController: UIViewController {
@IBOutlet weak var previewView: UIView!
private var captureSession = AVCaptureMultiCamSession()
private var audioInput: AVCaptureDeviceInput!
private var audioPort: AVCaptureDeviceInput.Port!
// 広角カメラの設定
private var wideAngleInput: AVCaptureDeviceInput!
private var wideAnglePort: AVCaptureDeviceInput.Port!
private var wideAngleOutput: AVCaptureMovieFileOutput!
private var wideAngleVideoConnection: AVCaptureConnec...
// 望遠カメラの設定
private var telephotoInput: AVCaptureDeviceInput!
private var telephotoPort: AVCaptureDeviceInput.Port!
private var telephotoOutput: AVCaptureMovieFileOutput!
private var telephotoVideoConnection: AVCaptureConnec...
// プレビュー
private var videoPreviewLayer: AVCaptureVideoPreviewL...
override func viewDidLoad() {
super.viewDidLoad()
// マルチキャプチャをサポートしているかどうか
guard AVCaptureMultiCamSession.isMultiCamSupporte...
fatalError()
}
setupSession()
}
// MARK: - セッションの設定
private func setupSession() {
captureSession.beginConfiguration()
// マイクの準備
do {
let microphone = AVCaptureDevice.default(for:...
let input = try AVCaptureDeviceInput(device: ...
guard captureSession.canAddInput(input) else {
fatalError()
}
audioInput = input
captureSession.addInputWithNoConnections(input)
guard let audioPort = input.ports(for: .audio,
sourceDevic...
sourceDevic...
fatalError()
}
self.audioPort = audioPort
}
catch {
fatalError(error.localizedDescription)
}
// カメラの利用準備
do {
try setupWideCamera()
try setupTeleCamera()
previewView.layer.addSublayer(videoPreviewLay...
videoPreviewLayer.frame = previewView.layer.f...
captureSession.commitConfiguration()
captureSession.startRunning()
if captureSession.canSetSessionPreset(.hd4K38...
print("4k利用可能")
}
else {
print("4k利用不可能")
}
}
catch {
print("error")
}
}
// MARK: - 広角カメラの設定
private func setupWideCamera() throws {
guard let camera = AVCaptureDevice.default(.built...
for: ....
positi...
print("camera not founc")
throw NSError()
}
// sessinに追加
wideAngleInput = try AVCaptureDeviceInput(device:...
guard captureSession.canAddInput(wideAngleInput) ...
print("can not add camera input")
throw NSError()
}
captureSession.addInputWithNoConnections(wideAngl...
guard let wideAnglePort = wideAngleInput.ports(
for: .video, sourceDeviceType: camera.deviceT...
sourceDevicePosition: camera.position).first ...
print("can not find wide angle port")
throw NSError()
}
self.wideAnglePort = wideAnglePort
// outputをsessionに追加する
wideAngleOutput = AVCaptureMovieFileOutput()
guard captureSession.canAddOutput(wideAngleOutput...
print("can not add wide angle output")
throw NSError()
}
captureSession.addOutputWithNoConnections(wideAng...
// inputとoutputを接続する
wideAngleVideoConnection = AVCaptureConnection(
inputPorts: [wideAnglePort], output: wideAngl...
wideAngleVideoConnection.videoOrientation = .port...
if (wideAngleVideoConnection.isVideoStabilization...
wideAngleVideoConnection.preferredVideoStabil...
}
guard captureSession.canAddConnection(wideAngleVi...
print("can not add wide angle video connetion")
throw NSError()
}
captureSession.addConnection(wideAngleVideoConnec...
// マイクとoutputを接続する
let audioConnection = AVCaptureConnection(
inputPorts: [audioPort], output: wideAngleOut...
guard captureSession.canAddConnection(audioConnec...
print("can not add audio connection")
throw NSError()
}
}
// MARK: - 望遠カメラの設定
private func setupTeleCamera() throws {
guard let camera = AVCaptureDevice.default(
.builtInTelephotoCamera, for: .video, positio...
print("not found builtin telephoto camera")
throw NSError()
}
telephotoInput = try AVCaptureDeviceInput(device:...
guard captureSession.canAddInput(telephotoInput) ...
print("can not add telephoto camera")
throw NSError()
}
captureSession.addInputWithNoConnections(telephot...
guard let telephotoPort = telephotoInput.ports(
for: .video,
sourceDeviceType: camera.deviceType,
sourceDevicePosition: camera.position).first ...
print("can not fine telephoto input port")
throw NSError()
}
self.telephotoPort = telephotoPort
// outputの設定
telephotoOutput = AVCaptureMovieFileOutput()
guard captureSession.canAddOutput(telephotoOutput...
print("can not add telephoto output")
throw NSError()
}
captureSession.addOutputWithNoConnections(telepho...
// inputとoutputを接続する
telephotoVideoConnection = AVCaptureConnection(
inputPorts: [telephotoPort], output: telephot...
telephotoVideoConnection.videoOrientation = .port...
if telephotoVideoConnection.isVideoStabilizationS...
telephotoVideoConnection.preferredVideoStabil...
}
guard captureSession.canAddConnection(telephotoVi...
print("can not add telephoto video connection")
throw NSError()
}
captureSession.addConnection(telephotoVideoConnec...
// マイクとinputとoutputを接続する
let audioConnection = AVCaptureConnection(
inputPorts: [audioPort], output: telephotoOut...
guard captureSession.canAddConnection(audioConnec...
print("can not add audio connection. telephot...
throw NSError()
}
captureSession.addConnection(audioConnection)
// プレビューの設定
videoPreviewLayer = AVCaptureVideoPreviewLayer()
videoPreviewLayer.setSessionWithNoConnection(capt...
videoPreviewLayer.videoGravity = .resizeAspect
videoPreviewLayer.bounds = previewView.bounds
let layerConnection = AVCaptureConnection(
inputPort: telephotoPort, videoPreviewLayer: ...
layerConnection.videoOrientation = .portrait
guard captureSession.canAddConnection(layerConnec...
print("can not add layer connection")
throw NSError()
}
captureSession.addConnection(layerConnection)
}
}
*感想 [#i1575abb]
4k撮影をサポートしているのであれば,チューニングされた標...
iPadProといったM2チップを搭載している端末であれば4K撮影可...
終了行:
[[FrontPage]]
*概要 [#s17f6516]
-iOS13より複数のカメラで同時撮影するAPIが追加された
-ズームレンズよりもメインレンズのほうが低照度環境でもノイ...
-結論: iPhone15ProMaxにおいて複数カメラのビデオ撮影では4K...
*コード [#icd019d8]
-最大撮影フォーマットを調べるためのコード
#highlightjs(swift)
import AVFoundation
import UIKit
import Photos
class ViewController: UIViewController {
@IBOutlet weak var previewView: UIView!
private var captureSession = AVCaptureMultiCamSession()
private var audioInput: AVCaptureDeviceInput!
private var audioPort: AVCaptureDeviceInput.Port!
// 広角カメラの設定
private var wideAngleInput: AVCaptureDeviceInput!
private var wideAnglePort: AVCaptureDeviceInput.Port!
private var wideAngleOutput: AVCaptureMovieFileOutput!
private var wideAngleVideoConnection: AVCaptureConnec...
// 望遠カメラの設定
private var telephotoInput: AVCaptureDeviceInput!
private var telephotoPort: AVCaptureDeviceInput.Port!
private var telephotoOutput: AVCaptureMovieFileOutput!
private var telephotoVideoConnection: AVCaptureConnec...
// プレビュー
private var videoPreviewLayer: AVCaptureVideoPreviewL...
override func viewDidLoad() {
super.viewDidLoad()
// マルチキャプチャをサポートしているかどうか
guard AVCaptureMultiCamSession.isMultiCamSupporte...
fatalError()
}
setupSession()
}
// MARK: - セッションの設定
private func setupSession() {
captureSession.beginConfiguration()
// マイクの準備
do {
let microphone = AVCaptureDevice.default(for:...
let input = try AVCaptureDeviceInput(device: ...
guard captureSession.canAddInput(input) else {
fatalError()
}
audioInput = input
captureSession.addInputWithNoConnections(input)
guard let audioPort = input.ports(for: .audio,
sourceDevic...
sourceDevic...
fatalError()
}
self.audioPort = audioPort
}
catch {
fatalError(error.localizedDescription)
}
// カメラの利用準備
do {
try setupWideCamera()
try setupTeleCamera()
previewView.layer.addSublayer(videoPreviewLay...
videoPreviewLayer.frame = previewView.layer.f...
captureSession.commitConfiguration()
captureSession.startRunning()
if captureSession.canSetSessionPreset(.hd4K38...
print("4k利用可能")
}
else {
print("4k利用不可能")
}
}
catch {
print("error")
}
}
// MARK: - 広角カメラの設定
private func setupWideCamera() throws {
guard let camera = AVCaptureDevice.default(.built...
for: ....
positi...
print("camera not founc")
throw NSError()
}
// sessinに追加
wideAngleInput = try AVCaptureDeviceInput(device:...
guard captureSession.canAddInput(wideAngleInput) ...
print("can not add camera input")
throw NSError()
}
captureSession.addInputWithNoConnections(wideAngl...
guard let wideAnglePort = wideAngleInput.ports(
for: .video, sourceDeviceType: camera.deviceT...
sourceDevicePosition: camera.position).first ...
print("can not find wide angle port")
throw NSError()
}
self.wideAnglePort = wideAnglePort
// outputをsessionに追加する
wideAngleOutput = AVCaptureMovieFileOutput()
guard captureSession.canAddOutput(wideAngleOutput...
print("can not add wide angle output")
throw NSError()
}
captureSession.addOutputWithNoConnections(wideAng...
// inputとoutputを接続する
wideAngleVideoConnection = AVCaptureConnection(
inputPorts: [wideAnglePort], output: wideAngl...
wideAngleVideoConnection.videoOrientation = .port...
if (wideAngleVideoConnection.isVideoStabilization...
wideAngleVideoConnection.preferredVideoStabil...
}
guard captureSession.canAddConnection(wideAngleVi...
print("can not add wide angle video connetion")
throw NSError()
}
captureSession.addConnection(wideAngleVideoConnec...
// マイクとoutputを接続する
let audioConnection = AVCaptureConnection(
inputPorts: [audioPort], output: wideAngleOut...
guard captureSession.canAddConnection(audioConnec...
print("can not add audio connection")
throw NSError()
}
}
// MARK: - 望遠カメラの設定
private func setupTeleCamera() throws {
guard let camera = AVCaptureDevice.default(
.builtInTelephotoCamera, for: .video, positio...
print("not found builtin telephoto camera")
throw NSError()
}
telephotoInput = try AVCaptureDeviceInput(device:...
guard captureSession.canAddInput(telephotoInput) ...
print("can not add telephoto camera")
throw NSError()
}
captureSession.addInputWithNoConnections(telephot...
guard let telephotoPort = telephotoInput.ports(
for: .video,
sourceDeviceType: camera.deviceType,
sourceDevicePosition: camera.position).first ...
print("can not fine telephoto input port")
throw NSError()
}
self.telephotoPort = telephotoPort
// outputの設定
telephotoOutput = AVCaptureMovieFileOutput()
guard captureSession.canAddOutput(telephotoOutput...
print("can not add telephoto output")
throw NSError()
}
captureSession.addOutputWithNoConnections(telepho...
// inputとoutputを接続する
telephotoVideoConnection = AVCaptureConnection(
inputPorts: [telephotoPort], output: telephot...
telephotoVideoConnection.videoOrientation = .port...
if telephotoVideoConnection.isVideoStabilizationS...
telephotoVideoConnection.preferredVideoStabil...
}
guard captureSession.canAddConnection(telephotoVi...
print("can not add telephoto video connection")
throw NSError()
}
captureSession.addConnection(telephotoVideoConnec...
// マイクとinputとoutputを接続する
let audioConnection = AVCaptureConnection(
inputPorts: [audioPort], output: telephotoOut...
guard captureSession.canAddConnection(audioConnec...
print("can not add audio connection. telephot...
throw NSError()
}
captureSession.addConnection(audioConnection)
// プレビューの設定
videoPreviewLayer = AVCaptureVideoPreviewLayer()
videoPreviewLayer.setSessionWithNoConnection(capt...
videoPreviewLayer.videoGravity = .resizeAspect
videoPreviewLayer.bounds = previewView.bounds
let layerConnection = AVCaptureConnection(
inputPort: telephotoPort, videoPreviewLayer: ...
layerConnection.videoOrientation = .portrait
guard captureSession.canAddConnection(layerConnec...
print("can not add layer connection")
throw NSError()
}
captureSession.addConnection(layerConnection)
}
}
*感想 [#i1575abb]
4k撮影をサポートしているのであれば,チューニングされた標...
iPadProといったM2チップを搭載している端末であれば4K撮影可...
ページ名: