一、RTMP推流方式一:推H.264、ACC
1、创建一个线程来初始化RTMP。

void RtmpPush::init() {LOGE("init()");mCallJava->onConnectint(THREAD_MAIN);pthread_create(&push_thread, NULL, callBackPush, this);}void *callBackPush(void *data)
{RtmpPush *rtmpPush = static_cast<RtmpPush *>(data);rtmpPush->startPushing = false;LOGE("callBackPush()");//RTMP 申请堆内存rtmpPush->rtmp = RTMP_Alloc();//RTMP 初始化RTMP_Init(rtmpPush->rtmp);rtmpPush->rtmp->Link.timeout = 10;rtmpPush->rtmp->Link.lFlags |= RTMP_LF_LIVE;//设置推流地址RTMP_SetupURL(rtmpPush->rtmp, rtmpPush->url);//打开输出模式,这里推流的时候.(拉流的时候可以不用开启)RTMP_EnableWrite(rtmpPush->rtmp);//连接服务器if(!RTMP_Connect(rtmpPush->rtmp, NULL)){//LOGE("can not connect the url");rtmpPush->mCallJava->onConnectFail("RTMPConnectsFaile");goto end;}if(!RTMP_ConnectStream(rtmpPush->rtmp, 0)){//LOGE("can not connect the stream of service");rtmpPush->mCallJava->onConnectFail("RTMPConnectStreamFaile");goto end;}rtmpPush->mCallJava->onConnectsuccess();LOGE("链接成功, 开始推流");rtmpPush->startPushing = true;rtmpPush->startTime = RTMP_GetTime();while(true){if(!rtmpPush->startPushing){break;}RTMPPacket *packet = NULL;packet = rtmpPush->queue->getRtmpPacket();if(packet != NULL){//发送数据包int result = RTMP_SendPacket(rtmpPush->rtmp, packet, 1);//LOGE("RTMP_SendPacket result is %d", result);if(!result){rtmpPush->mCallJava->onConnectFail("rtmpSocketDisconnect");goto end;}RTMPPacket_Free(packet);free(packet);packet = NULL;}}end:RTMP_Close(rtmpPush->rtmp);RTMP_Free(rtmpPush->rtmp);rtmpPush->rtmp = NULL;pthread_exit(&rtmpPush->push_thread);
}

2、RTMP发送SPS、PPS

void RtmpPush::pushSPSPPS(char *sps, int sps_len, char *pps, int pps_len) {int bodysize = sps_len + pps_len + 16;RTMPPacket *packet = static_cast<RTMPPacket *>(malloc(sizeof(RTMPPacket)));RTMPPacket_Alloc(packet, bodysize);RTMPPacket_Reset(packet);char *body = packet->m_body;int i = 0;body[i++] = 0x17;body[i++] = 0x00;body[i++] = 0x00;body[i++] = 0x00;body[i++] = 0x00;body[i++] = 0x01;body[i++] = sps[1];body[i++] = sps[2];body[i++] = sps[3];body[i++] = 0xFF;body[i++] = 0xE1;body[i++] = (sps_len >> 8) & 0xff;body[i++] = sps_len & 0xff;memcpy(&body[i], sps, sps_len);i += sps_len;body[i++] = 0x01;body[i++] = (pps_len >> 8) & 0xff;body[i++] = pps_len & 0xff;memcpy(&body[i], pps, pps_len);packet->m_packetType = RTMP_PACKET_TYPE_VIDEO;packet->m_nBodySize = bodysize;packet->m_nTimeStamp = 0;packet->m_hasAbsTimestamp = 0;packet->m_nChannel = 0x04;packet->m_headerType = RTMP_PACKET_SIZE_MEDIUM;packet->m_nInfoField2 = rtmp->m_stream_id;queue->putRtmpPacket(packet);
}

3、发送视频数据

