live555开发NVR/IPC RTSPServer时对视频录像回放控制的支持方法

我们在研发live555用于集成在NVR时,实时流可通过回调URL让上层应用去拉流再转发就可以了,是否可以让其也支持回放流呢? 答案是肯定的。

我们发现,在live555官方代码中就已支持回放控制,只是控制部分需要改成我们自己实现的部分,将控制消息通过回调函数回调出来。

解决方案

参考代码如下:


#include "LiveServerMediaSubsession.h"

LiveServerMediaSubsession::LiveServerMediaSubsession(UsageEnvironment& env, LiveSource *LiveSource, char *streamName, char *mediaTypeName, unsigned estimatedBitrate, RTSP_MEDIA_INFO_T *mediainfo, Boolean reuseFirstSource, unsigned int mediaType, portNumBits defaultPort)
  : OnDemandServerMediaSubsession(env, reuseFirstSource /*reuse the first source*/, streamName, mediaTypeName, defaultPort, false),
    fLiveSource(LiveSource), mMediaInfo(mediainfo), mMediaType(mediaType)
{
  //fEstimatedKbps = (estimatedBitrate + 500)/1000;

	fEstimatedKbps = estimatedBitrate;
}

LiveServerMediaSubsession::~LiveServerMediaSubsession() {
}

void LiveServerMediaSubsession::getAbsoluteTimeRange(char*& absStartTime, char*& absEndTime)// const
{
	absStartTime = absEndTime = NULL;
	//20100929T095038.00Z-20100929T102038.00Z

	RTSPSvrCallBack	pCallback = (RTSPSvrCallBack )fLiveSource->mCallbackPtr;
	if (NULL == pCallback)		return;
	
	RTSP_PLAY_CONTROL_INFO_T	durationCtlInfo;
	memset(&durationCtlInfo, 0x00, sizeof(RTSP_PLAY_CONTROL_INFO_T));
	durationCtlInfo.ctrlCommand = RTSP_PLAY_CTRL_CMD_GET_DURATION;
	durationCtlInfo.mediaType = mMediaType;

	if (fLiveSource->GetFlag() != LIVE_FLAG)	return;

	pCallback(RTSP_CHANNEL_PLAY_CONTROL, fLiveSource->channelName, &fLiveSource->mChannelHandle, fLiveSource->mMediaInfoPtr, &durationCtlInfo, fLiveSource->mUserPtr, (void *)fLiveSource->mChannelUserPtr);

	if ( (int)strlen((char *)durationCtlInfo.startTime) > 0 )
	{
		absStartTime = (char *)durationCtlInfo.startTime;
	}

	if ( (int)strlen((char *)durationCtlInfo.endTime) > 0 )
	{
		absEndTime = (char *)durationCtlInfo.endTime;
	}
}


//pause play
void	LiveServerMediaSubsession::pauseStreamSource()
{
	RTSPSvrCallBack	pCallback = (RTSPSvrCallBack )fLiveSource->mCallbackPtr;
	if (NULL == pCallback)			return;

	RTSP_PLAY_CONTROL_INFO_T	playCtrlInfo;
	memset(&playCtrlInfo, 0x00, sizeof(RTSP_PLAY_CONTROL_INFO_T));
	playCtrlInfo.ctrlCommand = RTSP_PLAY_CTRL_CMD_PAUSE;
	playCtrlInfo.mediaType = mMediaType;

	pCallback(RTSP_CHANNEL_PLAY_CONTROL, fLiveSource->channelName, &fLiveSource->mChannelHandle, fLiveSource->mMediaInfoPtr, &playCtrlInfo, fLiveSource->mUserPtr, (void *)fLiveSource->mChannelUserPtr);
}

