ある一つの動画をiOS端末のアルバムから取得し、フィルムのノイズのみの動画を重ねて、取得した動画を古めかしいフィルムノイズがのったような動画を生成しようと考えています。
GPUImageを使用してそれが実現できないか検討していますが、できる方法はありますでしょうか。
下記のコードはそもそも使い方が間違っているでしょうか。
- Xcode 13.0
- Swift 4.2
試したこと
Swift
1 private func filmFilter(url: URL, completion: @escaping (URL) -> Void) { 2 // GPUImageでフィルタをかける 3 guard let movieFile = GPUImageMovie(url: url) else { 4 print("movieFile is not initialized.") 5 return 6 } 7 movieFile.runBenchmark = true 8 movieFile.playAtActualSpeed = false 9 10 // ノイズ動画 11 let noiseUrl = Bundle.main.url(forResource: "30Filmnoise", withExtension: "mp4")! 12 guard let noiseFile = GPUImageMovie(url: noiseUrl) else { 13 print("noiseFile is not initialized.") 14 return 15 } 16 noiseFile.runBenchmark = true 17 noiseFile.playAtActualSpeed = false 18 19 let filter = GPUImageMultiplyBlendFilter() 20 movieFile.addTarget(filter) 21 noiseFile.addTarget(filter) 22 23 24 25 26 27 let movieUrl = Utils.getMP4Path() 28 guard let movieWriter = GPUImageMovieWriter(movieURL: movieUrl as URL, size:CGSize(width: 720, height: 720)) else { 29 print("movieWrite is not initialized.") 30 return 31 } 32 filter.addTarget(movieWriter) 33 34 movieWriter.shouldPassthroughAudio = true 35 movieFile.audioEncodingTarget = movieWriter 36 movieFile.enableSynchronizedEncoding(using: movieWriter) 37 noiseFile.audioEncodingTarget = movieWriter 38 noiseFile.enableSynchronizedEncoding(using: movieWriter) 39 40 self.movieWriter = movieWriter 41 self.movieFile = movieFile 42 self.noiseFile = noiseFile 43 44 self.movieWriter!.startRecording() 45 self.movieFile!.startProcessing() 46 self.noiseFile!.startProcessing() 47 48 self.movieWriter!.completionBlock = { 49 filter.removeTarget(self.movieWriter!) 50 self.movieWriter!.finishRecording() 51 52 DispatchQueue.main.async { 53 completion(movieUrl as URL) 54 } 55 } 56 57 58 }
関数filmFilterの引数urlに、もとの動画の場所がセットされています。
その動画に重ねたいノイズの動画は
let noiseUrl = Bundle.main.url(forResource: "30Filmnoise", withExtension: "mp4")!
で取得しています。
GPUImageMultiplyBlendFilterを使って乗算によりノイズが載ってくれればいいなという期待のみでコードを書きました。
このコードを実行すると、以下の例外が出力されてクラッシュします。
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '*** -[AVAssetWriterInput requestMediaDataWhenReadyOnQueue:usingBlock:] cannot be called more than once.'
グーグル検索してみても、2つの動画を重ねるという事例がほとんど見つからないので、そもそもGPUImageでできるかどうかも不明なところではあります。
あなたの回答
tips
プレビュー