void RtmpPush::pushVideoData(char *data, int data_len, bool keyframe) {int bodysize = data_len + 9;RTMPPacket *packet = static_cast<RTMPPacket *>(malloc(sizeof(RTMPPacket)));RTMPPacket_Alloc(packet, bodysize);RTMPPacket_Reset(packet);char *body = packet->m_body;int i = 0;if(keyframe){body[i++] = 0x17;} else{body[i++] = 0x27;}body[i++] = 0x01;body[i++] = 0x00;body[i++] = 0x00;body[i++] = 0x00;body[i++] = (data_len >> 24) & 0xff;body[i++] = (data_len >> 16) & 0xff;body[i++] = (data_len >> 8) & 0xff;body[i++] = data_len & 0xff;memcpy(&body[i], data, data_len);packet->m_packetType = RTMP_PACKET_TYPE_VIDEO;packet->m_nBodySize = bodysize;packet->m_nTimeStamp = RTMP_GetTime() - startTime;packet->m_hasAbsTimestamp = 0;packet->m_nChannel = 0x04;packet->m_headerType = RTMP_PACKET_SIZE_LARGE;packet->m_nInfoField2 = rtmp->m_stream_id;queue->putRtmpPacket(packet);
}

4、发送音频数据

void RtmpPush::pushAudioData(char *data, int data_len) {int bodysize = data_len + 2;RTMPPacket *packet = static_cast<RTMPPacket *>(malloc(sizeof(RTMPPacket)));RTMPPacket_Alloc(packet, bodysize);RTMPPacket_Reset(packet);char *body = packet->m_body;body[0] = 0xAF;body[1] = 0x01;memcpy(&body[2], data, data_len);packet->m_packetType = RTMP_PACKET_TYPE_AUDIO;packet->m_nBodySize = bodysize;packet->m_nTimeStamp = RTMP_GetTime() - startTime;packet->m_hasAbsTimestamp = 0;packet->m_nChannel = 0x04;packet->m_headerType = RTMP_PACKET_SIZE_LARGE;packet->m_nInfoField2 = rtmp->m_stream_id;queue->putRtmpPacket(packet);
}

二、RTMP推流方式二:推FLV封装格式

int RtmpPush::pushFlvData(char *data, int data_len) {if (data_len < 15) {return -1;}//packet attributesuint32_t type = 0;uint32_t datalength = 0;uint32_t timestamp = 0;uint32_t streamid = 0;memcpy(&type, data, 1);data++;memcpy(&datalength, data, 3);datalength = HTON24(datalength);data += 3;memcpy(&timestamp, data, 4);timestamp = HTONTIME(timestamp);data += 4;memcpy(&streamid, data, 3);streamid = HTON24(streamid);data += 3;//LOGE("解析包数据:%u,%u,%u,%u,%d",type, datalength, timestamp, streamid, data_len);if (type != 0x08 && type != 0x09) {return -2;}if (datalength != (data_len - 11 - 4)) {return -3;}RTMPPacket *packet = static_cast<RTMPPacket *>(malloc(sizeof(RTMPPacket)));RTMPPacket_Alloc(packet, 1024 * 64);RTMPPacket_Reset(packet);memcpy(packet->m_body, data, data_len - 11 - 4);packet->m_headerType = RTMP_PACKET_SIZE_LARGE;packet->m_nTimeStamp = timestamp;packet->m_packetType = type;packet->m_nBodySize = datalength;if(type == RTMP_PACKET_TYPE_AUDIO){packet->m_nChannel = 0x05;//audio}else if(type == RTMP_PACKET_TYPE_VIDEO){packet->m_nChannel = 0x04;//video}else if(type == RTMP_PACKET_TYPE_INFO){packet->m_nChannel = 0x03;//metaData}packet->m_nInfoField2 = rtmp->m_stream_id;queue->putRtmpPacket(packet);return 0;
}

