녹음 앱을 부지런히 만들고 있던 어느 날
내 앞에 나타난 알 수 없는 에러
Error Domain=AVFoundationErrorDomain Code=-11800
"The operation could not be completed"
UserInfo={NSLocalizedFailureReason=An unknown error occurred (-12780),
NSLocalizedDescription=The operation could not be completed,
NSUnderlyingError=0x282f99a40 {Error Domain=NSOSStatusErrorDomain Code=-12780 "
(null)"}}
말 그대로 알 수 없는 에러였다..
(레벨1 개발자인 나로썬 지금도 이유는 알 수 없다... 해결만 했됐을 뿐..)
앱의 플로우는 아래와 같았다.

위와 같은 플로우가 발생한 이유는 녹음 일시 중지 상태에서 이미 녹음 된 영역에 대해서 덮어쓰기 녹음을 가능하게 하기 위함이었고, 내 머리에서 나온 최적의 방법이었다..!
문제 발생은 이미 녹음 중이던 파일이 있어서 현재 녹음 중인 파일을 임시 저장된 파일과
병합하는 과정에서 발생하였으며, 해당 부분의 소스는 아래와 같다.
// 임시 파일 track
let stashAudioTrack = AVAsset(url: stashRecordingFileUrl).tracks(withMediaType: .audio).first!
// 녹음 파일 track
let recordingAudioTrack = AVAsset(url: recordingFileUrl).tracks(withMediaType: .audio).first!
let composition = AVMutableComposition()
let compositionAudioTrack = composition.addMutableTrack(withMediaType: .audio,
preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid))
do {
// 이 아랫 줄이 문제의 에러 발생 부분
try compositionAudioTrack?.insertTimeRange(stashAudioTrack.timeRange, of: stashAudioTrack, at: .zero)
compositionAudioTrack?.removeTimeRange(CMTimeRangeMake(start: CMTimeMake(value: Int64(recordingStartMeterIndex), timescale: 10),
duration: recordingAudioTrack.timeRange.duration))
try compositionAudioTrack?.insertTimeRange(recordingAudioTrack.timeRange,
of: recordingAudioTrack,
at: CMTimeMake(value: Int64(recordingStartMeterIndex), timescale: 10))
} catch {
print("joshua error is \(error)")
return
}
removeRecordingFiles()
let exporter = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetAppleM4A)!
exporter.outputURL = stashRecordingFileUrl
exporter.outputFileType = AVFileType.m4a
exporter.shouldOptimizeForNetworkUse = true
exporter.exportAsynchronously {[weak self] in
... 후략 ...
리서치를 해보았으나 마땅한 해결책 역시 찾지 못했다...
이건 방법이라고 하기엔 좀 무리가 있다...
// 이 코드를
let stashAudioTrack = AVAsset(url: stashRecordingFileUrl).tracks(withMediaType: .audio).first!
let recordingAudioTrack = AVAsset(url: recordingFileUrl).tracks(withMediaType: .audio).first!
// 이렇게 변수에 한번 할당 후 작업
let stashAudioAsset = AVAsset(url: stashRecordingFileUrl)
let recordingAudioAsset = AVAsset(url: recordingFileUrl)
let stashAudioTrack = stashAudioAsset.tracks(withMediaType: .audio).first!
let recordingAudioTrack = recordingAudioAsset.tracks(withMediaType: .audio).first!
위와 같이 하니 해결이 되었다..
(왜...?)
별볼일 없는 내용과 해결방법을 작성하였음을 알고있다.
하지만, 자세히 작성하진 않았으나 리서치 중 해당 이슈가 Apple 에서 공인한 버그라는
내용이 존재하여 적잖게 당황했던 이슈였다.
때문에 혹시나 누군가에게 도움이 될까 싶어 조심스레 작성을 해보았다.
때문에.. 혹시 이유를 아시는 분이 계시다면 조심스레 댓글을 부탁드립니다..
끝😔