使用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
- 【Scikit-Learn 中文文档】内核岭回归 - 监督学习 - 用户指南 | ApacheCN
- 可视化(番外篇)——在Eclipse RCP中玩转OpenGL
- 养良好C语言编程风格,编优质C语言代码,这才是C语言的开始
- IBM让《星球大战》中的各种黑科技变成现实
- 学习SVM(二) 如何理解支持向量机的最大分类间隔
- 解密区块链:不可编辑性带来的问题
- 学习SVM(三)理解SVM中的对偶问题
- 学习SVM(四) 理解SVM中的支持向量(Support Vector)
- 转行数据挖掘和机器学习(四)
- 了解ASP.NET MVC几种ActionResult的本质:JavaScriptResult & JsonResult
- 学习SVM(五)理解线性SVM的松弛因子
- 了解ASP.NET MVC几种ActionResult的本质:EmptyResult & ContentResult
- 可视化(番外篇)——SWT总结
- 新年必看!预测2018年将是区块链爆发的行情
- 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 数组属性和方法
- 实战 | PyQt5制作雪球网股票数据爬虫工具
- 别再问我Python怎么操作Word了!
- Vaex :突破pandas,快速分析100GB大数据集
- 【适合收藏】为了多点时间陪女朋友,我向BAT大佬跪求了这15条JS技巧
- Flask框架教程汇总(1)---视图/重定向/传参
- OkHttp请求耗时统计
- Ubuntu 18.04 通过 Docker 快速部署 Smokeping 2.6.11 教程
- MySQL 8.0新特性 — 函数索引
- Docker快速上手指北(一)【技术创作101训练营】
- leetcode树之二叉搜索树的最近公共祖先
- 【技术创作101训练营】技术角 | 在CentOS 8上使用Nginx 1.18: 基本配置
- Java诊断应用之Arthas实战(技术创作101训练营)
- 突击并发编程JUC系列-数组类型AtomicLongArray
- 个人量化投资体系搭建(一)
- 服务端的 WebAssembly 与 Rust 入门篇