专栏首页转载gongluck的CSDN博客使用librtmp推流/拉流

使用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 条评论
登录 后参与评论

相关文章

  • FFmpeg菜鸡互啄#第4篇#音频解码

    解码过程 音频解码跟上一篇的视频解码过程是一样的:打开输入文件,查找音频流,打开解码器,循环读帧解码帧,关闭解码器,关闭输入文件。 Code #define _...

    _gongluck
  • python笔记:#012#函数

    函数基础 目标 函数的快速体验 函数的基本使用 函数的参数 函数的返回值 函数的嵌套调用 在模块中定义函数 01. 函数的快速体验 1.1 快速体验 所谓函数,...

    _gongluck
  • FFmpeg菜鸡互啄#第6篇#音频帧格式转换(重采样)

    关键步骤 struct SwrContext* swr_covert_ctx = swr_alloc_set_opts(NULL, av_get_def...

    _gongluck
  • Android平台下RTMPDump的使用简介

    RTMPDump是一个用来处理RTMP流媒体的工具包,是一个C++的开源工程。而我们需要将Android平台下直接使用RTMPDump来进行RTMP推流,这里就...

    用户2929716
  • 抓包工具Wireshark过滤规则实践第一篇

    引子 现在从网上看到的一些wireshark过滤规则的介绍,都是比较老一点的,新版本的语法好像有所变化,所以在这里写一篇基于最新的1.12版本的wireshar...

    程序员互动联盟
  • 如何高效回退到特定层级目录?

    如果层级比较少,那这样勉强还可以接受,但如果层级很深,那可能就会 cd 到你怀疑人生了。

    用户6543014
  • 我眼中的网络设备虚拟化

    虚拟化是利用技术手段做到“一虚多、多虚一”,从而达到提升设备资源利用率以及加强系统可靠性和可用性的重要技术手段。专门做虚拟化的ICT厂商VMware...

    ICT售前新说
  • 一个月真的可以学会一门语言吗?

    知乎上总看到有人提这个问题, 我想转行,我要学多久才能学会,分享下我到经历,以便你评估一下自身来不来得及,别人是没办法帮你评估的。

    王炸
  • 解构吞噬世界的云原生:概念、炒作背后的理念与技术

    MegaEase创始人、酷壳博主陈皓老师高屋建瓴地解释了云原生产生、发展的历史背景,他指出,企业平台化(云原生)架构具备以下几个优势:

    TVP官方团队
  • HTTP中的重定向

    URL 重定向,也称为 URL 转发,是一种当实际资源,如单个页面、表单或者整个 Web 应用被迁移到新的 URL 下的时候,保持(原有)链接可用的技术。HTT...

    刘亦枫

扫码关注云+社区

领取腾讯云代金券