欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

掌握iOS直播技术 - 推流之RTP协议详解 原文解析: - 首先,原标题明确了主题是关于iOS直播技术中的推流部分,并且重点介绍了RTP协议。 - 其次,原标题用了一些专业的术语,如“流数据”、“实时传输”等,这可能会让一些非专业人员难以理解。 - 最后,原标题没有明确指出RTP协议的作用和重要性,也没有解释为什么需要了解RTP协议。 : - 我们将原标题简化为“掌握iOS直播技术 - 推流之RTP协议详解”,这样更容易让人明白文章的主题和内容。 - 在中,我们强调了“掌握”这个词,这暗示读者可以通过阅读这篇文章来学习和理解RTP协议。 - 此外,我们也加入了“RTP协议详解”这个短语,这让读者知道本文会详细介绍RTP协议的内容和作用。 修改原因: - 原标题过于专业,可能会让非专业人士感到困惑。我们将标题简化,使其更易于理解。 - 原标题没有明确指出RTP协议的重要性和作用,我们在中强调了这一点。 - 我们希望能够更好地吸引读者的兴趣,让他们愿意花时间阅读本文。

最编程 2024-02-14 19:41:18
...

rtmp创建连接过程:


image.png

连接代码:

- (NSInteger)RTMP264_Connect:(char *)push_url {
    //由于摄像头的timestamp是一直在累加,需要每次得到相对时间戳
    //分配与初始化
    _rtmp = PILI_RTMP_Alloc();
    PILI_RTMP_Init(_rtmp);

    //设置URL
    if (PILI_RTMP_SetupURL(_rtmp, push_url, &_error) == FALSE) {
        //log(LOG_ERR, "RTMP_SetupURL() failed!");
        goto Failed;
    }

    _rtmp->m_errorCallback = RTMPErrorCallback;
    _rtmp->m_connCallback = ConnectionTimeCallback;
    _rtmp->m_userData = (__bridge void *)self;
    _rtmp->m_msgCounter = 1;
    _rtmp->Link.timeout = RTMP_RECEIVE_TIMEOUT;
    
    //设置可写,即发布流,这个函数必须在连接前使用,否则无效
    PILI_RTMP_EnableWrite(_rtmp);

    //连接服务器
    if (PILI_RTMP_Connect(_rtmp, NULL, &_error) == FALSE) {
        goto Failed;
    }

    //连接流
    if (PILI_RTMP_ConnectStream(_rtmp, 0, &_error) == FALSE) {
        goto Failed;
    }

    if (self.delegate && [self.delegate respondsToSelector:@selector(socketStatus:status:)]) {
        [self.delegate socketStatus:self status:LFLiveStart];
    }

    [self sendMetaData];

    _isConnected = YES;
    _isConnecting = NO;
    _isReconnecting = NO;
    _isSending = NO;
    return 0;

Failed:
    PILI_RTMP_Close(_rtmp, &_error);
    PILI_RTMP_Free(_rtmp);
    _rtmp = NULL;
    [self reconnect];
    return -1;
}

音视频编码后上传数据:

#pragma mark -- EncoderDelegate
- (void)audioEncoder:(nullable id<WSAudioEncoding>)encoder audioFrame:(nullable WSAudioFrame *)frame {
    // 上传  时间戳对齐
    if (self.uploading){
        self.hasCaptureAudio = YES;
        if(self.AVAlignment) [self pushSendBuffer:frame];
    }
}

- (void)videoEncoder:(nullable id<WSVideoEncoding>)encoder videoFrame:(nullable WSVideoFrame *)frame {
    // 上传 时间戳对齐
    if (self.uploading){
        if(frame.isKeyFrame && self.hasCaptureAudio) self.hasKeyFrameVideo = YES;
        if(self.AVAlignment) [self pushSendBuffer:frame];
    }
}