日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

RTMP 推流代码

發布時間:2023/12/20 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 RTMP 推流代码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

初始化部分
av_log_set_level(1);
m_pRtmpContex = (RtmpContex*)malloc(sizeof(RtmpContex));
memset(m_Url, 0, 128);
memcpy(m_Url, RTMPUrl, strlen(RTMPUrl));

InitNet();
m_pRtmpContex->pRtmp = RTMP_Alloc();
RTMP_Init(m_pRtmpContex->pRtmp);
m_pRtmpContex->pRtmp->Link.timeout = 5;
RTMP_SetupURL(m_pRtmpContex->pRtmp, RTMPUrl);
RTMP_EnableWrite(m_pRtmpContex->pRtmp);

if (!RTMP_Connect(m_pRtmpContex->pRtmp, NULL)) {RTMP_Close(m_pRtmpContex->pRtmp);OutputDebugString("RTMP ::RTMP_Connect fail\n");return; }

if (!RTMP_ConnectStream(m_pRtmpContex->pRtmp, 0))
{
RTMP_Close(m_pRtmpContex->pRtmp);
OutputDebugString(“RTMP ::RTMP_ConnectStream fail\n”);
return;
}

RTMPPacket_Reset(&m_packet);
RTMPPacket_Alloc(&m_packet, DUMMY_SINK_RECEIVE_BUFFER);
OutputDebugString(“RTMP ::Init sucessful\n”);

發包

int i = 0;
int ret = 0;
long timeoffset = 0;
RTMPPacket_Reset(&m_packet);
unsigned char body = (unsigned char)m_packet.m_body;
if (!m_isfirst){ return 0; }

if (!m_firframe) //第一個包
{
memcpy(body + i, “\x17\x00\x00\x00\x00\x01”, 6); i += 6;
memcpy(body + i, m_pRtmpContex->spsBuf + 1, 3); i += 3;

body[i++] = 0xff;
body[i++] = 0xe1;
body[i++] = (m_pRtmpContex->spslen >> 8) & 0xff;
body[i++] = m_pRtmpContex->spslen & 0xff;
memcpy(body + i, m_pRtmpContex->spsBuf, m_pRtmpContex->spslen); i += m_pRtmpContex->spslen;

body[i++] = 0x01;body[i++] = (m_pRtmpContex->ppsLen >> 8) & 0xff;body[i++] = m_pRtmpContex->ppsLen & 0xff;

memcpy(body + i, m_pRtmpContex->ppsBuf, m_pRtmpContex->ppsLen); i += m_pRtmpContex->ppsLen;

timeoffset = timeGetTime();
m_pRtmpContex->StartTime = (uint32_t)timeoffset;
m_packet.m_packetType = RTMP_PACKET_TYPE_VIDEO;
m_packet.m_nBodySize = i;
m_packet.m_nChannel = 0x04;
m_packet.m_nTimeStamp = (uint32_t)timeoffset;
m_packet.m_hasAbsTimestamp = 0;
m_packet.m_headerType = RTMP_PACKET_SIZE_LARGE;
m_packet.m_nInfoField2 = m_pRtmpContex->pRtmp->m_stream_id;
ret = RTMP_SendPacket(m_pRtmpContex->pRtmp, &m_packet, true);
m_firframe = true;
return 0;
}

//第一個包過后,后面的頭有變化
這里說一下SPS PPS 如果包中涵蓋該信息是不用單獨發的,如果包中不含有,每個GOP是需要帶的
switch (m_type)
{
case AV_MEDIU_TYPE_PFRAME:
memcpy(body + i, “\x27\x01\x00\x00\0x00”, 5); i += 5;
body[i++] = (len >> 24) & 0xff;
body[i++] = (len >> 16) & 0xff;
body[i++] = (len >> 8) & 0xff;
body[i++] = len & 0xff;
memcpy(&body[i], data, len); i = i + len;
//時間戳最好是重新打,如果不重新打,最好保證是升序
timeoffset = timeGetTime();
m_packet.m_hasAbsTimestamp = 0;
m_packet.m_packetType = RTMP_PACKET_TYPE_VIDEO;
m_packet.m_nInfoField2 = m_pRtmpContex->pRtmp->m_stream_id;
m_packet.m_nChannel = 0x04;
m_packet.m_headerType = RTMP_PACKET_SIZE_LARGE;
m_packet.m_nTimeStamp = (uint32_t)timeoffset;
m_packet.m_nBodySize = i;
ret = RTMP_SendPacket(m_pRtmpContex->pRtmp, &m_packet, true);
if (!ret){ OutputDebugString(“RTMP ::RTMP_SendPacket fail\n”); }
return 0;
break;
case AV_MEDIU_TYPE_PPS:
if (!m_firframe) return 0;
timeoffset = timeGetTime();
memcpy(body + i, “\x17\x01\x00\x00\0x00”, 5); i += 5;
body[i++] = (m_pRtmpContex->spslen >> 24) & 0xff;
body[i++] = (m_pRtmpContex->spslen >> 16) & 0xff;
body[i++] = (m_pRtmpContex->spslen >> 8) & 0xff;
body[i++] = m_pRtmpContex->spslen & 0xff;
memcpy(body + i, m_pRtmpContex->spsBuf, m_pRtmpContex->spslen); i += m_pRtmpContex->spslen;

body[i++] = (m_pRtmpContex->ppsLen >> 24) & 0xff;body[i++] = (m_pRtmpContex->ppsLen >> 16) & 0xff;body[i++] = (m_pRtmpContex->ppsLen >> 8) & 0xff;body[i++] = m_pRtmpContex->ppsLen & 0xff;memcpy(body + i, m_pRtmpContex->ppsBuf, m_pRtmpContex->ppsLen); i += m_pRtmpContex->ppsLen;m_packet.m_hasAbsTimestamp = 0;m_packet.m_packetType = RTMP_PACKET_TYPE_VIDEO;m_packet.m_nInfoField2 = m_pRtmpContex->pRtmp->m_stream_id;m_packet.m_nChannel = 0x04;m_packet.m_headerType = RTMP_PACKET_SIZE_LARGE;m_packet.m_nTimeStamp = (uint32_t)timeoffset;m_packet.m_nBodySize = i;ret = RTMP_SendPacket(m_pRtmpContex->pRtmp, &m_packet, true);return 0;break; case AV_MEDIU_TYPE_IFRAME:memcpy(body+i, "\x17\x01\x00\x00\0x00", 5); i += 5;body[i++] = (len >> 24) & 0xff;body[i++] = (len >> 16) & 0xff;body[i++] = (len >> 8) & 0xff;body[i++] = len & 0xff;memcpy(body + i, data, len); i = i + len;timeoffset = timeGetTime();m_packet.m_hasAbsTimestamp = 0;m_packet.m_packetType = RTMP_PACKET_TYPE_VIDEO;m_packet.m_nInfoField2 = m_pRtmpContex->pRtmp->m_stream_id;m_packet.m_nChannel = 0x04;m_packet.m_headerType = RTMP_PACKET_SIZE_LARGE;m_packet.m_nTimeStamp = (uint32_t)timeoffset;m_packet.m_nBodySize = i;ret = RTMP_SendPacket(m_pRtmpContex->pRtmp, &m_packet, true);if (!ret){ OutputDebugString("RTMP ::RTMP_SendPacket fail\n"); }return 0;break;default:break; }return 0;

}

總結

以上是生活随笔為你收集整理的RTMP 推流代码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。