Я записываю видео/аудио с помощью AVAssetwriter и хочу иметь возможность писать тихие буферы для проб. Я не так разбираюсь в CoreAudio, поэтому у меня проблемы с рабочим решением.Написание тишины CMSampleBuffer вызывает сбой: CrashIfClientProvidedBogusAudioBufferList
Идея состоит в том, чтобы сохранять видеозапись, когда аудиоустройство отключено до его повторного подключения. Проблема заключается в том, что AVFoundation каким-то образом нажимает аудио на передний план, поэтому полученный файл видео не синхронизирован.
Моя текущая реализация пытается создать пустой/бесшумный CMSampleBuffer для размещения между сегментами, где нет подключенного аудиоустройства.
if (audioOutput == captureOutput && audioWriterInput.readyForMoreMediaData) {
if (needToFillAudioGap) {
CMTime temp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
CMItemCount numSamples = temp.value - lastAudioDisconnect.value;
OSStatus status;
CMBlockBufferRef bbuf = NULL;
CMSampleBufferRef sbuf = NULL;
int nchans = 2;
size_t buflen = numSamples * nchans * sizeof(float);
NSMutableData* data = [NSMutableData dataWithLength:buflen];
void* samples = [data mutableBytes];
status = CMBlockBufferCreateWithMemoryBlock(
kCFAllocatorDefault,
samples,
buflen,
kCFAllocatorNull,
NULL,
0,
buflen,
0,
&bbuf);
if (status != noErr) {
NSLog(@"CMBlockBufferCreateWithMemoryBlock error: %d", (int)status);
return;
}
CMBlockBufferRef blockBufferContiguous;
status = CMBlockBufferCreateContiguous(kCFAllocatorDefault,
bbuf,
kCFAllocatorNull,
NULL,
0,
buflen,
0,
&blockBufferContiguous);
CFRelease(bbuf);
if(status != noErr)
{
printf("CMBlockBufferCreateContiguous failed with error %d\n", (int)status);
return;
}
status = CMAudioSampleBufferCreateReadyWithPacketDescriptions(kCFAllocatorDefault, blockBufferContiguous, CMSampleBufferGetFormatDescription(sampleBuffer), numSamples, lastAudioDisconnect, NULL, &sbuf);
CFRelease(blockBufferContiguous);
if (status != noErr) {
NSLog(@"CMSampleBufferCreate error: %d", (int)status);
return;
}
BOOL r = [audioWriterInput appendSampleBuffer:sbuf];
if (!r) {
NSLog(@"appendSampleBuffer error: %d", (int)status);
return;
}
CFRelease(sbuf);
NSLog(@"Filling Audio Gap");
needToFillAudioGap = false;
} else {
if ([audioWriterInput appendSampleBuffer:sampleBuffer])
lastAudioDisconnect = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
}
}
sampleBuffer на вершине является первым samplebuffer после того, как аудиоустройство повторного подключения. Это дает мне информацию о том, как долго пробел, который я должен заполнить, должен быть. LastAudioDisconnect всегда содержит временную метку презентации из последнего записанного буфера аудио.
С Guard таНос включена программа падает с: CrashIfClientProvidedBogusAudioBufferList
EDIT: С Guard Malloc отключен я могу восстановить аудиоустройство несколько раз во время записи, и когда я остановить запись, разрыв там без проблем ,
Проблема заключается в том, что у меня есть только пара минут, чтобы остановить запись после повторного подключения устройства, потому что AVAssetWriter случайно не работает с кодом 11800 (AVErrorUnknown).
Вы сделали это? @Legi спасибо –