###環境
Xcode9.2
Swift4
###概要
現在、画像に対してリアルタイムにエフェクトをかけたものを、動画として書き出そうとしています。
イメージとしてはこのサイトに記載の「画像の配列から動画を生成」と同様に
AVFoundationのAVAssetWriterを使用した方法の中で
AVAssetWriterInputPixelBufferAdaptorに画像のバッファを書き込んでいくものとなります。
しかし、上記のサイトが「決められた数の画像をforループで書き込む」のに対し、私の場合は、マイク音声も別スレッドで録音し最終的に音声と動画を統合したいため
時間軸に沿った、動画書き込みを試みております。
そこでTimer.scheduledTimerでタイマーを回し、毎回以下のように日付から経過時間を取得/AVAssetWriterInputPixelBufferAdaptorに渡すためのCMTimeを出しております。
let FPS = 30 @objec func runLoop(){ let now = Date() let duration = now.timeIntervalSince(offsetDate) offsetDate = now; let presentTime = CMTimeMake(Int64(Float64(frameCount * FPS) * duration), Int32(FPS)) //バッファ追加 flg = adapter.append(baseImageBuffer, withPresentationTime: presentTime) if !flg { print("error") Thread.sleep(forTimeInterval: 0.1) } }
timer = Timer.scheduledTimer(timeInterval: 0.2, target: self, selector: #selector(self.runLoop), userInfo: nil, repeats: true) RunLoop.current.add(timer, forMode: RunLoopMode.commonModes)
###質問
上記の実装にて、タイマーの時間を0.2よりも小さくすると「adapter.append」の箇所で返るBoolがfalseとなり
appendに失敗します。(0.2では動作します)
FTPを30にしたいため、タイマーは1/30=0.03を設定したいのですが、
AVAssetWriterInputPixelBufferAdaptorに書き込む速度制限のようなものが存在するのかどうか
ご存知の方がおりましたらご教示いただけますと幸いです。
ちなみに音声の録音は上記タイマーとは別にAVAudioEngineを走らせ、以下のように実装しておりますが
こちらは正しくオーディオファイルが書き出されます。
mixer = AVAudioMixerNode() audioEngine.attach(mixer) try! AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord) try! AVAudioSession.sharedInstance().setActive(true) audioFormat = AVAudioFormat(commonFormat: AVAudioCommonFormat.pcmFormatInt16, sampleRate: 44100.0, channels: 1, interleaved: true) audioEngine.connect(audioEngine.inputNode, to: mixer, format: audioFormat) audioEngine.connect(mixer, to: audioEngine.mainMixerNode, format: audioFormat) let dir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! as String self.filePath = dir.appending("/temp.wav") _ = ExtAudioFileCreateWithURL(URL(fileURLWithPath: self.filePath!) as CFURL, kAudioFileWAVEType, (audioFormat?.streamDescription)!, nil, AudioFileFlags.eraseFile.rawValue, &outref) mixer.installTap(onBus: 0, bufferSize: AVAudioFrameCount((audioFormat?.sampleRate)!), format: audioFormat) { (buffer: AVAudioPCMBuffer!, time: AVAudioTime!) in let audioBuffer: AVAudioBuffer = buffer _ = ExtAudioFileWriteAsync(self.outref!, buffer.frameLength, audioBuffer.audioBufferList) }
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。