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

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

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

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

Q&A

解決済

1回答

560閲覧

動画撮影アプリについて

退会済みユーザー

退会済みユーザー

総合スコア0

Swift

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

0グッド

0クリップ

投稿2020/10/01 01:11

編集2020/10/01 01:13

下記のサイトのコードを打ち込んで、動画撮影のアプリを作ろうとしています。
質問したいことは2つあります。

1.@objcとは、objetive-cのことでしょうか?下記のコードはswiftではないですか?

2.storyboardと紐付けする場合、@IBOutlet、@IBActionのコードが生成されると思うのですが、下記のコードはそれがありません。紐付け前ということでしょうか?

環境 xcode11.4 swift4.2です。

リンク内容

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

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

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

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

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

guest

回答1

0

ベストアンサー

1.@objcとは、objetive-cのことでしょうか?下記のコードはswiftではないですか?

現在、Swift/SwiftUI をベースとした環境での開発が中心となりつつありますが、やはり従前使われてきた Objective-C の資産も使わざるを得ない場面がでてきます。

そのことをコンパイラに伝えるための一種のキーワードだと思ってください(おそらく、それ以上深く考える必要は今はないかと思います)。

2.storyboardと紐付けする場合、@IBOutlet、@IBActionのコードが生成されると思うのですが、下記のコードはそれがありません。紐付け前ということでしょうか?

いいえ、ご提示いただいているサンプルコードは、StoryBoard に部品を配置することなく実行できるよう作成されたコードです。

なので紐付けは一切必要ありません。

しかし、StoryBoard は一切使わないのかというとそういう訳でもなく、初期(Initial)ページとなる View Controller を一つ配置しておく必要はあります。

簡単に手順を示すと、

  1. 通常の Swift/StoryBoard を作る手順でプロジェクトを新規作成する
  2. StoryBoard には一切手を加えない
  3. ViewController.swift にサンプルのコードをそのままコピー&ペーストする
  4. Info.plist を編集する
  5. 「実機で」実行する

というステップで実行できると思います。

##2020年10月1日追記
参考にされたコードは iOS10 以降ではそのまま使えないため、使えるように一部変更を加えてみました。

また、オリジナルのコードはだと、録画終了後指定したフォルダに映像を保存するだけで、実はビデオライブラリには保存されないため、録画状態を確認することができません(要は、「写真」アプリで録画された映像を確認することができない)。

また、UIの一部が少し紛らわしいため、その修正も加えたコードを下記に提示しますので、コード中のコメントをよく読まれた上、試してみていただけますでしょうか。

Swift

