麒麟操作系统/Linux 摄像头采集录制

本文介绍了如何在Linux系统中利用V4L2接口进行摄像头采集和控制,通过调用/dev/videoxx设备文件进行读写操作。内容包括在Ubuntu 14上实现摄像头预览并推送播放,以及SDK提供的摄像头翻转和旋转功能,支持90、180、270度旋转。此外,还提到了Linux摄像头不能同时打开多次的问题以及虚拟机上USB摄像头的兼容性设置建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     Linux系统上采集摄像头,可以使用V4L2相关接口,Linux上的摄像头设备文件是/dev/videoxx, 采集和控制摄像头只要调用open("/dev/videoxx", flag) 打开文件,然后对文件进行读写等控制操作即可.

      最近在Linux推送SDK也增加了摄像头采集和预览功能,集成调用非常简单,几行C++代码就可以完成.

class CameraInfo
{
public:
	std::string name_;
	std::string id_;
	std::vector<NT_PB_VideoCaptureCapability> capabilities_;
};

void GetCameraInfo(NT_SmartPublisherSDKAPI* push_api, std::vector<CameraInfo>& cameras)
{
		NT_INT32 device_number = 0;
		if (NT_ERC_OK != push_api->GetVideoCaptureDeviceNumber(&device_number))
		{
			return;
		}

		if (device_number < 1)
		{
			return;
		}

		for (auto i = 0; i < device_number; ++i)
		{
			CameraInfo info;

			char name[256] = { 0 };
			char id[1024] = { 0 };

			if (NT_ERC_OK != push_api->GetVideoCaptureDeviceInfo(i,
				name, sizeof(name) / sizeof(char),
				id, sizeof(id) / sizeof(char)))
			{
				continue;
			}

			info.name_ = name;
			info.id_ = id;

			NT_INT32 capability_number = 0;
			if (NT_ERC_OK != push_api->GetVideoCaptureDeviceCapabilityNumber(
				id, &capability_number))
			{
				continue;
			}

			auto is_failed = false;

			//capability_number = 1;

			for (auto i = 0; i < capability_number; ++i)
			{
				NT_PB_VideoCaptureCapability capability = { 0, 0, 0 };

				if (NT_ERC_OK != push_api->GetVideoCaptureDeviceCapability(
					id, i, &capability))
				{
					is_failed = true;
					break;
				}

				info.capabilities_.push_back(capability);
			}

			if (!is_failed)
			{
				cameras.push_back(info);
			}
		}
	}

NT_HANDLE StartPush(NT_SmartPublisherSDKAPI* push_api, const std::string& rtmp_url, int dst_fps)
{
		std::vector<CameraInfo> cameras;
		GetCameraInfo(push_api, cameras);

		if (!cameras.empty())
		{
			fprintf(stdout, "cameras count:%d\n", (int)cameras.size());

			for (const auto& c : cameras)
			{
				fprintf(stdout, "camera name:%s, id:%s, cap_num:%d\n", c.name_.c_str(), c.id_.c_str(), (int)c.capabilities_.size());

				for (const auto& i : c.capabilities_)
				{
					fprintf(stdout, "cap w:%d, h:%d, fps:%d\n", i.width_, i.height_, i.max_frame_rate_);
				}
			}
		}

		NT_UINT32 auido_option = NT_PB_E_AUDIO_OPTION_NO_AUDIO;
		NT_UINT32 video_option = NT_PB_E_VIDEO_OPTION_SCREEN;

		if (!cameras.empty())
		{
			video_option = NT_PB_E_VIDEO_OPTION_CAMERA;
		}
	
		NT_HANDLE push_handle = nullptr;

		if (NT_ERC_OK != push_api->Open(&push_handle, video_option, auido_option, 0, NULL))
		{
			return nullptr;
		}
		
		if (video_option == NT_PB_E_VIDEO_OPTION_CAMERA)
		{
			if (!cameras.empty())
			{
			    // 设置摄像头id,和要采集的摄像头分辨率
				push_api->SetVideoCaptureDeviceBaseParameter(push_handle, cameras.front().id_.c_str(),
					640, 480);

				//push_api->FlipVerticalCamera(push_handle, 1); // 摄像头垂直翻转
				//push_api->FlipHorizontalCamera(push_handle, 1); // 摄像头水平翻转
				//push_api->RotateCamera(push_handle, 0); // 摄像头旋转
			}
		}

		push_api->SetFrameRate(push_handle, dst_fps); // 帧率设置
		push_api->SetVideoBitRate(push_handle, 2000);  // 平均码率2000kbps
		push_api->SetVideoQualityV2(push_handle, 26); 
		push_api->SetVideoMaxBitRate(push_handle, 4000); // 最大码率4000kbps
		push_api->SetVideoKeyFrameInterval(push_handle, dst_fps*2); // 关键帧间隔
		push_api->SetVideoEncoderProfile(push_handle, 3); // H264 high
		push_api->SetVideoEncoderSpeed(push_handle, 3); // 编码速度设置到3


		if ( NT_ERC_OK != push_api->SetURL(push_handle, rtmp_url.c_str(), NULL) )
		{
			push_api->Close(push_handle);
			push_handle = nullptr;
			return nullptr;
		}

		if ( NT_ERC_OK != push_api->StartPublisher(push_handle, NULL) )
		{
			push_api->Close(push_handle);
			push_handle = nullptr;
			return nullptr;
		}

		return push_handle;
}

// 下面是启动预览的代码
{
    push_api.SetPreviewXWindow(push_handle, NULL, sub_wid); // 传入用来显示图像的窗口
	push_api.StartPreview(push_handle, 0, nullptr);
}

      下面是在Ubuntu 14上摄像头预览, 然后推送播放的效果, 左边窗口是播放器,右边是预览窗口.

      除了基本的采集功能,SDK还支持摄像头水平/垂直翻转, 支持90, 180, 270度旋转,也支持层叠加模式,可以和屏幕叠加组合. 下面是和屏幕叠加组合的效果:

    Linux和Windows一样,摄像头也不能同时打开多次,另外虚拟机上跑的Linux系统,如果USB摄像头不能正常吐图像,可以试下改变USB兼容选项,可能就好了。对于更多问题可以联系qq: 1130758427, github

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值