使用librtmp推流/拉流

准备工作

#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 - %d\n", 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.2fkB\n",nRead,NRead*1.0/1024);
    }
    //拉流结束

清理资源

    RTMP_Close(rtmp);
    RTMP_Free(rtmp);
    WSACleanup();

Github

https://github.com/gongluck/testLibRtmp.git

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏菩提树下的杨过

ExtJs学习笔记(4)_EditorGridPanel(可编辑的网格控件)

这一节,我们将看到ExtJs功能强大的可编辑网格控件,几乎与VS.Net的GridView功能一样了,但是ExtJs的可是纯JS的UI 一.静态示例(改自Ext...

6515
来自专栏hbbliyong

WPF里ItemsControl的分组实现 --listbox 实现分组

我们在用到ItemsControl时,有时会用到分组,如ListBox,ListView,DataGrid。WPF的ItemsControl可以实现分组,是依托...

881
来自专栏Jerry的SAP技术分享

使用SAPGUI画图

国内80后上的编程课应该都学过Logo(https://en.wikipedia.org/wiki/Logo_(programming_language)这门编...

1134
来自专栏游戏杂谈

cocos2d-x 2.x版本接入bugly的总结

最开始项目使用的是自己DIY的很简陋的上报系统,后来改成google breakpad来上报,发现其实都做的不太理想,游戏引擎因为版本历史问题存在一些崩溃问题。...

980
来自专栏Golang语言社区

Go中的依赖注入

I have written a small utility package to handle dependency injection in Go (it'...

2124
来自专栏高性能服务器开发

(三) 服务器端的程序架构介绍2

下面我们以pc端登录为例来具体看一个数据包在服务器端各个服务之间走过的流程: 步骤1:login_server初始化侦听socket,设置新连接到来的回调函数。...

3854
来自专栏lulianqi

CASE 文件 范例

<?xml version="1.0" encoding="utf-8"?> <VaneLife_V1><!-- 基本规则,节点名首字母大写,属性首字母小写 -...

1022
来自专栏菩提树下的杨过

ExtJs+WCF+LINQ实现分页Grid

上篇文章《用ExtJs+Linq+Wcf打造简单grid 》,这个网格控件不带分页,本文在上文的基础上添加分页功能,文中会着重介绍如何在用LINQ返回分页数据,...

3397
来自专栏10km的专栏

Ubuntu16:cmake生成Makefile编译caffe过程(OpenBLAS/CPU+GPU)塈解决nvcc warning:The 'compute_20', 'sm_20'

之前在ubuntu14下实现了Caffe编译(参见去年写的博客 《 Ubuntu14:cmake生成Makefile编译caffe过程(OpenBLAS/CPU...

4158
来自专栏xingoo, 一个梦想做发明家的程序员

MFC 随机矩形

问题描述:   简单地使用随即的尺寸和颜色不停的绘制一系列的图像。 一种古老的方式:   设置一个向窗口函数发送WM_TIMER消息的windows计时器。  ...

2025

扫码关注云+社区