【问题标题】:Objective c: Send audio data in rtp packet via socket目标c:通过套接字在rtp数据包中发送音频数据
【发布时间】:2016-02-17 10:05:53
【问题描述】:

在我的应用程序中,我必须捕获麦克风并在 rtp 数据包中发送音频数据。但我只看到接收 rtp 数据,如iOS RTP live audio receiving 或未答复的one

我使用以下代码和AsuncUdpSocket 发送音频数据,但它没有包装在 rtp 数据包中。是否有任何库可以将我的音频数据包装到 rtp 数据包中?

初始 AsyncUdpSocket:

 udpSender = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];

NSError *error;
[udpSender connectToHost:@"192.168.1.29" onPort:1024 error:&error];   

我在播放回调函数中发送音频数据:

static OSStatus playbackCallback(void *inRefCon, 
                             AudioUnitRenderActionFlags *ioActionFlags, 
                             const AudioTimeStamp *inTimeStamp, 
                             UInt32 inBusNumber, 
                             UInt32 inNumberFrames, 
                             AudioBufferList *ioData) {    

/**
 This is the reference to the object who owns the callback.
 */
AudioProcessor *audioProcessor = (AudioProcessor*) inRefCon;

// iterate over incoming stream an copy to output stream
for (int i=0; i < ioData->mNumberBuffers; i++) { 
    AudioBuffer buffer = ioData->mBuffers[i];

    // find minimum size
    UInt32 size = min(buffer.mDataByteSize, [audioProcessor audioBuffer].mDataByteSize);

    // copy buffer to audio buffer which gets played after function return
    memcpy(buffer.mData, [audioProcessor audioBuffer].mData, size);

    // set data size
    buffer.mDataByteSize = size;

    //Send data to remote server      

    NSMutableData *data=[[NSMutableData alloc] init];
    Float32 *frame = (Float32*)buffer.mData;
    [data appendBytes:frame length:size];
    if ([udpSender isConnected])
    {
        [udpSender sendData:data withTimeout:-1 tag:1];
    }


}



return noErr;
} 

我该如何做到这一点?

谢谢。

【问题讨论】:

    标签: objective-c audio-streaming rtp


    【解决方案1】:

    最后,这是我的解决方案。

    设置麦克风捕获过程:

    -(void)open {
    NSError *error;
    m_capture = [[AVCaptureSession alloc]init];
    AVCaptureDevice *audioDev = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
    if (audioDev == nil)
    {
        printf("Couldn't create audio capture device");
        return ;
    }
    //m_capture.sessionPreset = AVCaptureSessionPresetLow;
    
    // create mic device
    AVCaptureDeviceInput *audioIn = [AVCaptureDeviceInput deviceInputWithDevice:audioDev error:&error];
    if (error != nil)
    {
        printf("Couldn't create audio input");
        return ;
    }
    
    
    // add mic device in capture object
    if ([m_capture canAddInput:audioIn] == NO)
    {
        printf("Couldn't add audio input");
        return ;
    }
    [m_capture addInput:audioIn];
    // export audio data
    AVCaptureAudioDataOutput *audioOutput = [[AVCaptureAudioDataOutput alloc] init];
    [audioOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
    if ([m_capture canAddOutput:audioOutput] == NO)
    {
        printf("Couldn't add audio output");
        return ;
    }
    
    
    [m_capture addOutput:audioOutput];
    [audioOutput connectionWithMediaType:AVMediaTypeAudio];
    [m_capture startRunning];
    return ;
    }
    

    捕获麦克风数据:

    -(void) captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection{
    char szBuf[450];
    int  nSize = sizeof(szBuf);
    
    if (isConnect == YES)
    {
    if ([self encoderAAC:sampleBuffer aacData:szBuf aacLen:&nSize] == YES)
    {
        [self sendAudioData:szBuf len:nSize channel:0];
    }
    
    }
    

    初始化套接字

    -(void)initialSocket{
        //Use socket
        printf("initialSocket\n");
        CFReadStreamRef readStream = NULL;
        CFWriteStreamRef writeStream = NULL;
    
        NSString *ip = @"192.168.1.147";   //Your IP Address
        uint *port = 22133;
    
        CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (__bridge CFStringRef)ip, port, &readStream,  &writeStream);
        if (readStream && writeStream) {
        CFReadStreamSetProperty(readStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
        CFWriteStreamSetProperty(writeStream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue);
    
        iStream = (__bridge NSInputStream *)readStream;
        [iStream setDelegate:self];
        [iStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        [iStream open];
    
        oStream = (__bridge NSOutputStream *)writeStream;
        [oStream setDelegate:self];
        [oStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        [oStream open];
        }
    }
    

    从麦克风采集数据时发送数据到socket。

    -(void)sendAudioData: (char *)buffer len:(int)len channel:(UInt32)channel
    {
        Float32 *frame = (Float32*)buffer;
        [globalData appendBytes:frame length:len];
    
        if (isConnect == YES)
        {
            if ([oStream streamStatus] == NSStreamStatusOpen)
            {
                [oStream write:globalData.mutableBytes maxLength:globalData.length];
    
    
                globalData = [[NSMutableData alloc] init];
    
            }
        }
    
    }
    

    希望这会对某人有所帮助。

    【讨论】:

    • 如果我没记错的话,这里你也没有将数据包装为 RTP。或者你在任何方法中都做同样的事情吗?请在这里帮助我,因为我被卡住了,我需要解决方案
    • @Wei Wen Hsiao : 亲爱的。我读了你的问题。我有同样的要求。请就如何为音频流创建 RTP 数据包提供一些建议。
    • 全球数据?它在哪里定义?
    猜你喜欢
    • 2018-05-23
    • 2013-05-05
    • 2013-09-16
    • 1970-01-01
    • 1970-01-01
    • 2017-03-25
    • 1970-01-01
    • 1970-01-01
    • 2018-07-15
    相关资源
    最近更新 更多