質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

0回答

657閲覧

録画アプリに切り替え機能をつけたい

gamak

総合スコア3

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2022/03/13 08:42

https://superhahnah.com/swift-avcapture-settings/
https://superhahnah.com/swift-camera-position-switching/

今、録画アプリを試しに作っているのですが。
上記の二つのサイトを使い(自分好みに少々改良)録画アプリに切り替え機能をつけたのですが、録画開始ボタンを押した時エラーが発生してしまいました。

かなり長くて申し訳ないのですが、下記のコードでどこを直せばよろしいでしょうか?

録画アプリのコード

import UIKit import AVFoundation class PlayVideoViewController: UIViewController, AVCaptureFileOutputRecordingDelegate{ var captureSession: AVCaptureSession? = nil var previewLayer: AVCaptureVideoPreviewLayer? = nil var videoDevice: AVCaptureDevice? let fileOutput = AVCaptureMovieFileOutput() var reverseButton: UIButton = UIButton() var recordAcitnoButton = UIButton() override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor = UIColor.black self.setupCaptureSession(withPosition: .back) self.setupPreviewLayer() self.setupReverseButton() self.zoomSlider() self.recordButton() } func setupCaptureSession(withPosition cameraPosition: AVCaptureDevice.Position) { self.videoDevice = AVCaptureDevice.default(AVCaptureDevice.DeviceType.builtInWideAngleCamera, for: AVMediaType.video, position: cameraPosition) let audioDevice: AVCaptureDevice? = AVCaptureDevice.default(for: AVMediaType.audio) self.captureSession = AVCaptureSession() // add video input to a capture session let videoInput = try! AVCaptureDeviceInput(device: self.videoDevice!) self.captureSession?.addInput(videoInput) let audioInput = try! AVCaptureDeviceInput(device: audioDevice!) captureSession?.addInput(audioInput) // add capture output let captureOutput: AVCaptureMovieFileOutput = AVCaptureMovieFileOutput() self.captureSession?.addOutput(captureOutput) self.fileOutput.maxRecordedDuration = CMTimeMake(value: 60, timescale: 1) captureSession?.sessionPreset = AVCaptureSession.Preset.high self.captureSession?.startRunning() } func setupPreviewLayer() { // camera apreview layer self.previewLayer = AVCaptureVideoPreviewLayer(session: captureSession!) self.previewLayer?.frame = self.view.bounds self.previewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill self.view.layer.addSublayer(self.previewLayer!) } func setupReverseButton() { // camera-reversing button self.reverseButton.frame = CGRect(x: 0, y: 0, width: 300, height: 70) self.reverseButton.center = self.view.center self.reverseButton.backgroundColor = UIColor.lightGray.withAlphaComponent(0.5) self.reverseButton.setTitle("Reverse Camera Position", for: .normal) self.reverseButton.setTitleColor(UIColor.white, for: .normal) self.reverseButton.setTitleColor(UIColor.lightGray, for: .disabled) self.reverseButton.addTarget(self, action: #selector(self.onTapReverseButton(sender:)), for: .touchUpInside) self.view.addSubview(self.reverseButton) } @objc func onTapReverseButton(sender: UIButton) { self.reverseCameraPosition() } func reverseCameraPosition() { self.captureSession?.stopRunning() self.captureSession?.inputs.forEach { input in self.captureSession?.removeInput(input) } self.captureSession?.outputs.forEach { output in self.captureSession?.removeOutput(output) } // prepare new camera preview let newCameraPosition: AVCaptureDevice.Position = self.videoDevice?.position == .front ? .back : .front self.setupCaptureSession(withPosition: newCameraPosition) let newVideoLayer: AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: self.captureSession!) newVideoLayer.frame = self.view.bounds newVideoLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill // horizontal flip UIView.transition(with: self.view, duration: 1.0, options: [.transitionFlipFromLeft], animations: nil, completion: { _ in // replace camera preview with new one self.view.layer.replaceSublayer(self.previewLayer!, with: newVideoLayer) self.previewLayer = newVideoLayer }) } func zoomSlider() { let slider: UISlider = UISlider() let sliderWidth: CGFloat = self.view.bounds.width * 0.75 let sliderHeight: CGFloat = 40 let sliderRect: CGRect = CGRect(x: (self.view.bounds.width - sliderWidth) / 2, y: self.view.bounds.height - 80, width: sliderWidth, height: sliderHeight) slider.frame = sliderRect slider.minimumValue = 0.0 slider.maximumValue = 1.0 slider.value = 0.0 slider.addTarget(self, action: #selector(self.onSliderChanged(sender:)), for: .valueChanged) self.view.addSubview(slider) } @objc func onSliderChanged(sender: UISlider) { do { try self.videoDevice?.lockForConfiguration() self.videoDevice?.ramp( toVideoZoomFactor: (self.videoDevice?.minAvailableVideoZoomFactor)! + CGFloat(sender.value) * ((self.videoDevice?.maxAvailableVideoZoomFactor)! - (self.videoDevice?.minAvailableVideoZoomFactor)!), withRate: 30.0) self.videoDevice?.unlockForConfiguration() } catch { print("Failed to change zoom.") } } func recordButton() { self.recordAcitnoButton = UIButton(frame: CGRect(x: 0, y: 0, width: 80, height: 80)) self.recordAcitnoButton.backgroundColor = .white self.recordAcitnoButton.tintColor = .red self.recordAcitnoButton.setImage(UIImage(systemName: "video.slash.fill"), for: .normal) self.recordAcitnoButton.layer.masksToBounds = true self.recordAcitnoButton.layer.cornerRadius = 30 self.recordAcitnoButton.layer.position = CGPoint(x: self.view.bounds.width / 2, y:self.view.bounds.height - 130) self.recordAcitnoButton.addTarget(self, action: #selector(self.onClickRecordButton(sender:)), for: .touchUpInside) self.view.addSubview(recordAcitnoButton) } @objc func onClickRecordButton(sender: UIButton) { if self.fileOutput.isRecording { // stop recording fileOutput.stopRecording() self.recordAcitnoButton.backgroundColor = .white self.recordAcitnoButton.tintColor = .red self.recordAcitnoButton.setImage(UIImage(systemName: "video.slash.fill"), for: .normal) } else { // start recording let tempDirectory: URL = URL(fileURLWithPath: NSTemporaryDirectory()) let fileURL: URL = tempDirectory.appendingPathComponent("mytemp1.mov") fileOutput.startRecording(to: fileURL, recordingDelegate: self) self.recordAcitnoButton.backgroundColor = .red self.recordAcitnoButton.tintColor = .white self.recordAcitnoButton.setImage(UIImage(systemName: "video.fill"), for: .normal) } } func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) { // show alert let alert: UIAlertController = UIAlertController(title: "Recorded!", message: outputFileURL.absoluteString, preferredStyle: .alert) let okAction: UIAlertAction = UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil) alert.addAction(okAction) self.present(alert, animated: true, completion: nil) } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gamak

2022/03/13 11:24 編集

このコードを書く前から色々とグーグルで検索したり思考錯誤をし書いてみたのですが、結局はエラーが出てしまうことや自分の思いどうりにいく結果が出せていないため、皆様の知識をお貸しくださればとても幸いです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問