1// This code is originally based on http://faboplatform.github.io/SwiftDocs/5.avfoundation/003_avfoundation/ 2// Some lines of this program are modified to enable to run this code correctly after iOS 10.0 ,and added codes to save captured image to the Photo library. 3 4import UIKit 5import AVFoundation 6 7// MARK: - フォトライブラリに保存するために必要 8import Photos 9 10class ViewController: UIViewController, AVCaptureFileOutputRecordingDelegate { 11 12 // ビデオのアウトプット. 13 private var myVideoOutput: AVCaptureMovieFileOutput! 14 15 // スタートボタン. 16 private var myButtonStart: UIButton! 17 18 // ストップボタン. 19 private var myButtonStop: UIButton! 20 21 override func viewDidLoad() { 22 super.viewDidLoad() 23 print(#function) 24 // セッションの作成. 25 let mySession = AVCaptureSession() 26 27 // デバイス. 28 var myDevice = AVCaptureDevice.default(for: .video) 29 30 // 出力先を生成. 31 // let myImageOutput = AVCaptureStillImageOutput() 32 // MARK: - 'AVCaptureStillImageOutput' was deprecated in iOS 10.0: Use AVCapturePhotoOutput instead. 33 // 警告通り、AVCapturePhotoOutput() でインスタンスを生成するよういする 34 let myImageOutput = AVCapturePhotoOutput() 35 36 // デバイス一覧の取得. 37 // let devices = AVCaptureDevice.devices() 38 // MARK: - 'devices()' was deprecated in iOS 10.0: Use AVCaptureDeviceDiscoverySession instead. 39 // 警告に従うが、警告で出力されているメソッド名が微妙に異なる(AVCaptureDevice.DiscoverySessionが正解)なので注意する 40 // 詳しい使い方は公式ドキュメントを参照 41 // refer to: https://developer.apple.com/documentation/avfoundation/cameras_and_media_capture/choosing_a_capture_device 42 let devices = AVCaptureDevice.DiscoverySession(deviceTypes: 43 [.builtInTrueDepthCamera, .builtInDualCamera, .builtInWideAngleCamera], 44 mediaType: .video, position: .unspecified).devices 45 // マイクを取得. 46 let audioCaptureDevice = AVCaptureDevice.default(for: .audio) 47 48 // マイクをセッションのInputに追加. 49 let audioInput = try! AVCaptureDeviceInput.init(device: audioCaptureDevice!) 50 51 // バックライトをmyDeviceに格納. 52 53 // for device in devices { 54 // if(device.position == AVCaptureDevice.Position.back){ 55 // myDevice = device 56 // } 57 // } 58 // MARK: - オリジナルのコードから一部変更。 59 guard !devices.isEmpty else { fatalError("選択されたデバイスは存在しません") } 60 myDevice = devices.first { $0.position == .back } 61 62 // バックカメラを取得. 63 let videoInput = try! AVCaptureDeviceInput.init(device: myDevice!) 64 65 // ビデオをセッションのInputに追加. 66 mySession.addInput(videoInput) 67 68 // オーディオをセッションに追加. 69 mySession.addInput(audioInput) 70 71 // セッションに追加. 72 mySession.addOutput(myImageOutput) 73 74 // 動画の保存. 75 myVideoOutput = AVCaptureMovieFileOutput() 76 77 // ビデオ出力をOutputに追加. 78 mySession.addOutput(myVideoOutput) 79 80 // 画像を表示するレイヤーを生成. 81 let myVideoLayer = AVCaptureVideoPreviewLayer.init(session: mySession) 82 myVideoLayer.frame = self.view.bounds 83 // myVideoLayer.session = myDevice 84 myVideoLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill 85 86 // Viewに追加. 87 self.view.layer.addSublayer(myVideoLayer) 88 89 // セッション開始. 90 mySession.startRunning() 91 92 // UIボタンを作成. 93 myButtonStart = UIButton(frame: CGRect(x: 0, y: 0, width: 120, height: 50)) 94 myButtonStop = UIButton(frame: CGRect(x: 0, y: 0, width: 120, height: 50)) 95 96 myButtonStart.backgroundColor = UIColor.red 97 myButtonStop.backgroundColor = UIColor.gray 98 99 myButtonStart.layer.masksToBounds = true 100 myButtonStop.layer.masksToBounds = true 101 102 myButtonStart.setTitle("撮影", for: .normal) 103 myButtonStop.setTitle("停止", for: .normal) 104 105 myButtonStart.layer.cornerRadius = 20.0 106 myButtonStop.layer.cornerRadius = 20.0 107 108 myButtonStart.layer.position = CGPoint(x: self.view.bounds.width/2 - 70, y:self.view.bounds.height-50) 109 myButtonStop.layer.position = CGPoint(x: self.view.bounds.width/2 + 70, y:self.view.bounds.height-50) 110 111 myButtonStart.addTarget(self, action: #selector(ViewController.onClickMyButton), for: .touchUpInside) 112 myButtonStop.addTarget(self, action: #selector(ViewController.onClickMyButton), for: .touchUpInside) 113 114 // UIボタンをViewに追加. 115 self.view.addSubview(myButtonStart) 116 self.view.addSubview(myButtonStop) 117 118 // 119 myButtonStop.isHidden = true 120 } 121 122 // MARK: 123 func toggleButtonStatus() { 124 // 125 myButtonStop.isHidden.toggle() 126 myButtonStart.isHidden.toggle() 127 } 128 129 /* 130 ボタンイベント. 131 */ 132 @objc internal func onClickMyButton(sender: UIButton){ 133 // 撮影開始. 134 if( sender == myButtonStart ){ 135 // MARK: 136 toggleButtonStatus() 137 138 let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) 139 140 // フォルダ. 141 let documentsDirectory = paths[0] 142 143 // ファイル名. 144 let filePath = "(documentsDirectory)/test.mp4" 145 146 // URL. 147 let fileURL = URL(fileURLWithPath: filePath) 148 149 // 録画開始. 150 myVideoOutput.startRecording(to: fileURL, recordingDelegate: self) 151 152 } 153 // 撮影停止. 154 else if ( sender == myButtonStop ){ 155 // 156 toggleButtonStatus() 157 158 myVideoOutput.stopRecording() 159 } 160 } 161 162 // MARK: - AVCaptureFileOutputRecordingDelegate 163 164 /* 165 動画がキャプチャーされた後に呼ばれるメソッド. 166 */ 167 func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) { 168 print("didFinishRecordingTo outputFileURL") 169 170 // MARK: - フォトライブラリにビデオを保存するのであれば、以下のコードを追加した上、NSPhotoLibraryAddUsageDescription を Info.plist に追加する必要がある。 171 PHPhotoLibrary.shared().performChanges({ 172 PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: outputFileURL) 173 }) { completed, error in 174 if completed { 175 print("Video is saved!") 176 } 177 } 178 } 179 180 /* 181 動画のキャプチャーが開始された時に呼ばれるメソッド. 182 */ 183 func fileOutput(_ output: AVCaptureFileOutput, didStartRecordingTo fileURL: URL, from connections: [AVCaptureConnection]) { 184 print("didStartRecordingTo fileURL") 185 } 186}

投稿2020/10/01 01:25

編集2020/10/01 13:52
TsukubaDepot

総合スコア5086

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

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

退会済みユーザー

退会済みユーザー

2020/10/01 06:21

回答ありがとうございます!! 実は回答通りやる前にlet devices = AVCaptureDevice.devices()の欄に 'devices()was deprecated in iOS10.0: Use'AVCaptureDeviceDiscoverySession'と表示されたため、変更したところ、'Type'AVCaptureDevice'has no member' AVCaptureDeviceDiscovery Session'と表示されました。メンバーが無いとはどのようなエラー内容なのでしょうか…?
TsukubaDepot

2020/10/01 13:48

気になったので、私も試してみました。 Xcode の Warning は、大抵そのまま受け入れても動くことが多いのですが、ここで出されているメソッド名は、実は微妙に間違っているため、そのままでは動きませんでした。 また、それ以外にも修正すべき点はいくつかあったため、回答本文に動くように変更したコードを追記します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問