AVAssetExportSession을 사용하여 mutablecomposition을 내보내려고합니다. MTAudioProcessingTap을 사용하여 mutable 컴포지션의 오디오 데이터를 처리하고 오디오 데이터를 기반으로 AVVideoCompositionCoreAnimationTool을 사용하여 mutable 컴포지션의 일부 애니메이션을 수정합니다. 애니메이션이 오디오 데이터에 의존하기 때문에 실시간으로이 작업을 수행하고 싶습니다. AVPlayer를 사용하면 잘 작동하지만 AVAssetExportSession에서는 그렇지 않습니다. MTAudioProcessingTapProcessCallback
에 수신 된 오디오 데이터가 AVAssetExportSession의 비디오와 동기화되지 않은 것 같습니다. 그래서 여기에 질문은, 그들이 AVAssetExportSession 동안 동기화가되기로되어 있는지 알 수 있습니까?AVAssetExportSession에 MTAudioProcessingTap 사용
여기 아래는 내 MTAudioProcessingTapProcessCallback
var tapProcess: MTAudioProcessingTapProcessCallback = {
(tap, numberFrames, flags, bufferListInOut, numberFramesOut, flagsOut) in
let status = MTAudioProcessingTapGetSourceAudio(tap, numberFrames, bufferListInOut, flagsOut, nil, numberFramesOut)
let viewController = MTAudioProcessingTapGetStorage(tap)
let viewController = Unmanaged<CanvasViewController>.fromOpaque(viewController).takeUnretainedValue()
DispatchQueue.main.sync {
// update my CALayer in viewController based on the audio data
}
}
입니다 audiomix 설정하기위한 코드입니다
func setupAudioMix(audioTrack: AVAssetTrack) -> AVAudioMix {
var callbacks = MTAudioProcessingTapCallbacks(
version: kMTAudioProcessingTapCallbacksVersion_0,
clientInfo: UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()),
init: tapInit,
finalize: tapFinalize,
prepare: tapPrepare,
unprepare: tapUnprepare,
process: tapProcess)
var tap: Unmanaged<MTAudioProcessingTap>?
let err = MTAudioProcessingTapCreate(kCFAllocatorDefault, &callbacks, kMTAudioProcessingTapCreationFlag_PreEffects, &tap)
print("err: \(err)\n")
if err == noErr {
}
let inputParams = AVMutableAudioMixInputParameters(track: audioTrack)
inputParams.audioTapProcessor = tap?.takeUnretainedValue()
let audioMix = AVMutableAudioMix()
audioMix.inputParameters = [inputParams]
return audioMix
}
을 그리고 AVAssetExportSession에 audiomix를 첨부 :
exporter = AVAssetExportSession(asset: mutableComposition!, presetName: AVAssetExportPresetMediumQuality)!
exporter!.outputURL = exportUrl as URL
exporter!.videoComposition = videoComposition!
exporter!.audioMix = audioMix!
exporter!.outputFileType = AVFileTypeMPEG4
exporter!.shouldOptimizeForNetworkUse = true
답변 해 주셔서 감사합니다. 작은 수정, 당신이 지적한 것처럼, 나는 AVAlayer 대신 AVAlayer를 의미했습니다. 내가 참조. AVAssetWriter를 사용하려고합니다. AVAssetWriter는 비디오 위의 CALayer 애니메이션 작성을 지원할 수 있어야합니까? 또한 AVPlayer는 오디오와 비디오가 뷰어와 동기화되어야한다고 생각합니다. 내 애니메이션도 동기화 된 것처럼 보입니다. – karyboy
AVAssetWriter가 파일에 동시에 쓰는 것 같지 않습니다. 두 개의 AVAssetWriterInput (하나의 오디오 및 비디오)을 만들어 AVAssetWriter에 추가했습니다. AVAssetReaderAudioMixOutput 및 AVAssetReaderVideoCompositionOutput을 사용하여 copyNextSampleBuffer로 자산에서 읽습니다. AudioMix를 AVAssetReaderAudioMixOutput에 연결합니다. MTAudioProcessingTapProcessCallback은 CALayer를 업데이트합니다. 하지만 내 보낸 파일에서 동기화되지 않습니다. – karyboy
CMSampleBufferGetOutputPresentationTimeStamp를 사용하여 각각의 CMSampleBuffer를 추가하기 전에 두 AVAssetWriterInput의 프레젠테이션 시간을 기록 했으므로 오디오 버퍼가 비디오 버퍼보다 약 6 초 앞당겨졌습니다. 어떻게 든 동기화 된 상태로 유지할 수 있습니까? 내 코드가 어떻게 보이는지 https://pastebin.com/kTzpzm1D – karyboy