RTSP服务器:一个传输h264/aac的RTSP服务器

该博客详细介绍了如何利用RTSP协议结合RTP传输H264和AAC码流,实现一个RTSP服务器。通过解析VLC客户端请求,响应PLAY指令并调用相应函数传输码流数据。示例代码展示了从接收客户端请求到发送响应及播放码流的过程。
摘要由CSDN通过智能技术生成

点击 RTSP实时监控项目:项目索引,回到目录。
image-20210625175348651

糅合RTSP协议实现RTP传输h264码流/RTP传输aac码流,即可实现一个传输h264码流的RTSP服务器。


基于RTSP与VLC的交互流程,在接收到PLAY请求时,使用rtp_play_h264传输视频码流,或使用rtp_play_aac传输音频码流。

①传输h264码流:do_client(client_sockfd, &client, rtp_fd, rtcp_fd, rtp_play_h264);

②传输aac码流:do_client(client_sockfd, &client, rtp_fd, rtcp_fd, rtp_play_aac);


do_client函数原型

static void do_client(int clientSockfd, client_t *client,
        int serverRtpSockfd, int serverRtcpSockfd, playfunc_t func)

职责:解析vlc客户端请求,响应并传输码流数据

#define BUF_MAX_SIZE    (1024*1024)
typedef int (*playfunc_t) (int, client_t *);
int rtp_play_null(int rtp_sockfd, client_t *client) {}

static void do_client(int clientSockfd, client_t *client,
        int serverRtpSockfd, int serverRtcpSockfd, playfunc_t func)
{
    char method[40], url[100], version[40];
    char *bufPtr;
    char* rbuf = malloc(BUF_MAX_SIZE);
    char* sbuf = malloc(BUF_MAX_SIZE);
    char line[400];
    
    int cseq = 0, recvLen;
    while(1)
    {
        recvLen = recv(clientSockfd, rbuf, BUF_MAX_SIZE, 0);
        if(recvLen <= 0)
            goto out;

        rbuf[recvLen] = '\0';
        printf("---------------C->S--------------\n");
        printf("%s", rbuf);

        /* 解析方法 */
        bufPtr = getLineFromBuf(rbuf, line);
        if(sscanf(line, "%s %s %s\r\n", method, url, version) != 3)
        {
            printf("parse err\n");
            goto out;
        }

        /* 解析序列号 */
        bufPtr = getLineFromBuf(bufPtr, line);
        if(sscanf(line, "CSeq: %d\r\n", &cseq) != 1)
        {
            printf("parse err\n");
            goto out;
        }

        /* 如果是SETUP,那么就再解析client_port */
        if (!strcmp(method, "SETUP")) {
            while(1) {
                bufPtr = getLineFromBuf(bufPtr, line);
                if (!strncmp(line, "Transport:", strlen("Transport:"))) {
                    sscanf(line, "Transport: RTP/AVP;unicast;client_port=%d-%d\r\n",
                            &client->rtp_port, &client->rtcp_port);
                    break;
                }
            }
        }

        if (!strcmp(method, "OPTIONS"))
            loadptk_OPTIONS(sbuf, cseq);
        else if (!strcmp(method, "DESCRIBE"))
            loadptk_DESCRIBE(sbuf, cseq, url);
        else if (!strcmp(method, "SETUP"))
            loadptk_SETUP(sbuf, cseq, client->rtp_port);
        else if (!strcmp(method, "PLAY")) {
            loadptk_PLAY(sbuf, cseq);
        }
        else
            goto out;

        printf("---------------S->C--------------\n");
        printf("%s", sbuf);
        send(clientSockfd, sbuf, strlen(sbuf), 0);
            
        // 响应完成后,再发码流数据
        if (!strcmp(method, "PLAY")) { 
            printf("start play\n");
            func(serverRtpSockfd, client);
            printf("play finish.\n");
        }
    }
out:
    close_socket(clientSockfd);
    free(rbuf);
    free(sbuf);
}

运行测试:
image-20210622215129971

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值