//Resume play
void  LiveServerMediaSubsession::resumeStreamSource()
{
	RTSPSvrCallBack	pCallback = (RTSPSvrCallBack )fLiveSource->mCallbackPtr;
	if (NULL == pCallback)			return;

	RTSP_PLAY_CONTROL_INFO_T	playCtrlInfo;
	memset(&playCtrlInfo, 0x00, sizeof(RTSP_PLAY_CONTROL_INFO_T));
	playCtrlInfo.ctrlCommand = RTSP_PLAY_CTRL_CMD_RESUME;
	playCtrlInfo.mediaType = mMediaType;

	pCallback(RTSP_CHANNEL_PLAY_CONTROL, fLiveSource->channelName, &fLiveSource->mChannelHandle, fLiveSource->mMediaInfoPtr, &playCtrlInfo, fLiveSource->mUserPtr, (void *)fLiveSource->mChannelUserPtr);
}


void LiveServerMediaSubsession::testScaleFactor(float& scale)
{
	if ( (scale >= 1.0000000f && scale <= 32.00000000f) ||
		 (scale >= 0.0312500f && scale<=0.500000000f)  ||
		 (scale >= -32.00000000f && scale <= 0.00000000f) )
	{
		return;
	}
	else
	{
		scale = 1.0f;
	}
}

void LiveServerMediaSubsession::setStreamSourceScale(FramedSource* inputSource, float scale)
{
	RTSPSvrCallBack	pCallback = (RTSPSvrCallBack )fLiveSource->mCallbackPtr;
	if (NULL == pCallback)			return;

	RTSP_PLAY_CONTROL_INFO_T	playCtrlInfo;
	memset(&playCtrlInfo, 0x00, sizeof(RTSP_PLAY_CONTROL_INFO_T));
	playCtrlInfo.ctrlCommand = RTSP_PLAY_CTRL_CMD_SCALE;
	playCtrlInfo.mediaType = mMediaType;
	playCtrlInfo.scale = scale;

	pCallback(RTSP_CHANNEL_PLAY_CONTROL, fLiveSource->channelName, &fLiveSource->mChannelHandle, fLiveSource->mMediaInfoPtr, &playCtrlInfo, fLiveSource->mUserPtr, (void *)fLiveSource->mChannelUserPtr);
}

void LiveServerMediaSubsession::seekStreamSource(FramedSource* inputSource, char*& absStart, char*& absEnd)
{
	RTSPSvrCallBack	pCallback = (RTSPSvrCallBack )fLiveSource->mCallbackPtr;
	if (NULL == pCallback)			return;

	RTSP_PLAY_CONTROL_INFO_T	playCtrlInfo;
	memset(&playCtrlInfo, 0x00, sizeof(RTSP_PLAY_CONTROL_INFO_T));
	playCtrlInfo.ctrlCommand = RTSP_PLAY_CTRL_CMD_SEEK_STREAM;
	playCtrlInfo.mediaType = mMediaType;
	if (NULL!=absStart && ((int)strlen(absStart)>0))		strcpy((char*)playCtrlInfo.startTime, absStart);
	if (NULL!=absEnd && ((int)strlen(absEnd)>0))		strcpy((char*)playCtrlInfo.endTime, absStart);

	pCallback(RTSP_CHANNEL_PLAY_CONTROL, fLiveSource->channelName, &fLiveSource->mChannelHandle, fLiveSource->mMediaInfoPtr, &playCtrlInfo, fLiveSource->mUserPtr, (void *)fLiveSource->mChannelUserPtr);
}


#if 0
void LiveServerMediaSubsession::seekStreamSource(FramedSource* inputSource, double& seekNPT, double streamDuration, u_int64_t& numBytes)
{
	printf("LiveServerMediaSubsession::seekStreamSource  seekNPT[%s]  absEnd[%.2f]\n", seekNPT, streamDuration);
}
void LiveServerMediaSubsession::seekStreamSource(FramedSource* inputSource, char*& absStart, char*& absEnd)
{
	printf("LiveServerMediaSubsession::seekStreamSource  absStart[%s]  absEnd[%s]\n", absStart, absEnd);
}

void LiveServerMediaSubsession::setStreamSourceDuration(FramedSource* inputSource, double streamDuration, u_int64_t& numBytes)
{
	printf("LiveServerMediaSubsession::setStreamSourceDuration  streamDuration: %.2f\n", streamDuration);
}

void LiveServerMediaSubsession::closeStreamSource(FramedSource* inputSource)
{

	printf("LiveServerMediaSubsession::closeStreamSource\n");
}
#endif


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值