Ağ üzerinden video ve ses akışı yapan bir iOS uygulaması yazıyorum.Bir AAC akışını belleğe kodlamak için AVCaptureSession kullanabilir miyim?
Ben AVCaptureVideoDataOutput kullanarak ham video kareleri yakala ve yazılım using x264 onları kodlamak için AVCaptureSession kullanıyorum. Bu harika çalışıyor.
Ses için de aynısını yapmak istedim, yalnızca ses tarafında o kadar fazla kontrole ihtiyacım yok ki bu yüzden bir AAC akışı oluşturmak için yerleşik donanım kodlayıcısını kullanmak istedim. Bu, Ses Araç Kutusu katmanından Audio Converter kullanılması anlamına geliyordu. ses dönüştürücü geri arama işlevi oldukça basittir Bu durumda
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection
{
// get the audio samples into a common buffer _pcmBuffer
CMBlockBufferRef blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer);
CMBlockBufferGetDataPointer(blockBuffer, 0, NULL, &_pcmBufferSize, &_pcmBuffer);
// use AudioConverter to
UInt32 ouputPacketsCount = 1;
AudioBufferList bufferList;
bufferList.mNumberBuffers = 1;
bufferList.mBuffers[0].mNumberChannels = 1;
bufferList.mBuffers[0].mDataByteSize = sizeof(_aacBuffer);
bufferList.mBuffers[0].mData = _aacBuffer;
OSStatus st = AudioConverterFillComplexBuffer(_converter, converter_callback, (__bridge void *) self, &ouputPacketsCount, &bufferList, NULL);
if (0 == st) {
// ... send bufferList.mBuffers[0].mDataByteSize bytes from _aacBuffer...
}
}
(paket boyutlarını varsayarak ve sayımlar düzgün kurulum vardır): Bunu yapmak için ben AVCaptudeAudioDataOutput 'ın ses çerçeveler için bir işleyici koymak:
- (void) putPcmSamplesInBufferList:(AudioBufferList *)bufferList withCount:(UInt32 *)count
{
bufferList->mBuffers[0].mData = _pcmBuffer;
bufferList->mBuffers[0].mDataByteSize = _pcmBufferSize;
}
Ve ses dönüştürücü kurulum
şuna benzer:{
// ...
AudioStreamBasicDescription pcmASBD = {0};
pcmASBD.mSampleRate = ((AVAudioSession *) [AVAudioSession sharedInstance]).currentHardwareSampleRate;
pcmASBD.mFormatID = kAudioFormatLinearPCM;
pcmASBD.mFormatFlags = kAudioFormatFlagsCanonical;
pcmASBD.mChannelsPerFrame = 1;
pcmASBD.mBytesPerFrame = sizeof(AudioSampleType);
pcmASBD.mFramesPerPacket = 1;
pcmASBD.mBytesPerPacket = pcmASBD.mBytesPerFrame * pcmASBD.mFramesPerPacket;
pcmASBD.mBitsPerChannel = 8 * pcmASBD.mBytesPerFrame;
AudioStreamBasicDescription aacASBD = {0};
aacASBD.mFormatID = kAudioFormatMPEG4AAC;
aacASBD.mSampleRate = pcmASBD.mSampleRate;
aacASBD.mChannelsPerFrame = pcmASBD.mChannelsPerFrame;
size = sizeof(aacASBD);
AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, 0, NULL, &size, &aacASBD);
AudioConverterNew(&pcmASBD, &aacASBD, &_converter);
// ...
}
Bu oldukça düz görünüyor Sadece BT'yi İZİN VERMEZ. AVCaptureSession çalışırken, ses dönüştürücü (özellikle AudioConverterFillComplexBuffer) bir 'hwiu' (kullanımda donanım) hatası döndürür. Oturum durduğunda dönüşüm iyi çalışıyor, ancak daha sonra hiçbir şey yakalayamıyorum ...
AVCaptureSession'dan bir AAC akışı almanın bir yolu olup olmadığını merak ediyordum. Ben düşünüyorum seçenekleri şunlardır:
- nasılsa AAC halinde ses örnekleri kodlamak ve ardından (sadece bir dosyaya yazardı ki AVAssetWriter aracılığıyla) nasılsa kodlanmış paketleri almak için AVAssetWriterInput kullanarak.
Uygulamamı yeniden düzenleme, böylece yalnızca video tarafında AVCaptureSession kullanıyor ve ses tarafında Audio Queues kullanıyor. Bu, akış kontrolünü (kaydı başlatmayı ve durdurmayı, kesintilere cevap vermeyi) daha karmaşık hale getirecek ve korkarım ki ses ve görüntü arasındaki eşzamanlama sorunlarına neden olabilir. Ayrıca, sadece iyi bir tasarım gibi görünmüyor.
AAC'yi AVCaptureSession'dan çıkarmak mümkün olup olmadığını bilen var mı? Ses Kuyruklarını burada kullanmak zorunda mıyım? Bu beni senkronize etme veya kontrol problemlerine sokabilir mi?
AudioConverter cihazınızın hiç çalıştığından emin misiniz? Yakalama işlemini kapatıp bazı sıfırları kodlamayı denediniz mi? –
Evet, yaptım (Sanırım bu konuda da bahsettim). AVCaptureSession 'çalışıyor' durumunda değilse kodlayıcı iyi çalışır. – Avner
oops, üzgünüm. bir bağın varmış gibi görünüyor. yakalama oturumunuza bir ses girişi eklemek AAC kodlayıcısını bağlamış gibi görünüyor. –