使用librtmp推流/拉流
时间:2022-05-03
本文章向大家介绍使用librtmp推流/拉流,主要内容包括准备工作、推流、拉流、清理资源、Github、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
准备工作
#include "librtmp/rtmp_sys.h"
#include "librtmp/log.h"
#pragma comment(lib, "librtmp.lib")
#pragma comment(lib, "WS2_32.lib")
WORD version;
WSADATA wsaData;
version = MAKEWORD(1, 1);
WSAStartup(version, &wsaData);
int res = 0;
RTMP* rtmp = RTMP_Alloc();
RTMP_Init(rtmp);
推流
res = RTMP_SetupURL(rtmp, "rtmp://192.168.34.40/live/test");//推流
PRINTERROR(res, 1, "RTMP_SetupURL error.n");
//if unable,the AMF command would be 'play' instead of 'publish'
RTMP_EnableWrite(rtmp);//推流要设置写
res = RTMP_Connect(rtmp, NULL);
PRINTERROR(res, 1, "RTMP_Connect error.n");
res = RTMP_ConnectStream(rtmp,0);
PRINTERROR(res, 1, "RTMP_ConnectStream error.n");
//推流
FILE *fp_push=fopen("save.flv","rb");
FlvHeader flvheader;
fread(&flvheader, sizeof(flvheader), 1, fp_push);
int32_t preTagLen = 0;//前一个Tag长度
fread(&preTagLen, 4, 1, fp_push);
TagHeader tagHeader;
uint32_t begintime=RTMP_GetTime(),nowtime,pretimetamp = 0;
while (true)
{
fread(&tagHeader, sizeof(tagHeader), 1, fp_push);
if(tagHeader.type != 0x09)
{
int num = FINT24TOINT(tagHeader.datalen);
fseek(fp_push, FINT24TOINT(tagHeader.datalen)+4, SEEK_CUR);
continue;
}
fseek(fp_push, -sizeof(tagHeader), SEEK_CUR);
if((nowtime=RTMP_GetTime()-begintime)<pretimetamp)
{
printf("%d - %dn", pretimetamp, nowtime);
Sleep(pretimetamp-nowtime);
continue;
}
char* pFileBuf=(char*)malloc(11+FINT24TOINT(tagHeader.datalen)+4);
memset(pFileBuf,0,11+FINT24TOINT(tagHeader.datalen)+4);
if(fread(pFileBuf,1,11+FINT24TOINT(tagHeader.datalen)+4,fp_push)!=11+FINT24TOINT(tagHeader.datalen)+4)
break;
if ((res = RTMP_Write(rtmp,pFileBuf,11+FINT24TOINT(tagHeader.datalen)+4)) <= 0)
{
printf("RTMP_Write end.n");
break;
}
pretimetamp = FINT24TOINT(tagHeader.timestamp);
free(pFileBuf);
pFileBuf=NULL;
}
//推流结束
拉流
res = RTMP_SetupURL(rtmp, "rtmp://live.hkstv.hk.lxdns.com/live//hks");//拉流
PRINTERROR(res, 1, "RTMP_SetupURL error.n");
//if unable,the AMF command would be 'play' instead of 'publish'
//RTMP_EnableWrite(rtmp);//推流要设置写
res = RTMP_Connect(rtmp, NULL);
PRINTERROR(res, 1, "RTMP_Connect error.n");
res = RTMP_ConnectStream(rtmp,0);
PRINTERROR(res, 1, "RTMP_ConnectStream error.n");
//拉流
int nRead = 0, NRead = 0;
int bufsize = 1024*1024;
char* buf = (char*)malloc(bufsize);
FILE* fp_save = fopen("save.flv", "wb");
while(nRead=RTMP_Read(rtmp,buf,bufsize))
{
fwrite(buf,1,nRead,fp_save);
NRead += nRead;
RTMP_LogPrintf("Receive: %5dByte, Total: %5.2fkBn",nRead,NRead*1.0/1024);
}
//拉流结束
清理资源
RTMP_Close(rtmp);
RTMP_Free(rtmp);
WSACleanup();
Github
https://github.com/gongluck/testLibRtmp.git
- Event Loop
- 把图片变成字体,然后在引入到网页
- Flutter环境搭建
- java.net.ConnectException: Call From slaver1/192.168.19.128 to slaver1:8020 failed on connection exc
- 18/03/18 04:53:44 WARN TaskSchedulerImpl: Initial job has not accepted any resources; check your clu
- 技术干货 | Hadoop3.0稳定版安装攻略来啦!
- ios逆向工具MonkeyDev简介
- 自定义下拉列表
- 身份证号码验证算法
- 技术干货 | hive安装部署
- js图片的预加载功能
- 简单理解通过原型继承
- 为我们的Web添加HTTPS支持
- 技术干货 | hbase配置详解
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- OpenCV与图像处理(四)
- 常用功能加载宏——单元格数据连接
- Nest.js 从零到壹系列(八):使用 Redis 实现登录挤出功能
- 创建常用功能加载宏
- 3分钟短文 | Linux 使用curl发起post请求的4个常用方式
- 类模块——接口
- OpenCV与图像处理(三)
- 常用功能加载宏——单元格数字转变
- OpenCV与图像处理(二)
- ECCV2020 | SOD100K:超低参数量的高效显著性目标检测算法,广义OctConv和动态权重衰减
- Rust FFI 编程 - Rust导出共享库02
- 常用功能加载宏——单元格数字格式
- 【翻译】200行代码讲透RUST FUTURES (2)
- 【Rust日报】2020-07-23 Rust 的 CI 将使用 GitHub Actions
- 【每周一库】- Tonic 基于Rust的gRPC实现