<三:使用,推流端>live555-从buffer读取h264推流

12 篇文章 1 订阅
10 篇文章 2 订阅

使用live555库推流h264,一般从testOnDemandRTSPServer.cpp 修改而来,不过其中都是通过从本地文件,或作类似文件描述符“fd”源中读数据,这类数据源,需要对数据源进行分析处理,拿h264裸文件来说,就需要根据NAL 00 00 00 01 来切分出一帧帧的数据,这是一个消耗资源的操作,如果我们是已经就绪的h264帧数据在内存里,就不需要这一部分,否则造成明显的推流延迟。
testOnDemandRTSPServer.cpp中测试 h264推流的代码。

// A H.264 video elementary stream:
  {
    char const* streamName = "h264ESVideoTest";
    char const* inputFileName = "test.264";
    ServerMediaSession* sms
      = ServerMediaSession::createNew(*env, streamName, streamName,
				      descriptionString);
    sms->addSubsession(H264VideoFileServerMediaSubsession
		       ::createNew(*env, inputFileName, reuseFirstSource));
    rtspServer->addServerMediaSession(sms);

    announceStream(rtspServer, sms, streamName, inputFileName);
  }

被添加到 ServerMediaSession的 ServerMediaSubsession ——H264VideoFileServerMediaSubsession,是继承自FileServerMediaSubsession。 要实现从内存buffer中读264数据的 ServerMediaSubsession, 需要实现自己的 ServerMediaSubsession. 之前有写过一篇:https://blog.csdn.net/u012459903/article/details/86676702
实现了两个自己的类:
class H264LiveVideoServerMediaSubssion : public OnDemandServerMediaSubsession
class H264FramedLiveSource : public FramedSource
在H264LiveVideoServerMediaSubssion 中实现两个关键的函数:createNewStreamSource() ,用来创建source
createNewRTPSink() 创建sink。 对于FileServerMeidiaSubsession, 创建的输入源。但是之前的这篇blog在创建 StreamSource的时候依然用了 return H264VideoStreamFramer::createNew(envir(), liveSource);  把得到的流再用 H264VideoStreamFramer进行了一遍”过滤“,这个H264VideoStramFramer内部会重新从流数据中遍历,找出 NAL, 分离出h264帧,这个过程是多余的并且消耗资源,导致实际推流有明显延迟。这里更正:

#if 0
	// Create a framer for the Video Elementary Stream:
	//return H264VideoStreamFramer::createNew(envir(), liveSource);
#else 
	//不需要parse, 直接就是完整的一帧
	return H264VideoStreamDiscreteFramer::createNew(envir(), liveSource);

#endif 

使用 H264VideoStreamDiscreteFramer来代替H264VideoStreamFramer。 注意这个H264VideoStreamDiscreteFramer 要求输入的数据不带 NAL头。不然一直在抱怨。

 

读取FLV文件并将其通过RTMP推流到本地服务器,需要使用C语言编写程序,并使用一些第方库来完成这个过程。以下是一个实现此过程的简单示例程序: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include <librtmp/rtmp.h> #define BUFFER_SIZE 4096 int main(int argc, char *argv[]) { if (argc < 3) { printf("Usage: %s file.rtmp rtmp://localhost/live/stream\n", argv[0]); return 1; } const char *rtmp_url = argv[1]; const char *stream_url = argv[2]; // 初始化 RTMP RTMP *rtmp = RTMP_Alloc(); RTMP_Init(rtmp); RTMP_SetupURL(rtmp, rtmp_url); RTMP_EnableWrite(rtmp); // 连接 RTMP 服务器 if (!RTMP_Connect(rtmp, NULL)) { printf("Failed to connect RTMP server: %s\n", rtmp_url); return 1; } // 连接流 if (!RTMP_ConnectStream(rtmp, 0)) { printf("Failed to connect stream: %s\n", stream_url); return 1; } // 打开 FLV 文件 FILE *fp = fopen(stream_url, "rb"); if (!fp) { printf("Failed to open file: %s\n", stream_url); return 1; } // 读取 FLV 文件并推流 uint8_t buffer[BUFFER_SIZE]; int nread = 0; while ((nread = fread(buffer, 1, BUFFER_SIZE, fp)) > 0) { if (!RTMP_Write(rtmp, buffer, nread)) { printf("Failed to write data to RTMP stream\n"); break; } } // 关闭文件和 RTMP 连接 fclose(fp); RTMP_Close(rtmp); RTMP_Free(rtmp); return 0; } ``` 这个示例程序使用 librtmp 库来连接 RTMP 服务器,并使用标准的文件 I/O 函数来读取 FLV 文件。在此过程中,程序将 FLV 文件中的数据写入 RTMP 流中,从而将其推流到服务器。 注意,这个示例程序只是一个简单的演示,实际应用中需要更加完善和健壮的错误处理。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值