网易直播--摄像头采集回调总结

版权声明:www.gudianxiaoshuo.com (古典小说网) 今日头条号: 古典古韵古典小说、讨厌编程 https://blog.csdn.net/shuilan0066/article/details/87855789

参考资料:

https://dev.yunxin.163.com/docs/product/%E7%9B%B4%E6%92%AD/%E4%BA%A7%E5%93%81%E4%BB%8B%E7%BB%8D/%E7%AE%80%E4%BB%8B

一 视频回调

  1 合成视频回调

  Nlss_SetVideoSamplerCB,会通过设置的回调函数返回推流之前的rgb32的buffer给上层用于显示;

 1)设置视频回调函数

typedef void(*PFN_NLSS_MERGED_VIDEO_SAMPLER_CB)(_HNLSSERVICE hNLSService, ST_NLSS_VIDEO_SAMPLER *pstSampler);


	void  LsSession::SetVideoSamplerCB(){
		NLS_SDK_GET_FUNC(Nlss_SetVideoSamplerCB)(LsClient, VideoCallback);
	}
	void LsSession::SetVideoSamplerCB(PFN_NLSS_MERGED_VIDEO_SAMPLER_CB cb)
	{
		NLS_SDK_GET_FUNC(Nlss_SetVideoSamplerCB)(LsClient, cb);
	}


//初始化时,添加视频回调
bool NLSLiveForm::StartPrew(){

	ST_NLSS_VIDEOIN_PARAM stChildVInParam;
	std::string accid;

	//Nlss_InitParam初始化直播对象,直播参数ST_NLSS_PARAM生效
	if(!NewInitMediaCapture())//if (!InitMediaCapture())              
	{
		m_errorLog.WriteErrorFuc("InitMediaCapture()");
		m_errMsg = L"初始化视频采集设备出错";
		ShowMsgBox(this->GetHWND(), m_errMsg, MsgboxCallback(), L"校内外直播间 ", L"确定", L"取消");
		return false;
	}

	//Nlss_Start创建推流实例,开始处理视频(还未开始推流)
	if (!m_LiveStreaming.OnStartVideo())   
	{
		m_errorLog.WriteErrorFuc("!m_LiveStreaming.OnStartVideo() - 打开视频采集出错");
		m_ChildVideoDisplayList.clear();
		m_ChildVideoList.clear();
		m_ChildVideoInfoList.clear();

		m_errMsg = L"打开视频采集出错";
		ShowMsgBox(this->GetHWND(), m_errMsg, MsgboxCallback(), L"校内外直播间 ", L"确定", L"取消");
		return false;
	}


	

	m_LiveStreaming.SetStatusCB(&OnLiveStreamStatusNty); //直播过程状态改变通知函数 比如,网络不好

	if (g_bUseSharedCamera)
	{
		m_LiveStreaming.SetVideoSamplerCB(VideoCallback_G);          
	}else
		m_LiveStreaming.SetVideoSamplerCB();

2)合成后画面的视频回调

扫描二维码关注公众号,回复: 5281331 查看本文章

//合成画面后的视频回调
void VideoCallback_G(_HNLSSERVICE hNLSService, ST_NLSS_VIDEO_SAMPLER *sampler)
{
	if (sampler)
	{
		int ret = sampler->iDataSize;
		if (ret > 0)
		{

			int nLen = sampler->iWidth*sampler->iHeight;
			nim_nls::LssManange::IsBlackVideo = IsBlack((DWORD*)sampler->puaData, nLen);

			timeb time_now;
			ftime(&time_now); // 秒数
			__int64 cur_timestamp = time_now.time * 1000 + time_now.millitm; // 毫秒
			nim_nls::LssManange::GetVideoFrameMng()->AddVideoFrame(true, cur_timestamp, (const char*)sampler->puaData, sampler->iDataSize, \
				sampler->iWidth, sampler->iHeight, "", nim_comp::VideoFrameMng::Ft_ARGB);

			//capture_video_pic_.ResetData(cur_timestamp, src_buffer, size, width, height/*, subtype*/);
			char* pData=m_memMng.getData();

			INT32 nFps = g_pLiveForm->m_videoFps;
			INT32 nWidth = sampler->iWidth;
			INT32 nHeight = sampler->iHeight;

			INT32 Info[] = { nFps, nWidth, nHeight };
			int len = sizeof(Info) / sizeof(Info[0]);

			if (pData)
			{
				WaitForSingleObject(m_memMng.m_hReadEvent, INFINITE);
				ResetEvent(m_memMng.m_hWriteEvent);

				memcpy((INT32*)pData, Info, sizeof(INT32)*len);

				memcpy(pData + 12, nim_nls::LssManange::GetVideoFrameMng()->capture_video_pic_.pdata_, nim_nls::LssManange::GetVideoFrameMng()->capture_video_pic_.size_);


				SetEvent(m_memMng.m_hWriteEvent);
			}

		}
	}
}

  2 单个独立子视频回调

 Nlss_ChildVideoSetSoloPreviewCB设置单独预览的视频流buffer回调函数,可用于预览进行显示  

 Nlss_ChildVideoSwitchSoloPreview开|关子视频单独预览

