मैं एक आईओएस ऐप लिख रहा हूं जो नेटवर्क पर वीडियो और ऑडियो स्ट्रीम करता है।क्या मैं एएसी स्ट्रीम को स्मृति में एन्कोड करने के लिए AVCaptureSession का उपयोग कर सकता हूं?
मैं AVCaptureSession उपयोग कर रहा हूँ AVCaptureVideoDataOutput का उपयोग कर कच्चे वीडियो फ्रेम आकर्षित करने और उन्हें सॉफ्टवेयर using x264 में एन्कोड करने के लिए। यह बहुत अच्छा काम करता है।
मैं ऑडियो के लिए ऐसा करना चाहता था, केवल मुझे ऑडियो पक्ष पर इतना अधिक नियंत्रण की आवश्यकता नहीं है, इसलिए मैं एएसी स्ट्रीम बनाने के लिए निर्मित हार्डवेयर एन्कोडर का उपयोग करना चाहता था। इसका मतलब ऑडियो टूलबॉक्स परत से Audio Converter का उपयोग करना था।
- (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...
}
}
इस मामले ऑडियो कनवर्टर के लिए कॉलबैक फ़ंक्शन बहुत सरल है (पैकेट आकार संभालने और मायने रखता है ठीक से सेट कर रहे हैं): ऐसा करने के लिए मैं AVCaptudeAudioDataOutput की ऑडियो फ्रेम के लिए कोई हैंडलर में डाल:
- (void) putPcmSamplesInBufferList:(AudioBufferList *)bufferList withCount:(UInt32 *)count
{
bufferList->mBuffers[0].mData = _pcmBuffer;
bufferList->mBuffers[0].mDataByteSize = _pcmBufferSize;
}
और ऑडियो कनवर्टर के लिए सेटअप इस तरह दिखता है:
{
// ...
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);
// ...
}
यह बहुत सीधा लगता है केवल को आगे बढ़ाएं यह काम नहीं करता है। एक बार AVCaptureSession चल रहा है, ऑडियो कनवर्टर (विशेष रूप से AudioConverterFillComplexBuffer) एक 'hwiu' (उपयोग में हार्डवेयर) त्रुटि देता है। सत्र बंद होने पर रूपांतरण ठीक काम करता है लेकिन फिर मैं कुछ भी कैप्चर नहीं कर सकता ...
मैं सोच रहा था कि AVCaptureSession से एएसी स्ट्रीम प्राप्त करने का कोई तरीका है या नहीं। विकल्प पर विचार कर रहा हूँ कर रहे हैं:
किसी तरह AVAssetWriterInput का उपयोग कर एएसी में ऑडियो नमूने एन्कोड करने के लिए और उसके बाद (नहीं AVAssetWriter के माध्यम से है, जो केवल एक फाइल करने के लिए लिखते थे) किसी भी तरह इनकोडिंग पैकेट मिलता है।
मेरे ऐप को पुनर्गठित करना ताकि यह केवल वीडियो पक्ष पर AVCaptureSession का उपयोग करे और ऑडियो पक्ष पर Audio Queues का उपयोग करे। यह प्रवाह नियंत्रण (रिकॉर्डिंग शुरू करना और रोकना, बाधाओं का जवाब देना) अधिक जटिल होगा और मुझे डर है कि यह ऑडियो और वीडियो के बीच सिंकिंग समस्याओं का कारण बन सकता है। इसके अलावा, यह सिर्फ एक अच्छा डिजाइन की तरह प्रतीत नहीं होता है।
क्या किसी को पता है कि AVCaptureSession से एएसी प्राप्त करना संभव है? क्या मुझे यहां ऑडियो कतार का उपयोग करना है? क्या यह मुझे समस्याओं को सिंक करने या नियंत्रित करने में ला सकता है?
क्या आप सुनिश्चित हैं कि आपका ऑडियो कनवर्टर बिल्कुल काम करता है? क्या आपने कुछ शून्यों को कैप्चर करने और एन्कोड करने की कोशिश की है? –
हां, मैंने किया (मुझे लगता है कि मैंने इस सवाल में भी इसका उल्लेख किया है)। AVCaptureSession 'चल रहे' स्थिति में नहीं है तो एन्कोडर ठीक काम करता है। – Avner
ओह, क्षमा करें। ऐसा लगता है कि आप एक बाध्य हैं। आपके कैप्चर सत्र में एक ऑडियो इनपुट जोड़ने से एएसी एन्कोडर को जोड़ना प्रतीत होता है। –