live555 通过rtsp同时拉取多路拉取网络摄像头H264,可保存文件,可推送到rtmp服务;

3 篇文章 0 订阅
1 篇文章 0 订阅

通过示例代码
1.指定配置文件 url.conf
#rtsp://192.168.0.114/1.mkv
#rtsp://192.168.0.114/2.mkv
#rtsp://192.168.0.114/3.mkv
#rtsp://192.168.0.114/4.mkv
#rtsp://192.168.0.114/aaa.264
#rtsp://192.168.0.114/bbb.264
#rtsp://admin:hk123456@192.168.0.64:554/h264/ch1/main/av_stream
rtsp://192.168.153.1/1.mkv
rtsp://192.168.153.1/2.mkv
rtsp://192.168.153.1/3.mkv
rtsp://192.168.153.1/4.mkv
rtsp://192.168.153.1/aaa.264
rtsp://192.168.153.1/bbb.264

void DummySink::afterGettingFrame(void* clientData, unsigned frameSize, unsigned numTruncatedBytes,
	struct timeval presentationTime, unsigned durationInMicroseconds) {
	DummySink* sink = (DummySink*)clientData;
	sink->afterGettingFrame(frameSize, numTruncatedBytes, presentationTime, durationInMicroseconds);
}



 if (fStreamId != NULL) printf("Stream url: %s \t mediumName: %s \t codecName: %s \t pkt_Size %d\n", fStreamId, fSubsession.mediumName(), fSubsession.codecName(), frameSize) ;
	

#if 1 //rtmp 推流
	if (!strcmp(fSubsession.mediumName(), "video"))
	{
		RTPSource *s = fSubsession.rtpSource();
		uint32_t ssrc = s->SSRC();

		std::map<uint32_t, ReceiveH264 *>::iterator it = ReceiveH264_Map.find(ssrc);
		if (it == ReceiveH264_Map.end())
		{
			printf("%u\n", ssrc);
			ReceiveH264 *h264_obj = new ReceiveH264();
			h264_obj->setSSRC(ssrc);
			ReceiveH264_Map.insert(make_pair(ssrc, h264_obj));
		}
		else
		{
			char temp[200];
			ReceiveH264 *h264_obj = it->second;
			

			if (h264_obj->firstFrame)
			{
				unsigned int num;
				SPropRecord *sps = parseSPropParameterSets(fSubsession.fmtp_spropparametersets(), num);

				h264_obj->setSpsPPs(sps[0].sPropBytes, sps[0].sPropLength, sps[1].sPropBytes, sps[1].sPropLength);
				//"rtmp://127.0.0.1/live/1003", CANVAS_WIDTH, CANVAS_HEIGHT,25,1
				char url[200];
				sprintf_s(url, "rtmp://127.0.0.1/live/%u", h264_obj->ssrc);
				int width = 0;
				int height = 0;
				int fps = 0;
				int audio = 0;

				h264_decode_sps(sps[0].sPropBytes, sps[0].sPropLength, width, height, fps);
				h264_obj->set_width_heigth_fps(width, height, fps);
				printf("====================================video===========================\n");
				printf("url:%s \t width:%d heigth:%d fps %d\n", url,width, height, fps);
				printf("====================================video===========================\n");
				h264_obj->rtmp_obj.InitParam(url, width, height,fps,audio);

				h264_obj->rtmp_obj.SetSpsPps(sps[0].sPropBytes, sps[0].sPropLength, sps[1].sPropBytes, sps[1].sPropLength);

				

				delete[] sps;
				h264_obj->firstFrame = false;

			}
			
			if (fReceiveBuffer != NULL && _Buffer != NULL)
			{
				char nalu = *fReceiveBuffer & 0x0F;
				if (nalu == 0x05 || nalu == 0x01)
				{
					char *pbuf = (char *)fReceiveBuffer - 4; //带上 00 00 00 01

					int size = frameSize + 4;
					h264_obj->revice_frame(fReceiveBuffer, frameSize);
					h264_obj->rtmp_obj.SendPacketVideoFrameRaw((uint8_t*)pbuf, size, h264_obj->ts);
					h264_obj->ts += h264_obj->_durtion_time;

				}
			}
				

			
		}


}
#endif

#if 0 //H264 文件保存 
	if (!strcmp(fSubsession.mediumName(), "video"))
	{
		RTPSource *s=fSubsession.rtpSource();
		uint32_t ssrc=s->SSRC();
		
		std::map<uint32_t, ReceiveH264 *>::iterator it=ReceiveH264_Map.find(ssrc);
		if (it == ReceiveH264_Map.end())
		{
			printf("%u\n", ssrc);
			ReceiveH264 *h264_obj=new ReceiveH264();
			h264_obj->setSSRC(ssrc);
			ReceiveH264_Map.insert(make_pair(ssrc, h264_obj));
		}
		else
		{
			char temp[200];
			ReceiveH264 *h264_obj = it->second;
			sprintf_s(temp, "./H264/%u.h264", h264_obj->ssrc);

			if (h264_obj->firstFrame)
			{
				unsigned int num;
				SPropRecord *sps = parseSPropParameterSets(fSubsession.fmtp_spropparametersets(), num);

				h264_obj->setSpsPPs(sps[0].sPropBytes, sps[0].sPropLength, sps[1].sPropBytes, sps[1].sPropLength);

				// For H.264 video stream, we use a special sink that insert start_codes:
				struct timeval tv = { 0,0 };
				unsigned char start_code[4] = { 0x00, 0x00, 0x00, 0x01 };

				FILE *fp = fopen(temp, "wb");
				if (fp)
				{
					fwrite(start_code, 4, 1, fp);
					printf("sps ..........%d\n", sps[0].sPropLength);
					fwrite(sps[0].sPropBytes, sps[0].sPropLength, 1, fp);
					fwrite(start_code, 4, 1, fp);
					printf("pps ..........%d\n", sps[1].sPropLength);
					fwrite(sps[1].sPropBytes, sps[1].sPropLength, 1, fp);
					fclose(fp);
					fp = NULL;
				}
				delete[] sps;
				h264_obj->firstFrame = false;

			}
			else
			{
				char nalu = *fReceiveBuffer & 0x0F;
				if (nalu == 0x05 || nalu == 0x01)
				{

					char *pbuf = (char *)fReceiveBuffer-4;
				
					int size = frameSize + 4;
					
					FILE *fp = fopen(temp, "ab");
					if (fp)
					{
						fwrite(pbuf, size, 1, fp);
						fclose(fp);
						fp = NULL;
					}
				}

			}
		}

	
	}
#endif


	continuePlaying();
}

Boolean DummySink::continuePlaying() {
	if (fSource == NULL) return False; // sanity check (should not happen)

	// Request the next frame of data from our input source.  "afterGettingFrame()" will get called later, when it arrives:
	fSource->getNextFrame(fReceiveBuffer, DUMMY_SINK_RECEIVE_BUFFER_SIZE,
		afterGettingFrame, this,
		onSourceClosure, this);
	return True;
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值