void    Nlss_ChildVideoSetSoloPreviewCB(_HNLSSCHILDSERVICE hNLSSChild, PFN_NLSS_VIDEOSAMPLER_CB pFunVideoSamplerCB);
void    Nlss_ChildVideoSwitchSoloPreview(_HNLSSCHILDSERVICE hNLSSChild, bool bOn);

注意:  遇到奇怪的事情,就是单视频回调,必须在单视频采集后设置才有效,否则,不会返回回调信息。

就是说必须先调用  OnChildVideoStartCapture(accid),在采集这个视频后,

再调用OnChildVideoSetSoloPreviewCB(accid, SoloVideoCallback_G); 才有效。

如果先调用OnChildVideoSetSoloPreviewCB, 后调用OnChildVideoStartCapture,这样即使调用成功了startCapture,也不会有视频回调

   1)设置回调

	void LsSession::OnChildVideoSetSoloPreviewCB(const std::string& accid, PFN_NLSS_CHILD_VIDEO_SAMPLER_CB pFunVideoSamplerCB)
	{
		std::map<std::string, _HNLSSCHILDSERVICE>::const_iterator iter = nlss_child_services_.find(accid);
		if (iter != nlss_child_services_.end())
			NLS_SDK_GET_FUNC(Nlss_ChildVideoSetSoloPreviewCB)(iter->second, pFunVideoSamplerCB);
	}

	void  LsSession::OnChildVideoSwitchSoloPreview(const std::string& accid, bool bOn)
	{
		std::map<std::string, _HNLSSCHILDSERVICE>::const_iterator iter = nlss_child_services_.find(accid);
		if (iter != nlss_child_services_.end())
			NLS_SDK_GET_FUNC(Nlss_ChildVideoSwitchSoloPreview)(iter->second, bOn);
	}
void NLSLiveForm::SetAllCamerasSoloVideoCB(){

	std::string path;
	std::string accid;
	for (int i = 0; i < m_iVideoDeviceNum; i++)
	{
		path = m_pVideoDevices[i].paPath;
		accid = GetAccidFromPath(path);

		m_LiveStreaming.OnChildVideoSetSoloPreviewCB(accid, SoloVideoCallback_G);
		SwitchSoloPreview(accid, TRUE);
	}
}

  2) 回调函数

void SoloVideoCallback_G(_HNLSSERVICE hNLSService, _HNLSSCHILDSERVICE hNLSSChild, ST_NLSS_VIDEO_SAMPLER *sampler)
{


	_HNLSSCHILDSERVICE handle = g_pLiveStreaming->GetChildServiceByAccid(g_pLiveForm->GetCurCameraAccid());

	if (handle!=hNLSSChild)
	{
		return;
	}

	if (sampler)
	{
		int ret = sampler->iDataSize;

		printf("%d\n", sampler->iDataSize);
  		if (ret > 0)
		{

			int nLen = sampler->iWidth*sampler->iHeight;
			nim_nls::LssManange::IsBlackVideo = IsBlack((DWORD*)sampler->puaData, nLen);

			timeb time_now;
			ftime(&time_now); // 秒数
			__int64 cur_timestamp = time_now.time * 1000 + time_now.millitm; // 毫秒
			nim_nls::LssManange::GetSoloVideoFrameMng()->AddVideoFrame(true, cur_timestamp, (const char*)sampler->puaData, sampler->iDataSize, \
						sampler->iWidth, sampler->iHeight, "", nim_comp::VideoFrameMng::Ft_ARGB);

		}

	}
}

猜你喜欢

转载自blog.csdn.net/shuilan0066/article/details/87855789