200行代码实现推流到直播平台
原文:https://blog.csdn.net/leixiaohua1020/article/details/42104945
看了雷神的文章后,尝试自己实现推流到YY直播。
主要做了两点改进:
1、支持直播码
2、严格按flv文件中的时间戳推流,解决拉流观看视频卡顿问题
前提:
1、依赖librtmp库,需要自己下载源码编译(网上很多资料),我使用mac已经自带了librtmp库,省去了编译环节
2、注册YY账号,到“个人中心”-> “开播设置”中获取推流地址和直播码,如下图
源码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "librtmp/rtmp.h"
#include "librtmp/log.h"#define HTON16(x) ((x>>8&0xff) | (x<<8&0xff00))
#define HTON24(x) ((x>>16&0xff) | (x<<16&0xff0000) | (x&0xff00))
#define HTON32(x) ((x>>24&0xff) | (x>>8&0xff00) | (x<<8&0xff0000) | (x<<24&0xff000000))
#define HTONTIME(x) ((x>>16&0xff) | (x<<16&0xff0000) | (x&0xff00) | (x&0xff000000))/*read 1 byte*/
int ReadU8(uint32_t *u8, FILE* fp)
{if (fread(u8, 1, 1, fp) != 1){return 0;}return 1;
}/*read 2 byte*/
int ReadU16(uint32_t *u16, FILE* fp)
{if (fread(u16, 2, 1, fp) != 1){return 0;}*u16 = HTON16(*u16);return 1;
}/*read 3 byte*/
int ReadU24(uint32_t *u24, FILE* fp)
{if (fread(u24, 3, 1, fp) != 1){return 0;}*u24 = HTON24(*u24);return 1;
}/*read 4 byte*/
int ReadU32(uint32_t *u32, FILE* fp)
{if (fread(u32, 4, 1, fp) != 1){return 0;}*u32 = HTON32(*u32);return 1;
}/*read 1 byte,and loopback 1 byte at once*/
int PeekU8(uint32_t *u8, FILE* fp)
{if (fread(u8, 1, 1, fp) != 1){return 0;}fseek(fp, -1, SEEK_CUR);return 1;
}/*read 4 byte and convert to time format*/
int ReadTime(uint32_t *utime, FILE* fp)
{if (fread(utime, 4, 1, fp) != 1){return 0;}*utime = HTONTIME(*utime);return 1;
}int main(int argc, char* argv[])
{uint32_t start_time = 0;uint32_t now_time = 0;uint32_t pre_frame_time = 0;uint32_t last_time = 0;
// int bNextIsKey = 0;char* pFileBuf = NULL;uint32_t bufLength = 0;uint32_t type = 0;uint32_t dataLength = 0;uint32_t timestamp = 0;char rtmp_url[] = "[推流地址]";char play_path[] = "[直播码]";FILE* fp = fopen("linchao.flv", "rb");if (!fp){RTMP_LogPrintf("Open File Error.\n");return -1;}RTMP* rtmp = RTMP_Alloc();RTMP_Init(rtmp);rtmp->Link.timeout = 5;if (!RTMP_SetupURL(rtmp, rtmp_url)){RTMP_Log(RTMP_LOGERROR,"SetupURL Err\n");RTMP_Free(rtmp);return -1;}RTMP_EnableWrite(rtmp);RTMP_SetBufferMS(rtmp, 3600*1000);rtmp->Link.playpath.av_val = play_path;rtmp->Link.playpath.av_len = strlen(play_path);if (!RTMP_Connect(rtmp, NULL)){RTMP_Log(RTMP_LOGERROR,"Connect Err\n");RTMP_Free(rtmp);return -1;}if (!RTMP_ConnectStream(rtmp, 0)){RTMP_Log(RTMP_LOGERROR,"ConnectStream Err\n");RTMP_Close(rtmp);RTMP_Free(rtmp);return -1;}RTMP_LogPrintf("Start to send data ...\n");fseek(fp, 9, SEEK_SET);fseek(fp, 4, SEEK_CUR);start_time = RTMP_GetTime();RTMP_LogPrintf("start_time %u\n", start_time);while(1){now_time = RTMP_GetTime() - start_time;if (now_time < pre_frame_time){if (pre_frame_time > last_time){//RTMP_LogPrintf("TimeStamp:%u ms\n", pre_frame_time);last_time = pre_frame_time;}usleep((pre_frame_time - now_time) * 1000);continue;}// jump over typefseek(fp, 1, SEEK_CUR);if (!ReadU24(&dataLength, fp)){break;}if (!ReadTime(×tamp, fp)){break;}// jump backfseek(fp, -8, SEEK_CUR);bufLength = 11 + dataLength + 4;pFileBuf = (char*)malloc(bufLength);memset(pFileBuf, 0, bufLength);if (fread(pFileBuf, 1, bufLength, fp) != bufLength){break;}pre_frame_time = timestamp;if (!RTMP_IsConnected(rtmp)){RTMP_Log(RTMP_LOGERROR, "rtmp is not connect\n");break;}if (!RTMP_Write(rtmp, pFileBuf, bufLength)){RTMP_Log(RTMP_LOGERROR, "Rtmp Write Error\n");break;}free(pFileBuf);pFileBuf = NULL;if (!PeekU8(&type, fp)){break;}}RTMP_LogPrintf("\nSend Data Over\n");fclose(fp);RTMP_Close(rtmp);RTMP_Free(rtmp);rtmp = NULL;if (pFileBuf){free(pFileBuf);pFileBuf = NULL;}return 0;
}
github:https://github.com/ChriFang/media/blob/main/rtmp
编译:
g++ -lrtmp publish.cpp -o publish
运行效果:
运行后,进入自己的直播间可以观看到推流的效果了
200行代码实现推流到直播平台相关推荐
- 200行代码如何实现人脸识别开锁应用?
多种条件限制之下,如何完成真人实景游戏场景下的人脸识别开锁功能?云加社区邀请到腾讯科技产品经理-高树磊,分享他是如何用200行代码,从系统架构.硬件选型.到系统搭建,一步步地实现此精致小巧的人脸识别开 ...
- 宁愿“大小周”、每天只写 200 行代码、月薪 8k-17k 人群再涨!揭晓中国开发者真实现状...
作者 | 郑丽媛 出品 | CSDN(ID:CSDNnews) 程序员,一个圈外人羡慕.圈内人喊苦的"神奇"职业--高薪.福利好是旁人羡慕的理由,高压.加班多却也是他们最常见的写照 ...
- 宁愿“大小周”、每天只写 200 行代码、月薪 8k-17k 人群再涨 | 揭晓中国开发者真实现状
作者 | 郑丽媛 出品 | CSDN(ID:CSDNnews) 程序员,一个圈外人羡慕.圈内人喊苦的"神奇"职业--高薪.福利好是旁人羡慕的理由,高压.加班多却也是他们最常见的写照 ...
- js websocket同步等待_WebSocket硬核入门:200行代码,教你徒手撸一个WebSocket服务器...
本文原题"Node.js - 200 多行代码实现 Websocket 协议",为了提升内容品质,有较大修订. 1.引言 最近正在研究 WebSocket 相关的知识,想着如何能自 ...
- 爬虫python代码-Python爬虫教程:200行代码实现一个滑动验证码
Python爬虫教程:教你用200行代码实现一个滑动验证码 做网络爬虫的同学肯定见过各种各样的验证码,比较高级的有滑动.点选等样式,看起来好像挺复杂的,但实际上它们的核心原理还是还是很清晰的,本文章大 ...
- blockchain 区块链200行代码:在JavaScript实现的一个简单的例子
blockchain 区块链200行代码:在JavaScript实现的一个简单的例子 了解blockchain的概念很简单(区块链,交易链块):它是分布式的(即不是放置在同一台机器上,不同的网络设备上 ...
- JavaScript开发区块链只需200行代码
JavaScript开发区块链只需200行代码 用JavaScript开发实现一个简单区块链.通过这一开发过程,你将理解区块链技术是什么:区块链就是一个分布式数据库,存储结构是一个不断增长的链表,链表 ...
- 不到 200 行代码,教你如何用 Keras 搭建生成对抗网络(GAN)
不到 200 行代码,教你如何用 Keras 搭建生成对抗网络(GAN) 生成对抗网络(Generative Adversarial Networks,GAN)最早由 Ian Goodfello ...
- 蒋金楠:200行代码7个对象《ASP.NET Core框架揭密》苏州.NET俱乐部课程分享
[课程名称] <ASP.NET Core框架揭密> [老师介绍] 蒋金楠,同程艺龙机票事业部技术专家,微软最有价值专家(MVP,连续12),多本.NET专著作者.博客园Artech,公众号 ...
- 前端 验证码隐藏怎么实现_Python爬虫教程:200行代码实现一个滑动验证码
Python爬虫教程:教你用200行代码实现一个滑动验证码 做网络爬虫的同学肯定见过各种各样的验证码,比较高级的有滑动.点选等样式,看起来好像挺复杂的,但实际上它们的核心原理还是还是很清晰的,本文章大 ...
最新文章
- 支付宝的架构到底有多牛逼!还没看完我就跪了!
- 自己动手安装ARM交叉编译工具链
- 使用IIS组建PHP服务器
- CSS上下左右居中的几种方法
- Java学习笔记六 常用API对象二
- 如何启动php程序下载,php – 最好的方式来启动下载?
- Java中反射获取成员变量、构造方法、成员方法及类名
- 移动开发出路在哪里?是时候用物联网了!| 技术头条
- C语言单链表的应用,单链表应用
- python灰度处理_python 简单图像处理(9) 灰度变换
- TensorFlow 实现深度神经网络 —— Denoising Autoencoder
- 编译通用无界面版Emacs27.1
- 深入浅出mysql pdf_深入浅出MySQLpdf_深入浅出MySQL下载_深入浅出MySQLmobi
- STM32F103RC单片机ADC1使用TIM1自动触发注入通道组的AD转换
- ACL2021_Lexicon Enhanced Chinese Sequence Labelling Using BERT Adapter
- AUTOCAD——Excel表格导入CAD、CAD合并两兄弟
- 网络工程师笔记--网络安全技术
- python 图片数据集批量打标签
- java大马后门_【猥琐流】制作一个隐藏在黑页下的大马并且添加后门
- html扫码支付,WEB端第三方支付接入 - 支付宝 - 扫码支付