前提・実現したいこと
動画撮影時の入力音声にイコライザー処理を行った上で、カメラロールに保存したいです。
発生している問題・エラーメッセージ
通常の動画撮影と保存は問題なくできています。
イコライザー処理にはAVAudioEngine
を使用しようと思っています。
動画撮影
↓
入力された音声にイコライザーをかける
↓
イコライザー処理がかかった状態で動画としてカメラロールに保存
上記を実装するためにはどのようにすればよいのでしょうか?
(そもそも上記の実装は可能なのでしょうか?)
何卒ご教示のほどよろしくお願いいたします。
該当のソースコード
ViewController
1import UIKit 2import AVFoundation 3import Photos 4 5class ViewController: UIViewController, AVCaptureFileOutputRecordingDelegate { 6 7 var session: AVCaptureSession! 8 var videoDevice: AVCaptureDevice! 9 var audioDevice: AVCaptureDevice! 10 var fileOutput: AVCaptureFileOutput! 11 var isRecording = false 12 13 @IBOutlet weak var recordButton: UIButton! 14 15 override func viewDidLoad() { 16 super.viewDidLoad() 17 18 session = AVCaptureSession() 19 videoDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) 20 let videoInput = try! AVCaptureDeviceInput.init(device: videoDevice) 21 session.addInput(videoInput) 22 23 audioDevice = AVCaptureDevice.default(for: .audio) 24 let audioInput = try! AVCaptureDeviceInput.init(device: audioDevice) 25 session.addInput(audioInput) 26 27 fileOutput = AVCaptureMovieFileOutput() 28 session.addOutput(fileOutput) 29 30 session.commitConfiguration() 31 session.startRunning() 32 33 setUpPreview() 34 35 } 36 37 func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) { 38 PHPhotoLibrary.shared().performChanges({ 39 PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: outputFileURL) 40 }) { (isCompleted, error) in 41 if isCompleted { 42 print("Saved") 43 } 44 } 45 } 46 47 func setUpPreview() { 48 let previewLayer: AVCaptureVideoPreviewLayer! 49 previewLayer = AVCaptureVideoPreviewLayer(session: session) 50 previewLayer.frame = self.view.bounds 51 previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill 52 self.view.layer.insertSublayer(previewLayer, at: 0) 53 54 } 55 56 @IBAction func tapRecordButton(_ sender: Any) { 57 onClickRecordButton() 58 } 59 60 func startRecording() { 61 let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) 62 let documentDirectry = paths[0] as String 63 let formatter = DateFormatter() 64 formatter.dateFormat = "yyyyMMddHHmmSS" 65 let filePath: String? = "(documentDirectry)/video-(formatter.string(from: Date())).mp4" 66 let fileURL = NSURL(fileURLWithPath: filePath!) 67 print("Start recording") 68 fileOutput?.startRecording(to: fileURL as URL, recordingDelegate: self) 69 recordButton.setImage(UIImage.init(named: "stop"), for: UIControl.State.normal) 70 } 71 72 func stopRecording() { 73 print("Stop recording") 74 fileOutput?.stopRecording() 75 recordButton.setImage((UIImage.init(named: "start")), for: UIControl.State.normal) 76 } 77 78 func onClickRecordButton() { 79 if !isRecording { 80 startRecording() 81 isRecording = true 82 } else { 83 stopRecording() 84 isRecording = false 85 } 86 } 87 88 // ここから下がイコライザーの部分 89 var audioEngine = AVAudioEngine() 90 func setup() { 91 let audioSession = AVAudioSession.sharedInstance() 92 do { 93 try audioSession.setActive(true) 94 } catch let error as NSError { 95 print("Error : (error)") 96 } 97 98 let input = audioEngine.inputNode 99 let mixer = audioEngine.mainMixerNode 100 101 // Reverb 102 let reverb = AVAudioUnitReverb() 103 reverb.loadFactoryPreset(.largeRoom) 104 audioEngine.attach(reverb) 105 106 // Delay 107 let delay = AVAudioUnitDelay() 108 delay.delayTime = 1 109 audioEngine.attach(delay) 110 111 // EQ 112 let eq = AVAudioUnitEQ() 113 audioEngine.attach(eq) 114 115 audioEngine.connect(input, to: reverb, format: input.inputFormat(forBus: 0)) 116 audioEngine.connect(reverb, to: delay, format: input.inputFormat(forBus: 0)) 117 audioEngine.connect(delay, to: eq, format: input.inputFormat(forBus: 0)) 118 audioEngine.connect(eq, to: mixer, format: input.inputFormat(forBus: 0)) 119 120 // Distortion 121 let distortion = AVAudioUnitDistortion() 122 distortion.loadFactoryPreset(.speechAlienChatter) 123 audioEngine.attach(distortion) 124 125 audioEngine.connect(input, to: distortion, format: input.inputFormat(forBus: 0)) 126 audioEngine.connect(distortion, to: mixer, format: input.inputFormat(forBus: 0)) 127 } 128} 129 130
試したこと
上記のコードでは削除してありますが、イコライザ処理部分のブロックに動画と同じ保存先を指定したりなどもやってみたのですが、通常の動画としてしか保存されませんでした。
あなたの回答
tips
プレビュー