RTMP 两种方式推流:推H.264、ACC和推FLV封装格式相关推荐

  1. 点击/拖拽两种方式,预览并上传png/jpg/jpeg格式图片

    <template><div class="content"><div class="PictureBox"><img ...

  2. php 将二维数组合并,PHP二维数组合并排重的两种方式

    业务中需要统计一段时间投票独立的用户数,涉及到数组的排重,用传统array_unique()发现,当数据量达到百万级后, 设置的1G内存都耗尽了,仍然没有统计完.而用array_flip()发现不仅可 ...

  3. python接口服务两种方式(被调用、主动推送)

    项目中用python开发,要对外接口时,根据场景不同,一般有两种方式: 外部调用python接口,返回数据 接口主动向外部推送数据 1外部调用python接口,返回数据 这种方式一般可以通过http接 ...

  4. 两种方式(goto语句以及while循环)实现C语言关机小程序

    用C语言写的关机小程序简单易懂,可以拿去整蛊室友同学(每天一个挨打小技巧),下面我就给出两种方式实现这个代码,欢迎大家讨论补充. 1.用goto语句实现: #include <stdio.h&g ...

  5. java 生成二维码 QRCode、zxing 两种方式

    版权声明:本文为 testcs_dn(微wx笑) 原创文章,非商用自由转载-保持署名-注明出处,谢谢. https://blog.csdn.net/testcs_dn/article/details/ ...

  6. 内存分配的原理__进程分配内存有两种方式,分别由两个系统调用完成:brk和mmap(不考虑共享内存)

    如何查看进程发生缺页中断的次数? 用ps -o majflt,minflt -C program命令查看. majflt代表major fault,中文名叫大错误,minflt代表minor faul ...

  7. [原][osg][gdal]两种方式修改tiff高程

    因为对于globalmap不熟悉,不怎么怎么修改高程,好像也没有这功能. 干脆自己手动修改了高程图tiff了 由于自身一直使用osg的 自己使用了osgDB直接读取tiff,修改后保存的. 同事小周一 ...

  8. laravel 图片流_laravel实现上传图片的两种方式小结

    第一:是laravel里面自带的上传方式(写在接口里面的) function uploadAvatar(Request $request) { $user_id = Auth::id(); $avat ...

  9. DLL中导出函数的声明有两种方式

    本文引用自:VC编程时DLL中导出函数的声明有两种方式 一种方式是:在函数声明中加上__declspec(dllexport): 另外一种方式是:采用模块定义(.def)文件声明,(.def)文件为链 ...

  10. centos6配置日志外发_CentOS6下记录后台操作日志的两种方式

    CentOS6下记录后台操作日志的两种方式 平时为了记录登录CentOS Linux系统的操作命令,需要将操作日志记录下来,下面介绍两种方式 1.利用script以及scriptreplay工具 sc ...

最新文章

  1. 自定义RadioGrop,支持添加包裹着的RadioButton
  2. The Report(连接查询)
  3. 他是中国投资最厉害的人:投网易一战成名 是巴菲特忠实信徒
  4. 继承 抽象 接口 多态
  5. Redis Lua脚本中学教程(上)
  6. Tomcat 5.0.18 安装配置指南
  7. MATLAB App Designer GUI开发从0到1(实战篇)
  8. java json.tostring,idea以JSON形式重写toString()方法
  9. linux 系统频率,Linux下CPU的手动频率设定
  10. excel表格行列显示十字定位_取消excel单元格十字定位(excle表格里的十字对准)
  11. linux shell 学习时遇到的一些问题([: 11: y: unexpected operator)
  12. phpdesigner8 php7.0,让getter和setter在phpDesigner8中运行
  13. 如何领购和作废电子发票流程
  14. python量化交易策略技巧与实战_量化交易策略基本框架
  15. Eclipse2020下载安装教程详细
  16. python全栈开发中级班全程笔记(第三模块、第一章(多态、封装、反射、内置方法、元类、作业))...
  17. 计算机网络广东海洋大学简答题,广东海洋大学计算机网络历年考题(直接阅读版6套可编辑)...
  18. NOR flash 坏块处理方法
  19. php循环图案正方形,javascript输出指定行数正方形图案效果的实现方法
  20. 透过华为军团看科技之变(二):机场轨道

热门文章

  1. 门禁管理系统服务器,门禁控制软件 门禁管理系统
  2. 盘点JavaScript设计模式(常用十五大设计模式)
  3. 基础练习 回文数 C语言
  4. 计算机基础之二进制详解(二)
  5. 【错误记录】Ubuntu 编译 ffmpeg 报错 ( nasm/yasm not found or too old. Use --disable-x86asm for a crippled bu )
  6. php spider视频教程,phpspider的简单使用
  7. WinAPI 多线程(一)
  8. 5G六大关键技术及未来发展趋势
  9. 有限元方法入门:有限元方法简单的一维算例
  10. ffmpeg 将视频转换为图片