利用EasyRTSTClient推海康视频流到EasyDarwin

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/tianyi1991/article/details/50483659

一切都是为了好玩而已


因为前面花了点时间研究了一下EasyDarwin的相关数据结构和流传输的方式,所以,后面做起事情来就方便多了,但也还是有很多不清楚的地方,不过,这并不影响我的使用。


准备工具:

(1)EasyDarwin服务器

(2)EasyPusher库

(3)EasyRTSPClient库

(4)海康摄像头一个

(5)VS2010(或者别的版本,但我没试过)

(6)windows 7系统(其它版本我没试过)


第一步:测试一下海康摄像头,做法如下:

海康摄像头的访问url格式:rtsp://[username]:[password]@[ip]:[port]/[codec]/[channel]/[subtype]/av_stream
username: 用户名。例如admin。
password: 密码。例如12345。
ip: 为设备IP。例如 192.0.0.64。
port: 端口号默认为554,若为默认可不填写。
codec:有h264、MPEG-4、mpeg4这几种。
channel: 通道号,起始为1。例如通道1,则为ch1。
subtype: 码流类型,主码流为main,辅码流为sub。

如:rtsp://admin:12345@x.x.x.x:554/h264/ch1/main/av_stream

利用VLC访问,测试通过。


第二步:搭建流媒体服务器EasyDarwin

这个可以参照官网http://www.easydarwin.org/unit/EasyDarwin.html

可以用release版本的,但我当时用这个版本的没搭起来(好像是),然后我就直接拿源码在VS2010上编译的。遇到的问题:

(1)因为Lib的库都是release下生成的,所以,VS工程也要设为release模式,否则一堆Link错误;

主要就是这个问题吧。

搭好以后,可以测试一下。要注意的是,按照官网的测试方式,是用一个mp4点播测试的,但我觉得对于新手来说(像我,没接触过编码,流媒体的人),有一个地方要注意的,就是这个Mp4文件是经过hint处理的!我当时也纠结这是什么意思。这个是流化处理,加入了一些东西。那么如何做流化?

我也是找了好久,最后还是要靠强大的ffmpeg来帮忙(windows下):

ffmpeg.exe -i test.mp4 -movflags rtphint out.mp4

经过上面转换后,这个out.mp4就可以被流媒体服务器转发了。具体就不说了,实验去吧。


第三步:利用EasyRTSPClient的demo,加入Pusher模块

这里,我只说关键部分,关于如果初始化pusher模块,去关注EasyPusher就行。


其实很简单,只要是EasyRTSPClient demo中一个回调中调用pusher的推流函数就可以了,关键就是如何组合一个符合推流格式的结构体。

关键的一个结构体:

typedef struct __EASY_AV_Frame
{
    Easy_U32    u32AVFrameFlag;		/* 帧标志  视频 or 音频 */
    Easy_U32    u32AVFrameLen;		/* 帧的长度 */
    Easy_U32    u32VFrameType;		/* 视频的类型,I帧或P帧 */
    Easy_U8     *pBuffer;			/* 数据 */
	Easy_U32	u32TimestampSec;	/* 时间戳(秒)*/
	Easy_U32	u32TimestampUsec;	/* 时间戳(微秒) */
}EASY_AV_Frame;


这个结构体会被/* 推流 frame:具体推送的流媒体帧 */
Easy_API Easy_U32 Easy_APICALL EasyPusher_PushFrame(Easy_Pusher_Handle handle, EASY_AV_Frame* frame );

调用(关注easypusher的demo就可以知道)。

而同时:

/* RTSPClient数据回调 */
int Easy_APICALL __RTSPClientCallBack( int _chid, int *_chPtr, int _frameType, char *_pBuf, RTSP_FRAME_INFO* _frameInfo);


这个回调会自动把RTSP流的信息给我们传进来,也就是说,不用去管它怎么取得信息的,只管知道:

(1)_frameType  指示是视频帧还是音频帧

(2)_pBuf 帧数据

(3)_frameInfo 帧数据信息头

         这个结构体如下:

         

/* 帧信息 */
typedef struct 
{
	unsigned int	codec;			/* 音视频格式 */

	unsigned int	type;			/* 视频帧类型 */
	unsigned char	fps;			/* 视频帧率 */
	unsigned short	width;			/* 视频宽 */
	unsigned short  height;			/* 视频高 */

	unsigned int	reserved1;		/* 保留参数1 */
	unsigned int	reserved2;		/* 保留参数2 */

	unsigned int	sample_rate;	/* 音频采样率 */
	unsigned int	channels;		/* 音频声道数 */

	unsigned int	length;			/* 音视频帧大小 */
	unsigned int    timestamp_usec;	/* 时间戳,微妙 */
	unsigned int	timestamp_sec;	/* 时间戳 秒 */
	
	float			bitrate;		/* 比特率 */
	float			losspacket;		/* 丢包率 */
}RTSP_FRAME_INFO;


上面的信息已经足够做一切事情了。。。。。。不多说了,直接贴上一段加在这个回调中的关键代码吧:

//pusher
			//推送要求填写的信息:帧长度,数据(指纯视频数据?),视频帧类型(I,P)
			EASY_AV_Frame  avFrame;
			memset(&avFrame, 0x00, sizeof(EASY_AV_Frame));
			avFrame.u32AVFrameLen = _frameInfo->length;
			avFrame.pBuffer = (unsigned char*)_pBuf;
			avFrame.u32VFrameType = _frameInfo->type;
			avFrame.u32AVFrameFlag = EASY_SDK_VIDEO_FRAME_FLAG;//视频还是音频标志
			avFrame.u32TimestampSec =  _frameInfo->timestamp_sec;
			avFrame.u32TimestampUsec = _frameInfo->timestamp_usec;
			EasyPusher_PushFrame(fPusherHandle, &avFrame);


好了,到此结束

展开阅读全文

没有更多推荐了,返回首页