前言
本篇文档是在上一篇的基础上实现的,上一篇文档如下
创建qml自定义视频源(Qt6.3.1+取景器帧)_꧁白杨树下꧂的博客-优快云博客_qml 视频
笔者尝试使用Qt自身的类获取视频帧,在win10下测试没问题,但鸿蒙平板上测试,总出问题,估计其他android设备应该类似。所以笔者尝试使用openCV的库来实现
一、拉取windows下的视频流
关键代码如下
cv::VideoCapture cap;
cap.open(0);
//cap.open("rtsp://admin:@192.168.18.102:554/stream1");
// check if we succeeded
if (!cap.isOpened()) {
std::cerr << "ERROR! Unable to open camera\n";
return ;
}
while(1)
{
cv::Mat frame;
cap.read(frame);
if (frame.empty()) {
std::cerr << "ERROR! blank frame grabbed\n";
return;
}
cvtColor(frame, frame, cv::COLOR_RGB2RGBA);
const int size = frame.rows * frame.cols * 4;
QVideoFrameFormat frameFormat(QSize(frame.cols, frame.rows),
QVideoFrameFormat::Format_RGBA8888);
QVideoFrame f(frameFormat);
if (f.map(QVideoFrame::WriteOnly)) {
memcpy(f.bits(0), frame.data, size);
f.setStartTime(0);
f.unmap();
emit newFrame(f);
}
}
直接使用openCV获取视频帧,然后转换成RGBA的颜色空间,再包装成QVideoFrame。包装后的视频帧,就可以直接送到视频源中
但要注意,不同的摄像头,通过openCV获取到的视频帧,颜色空间可能不同。笔者使用的摄像头返回的是RGB,读者测试时一定要注意查看
二、拉取android下的视频流
android下获取视频帧,需要重新编译下openCV,笔者测试过openCV4.5.5和openCV4.6.0
Qt+openCV学习笔记(十四)Qt6.3.0+openCV4.5.5+android_arm64-v8a测试拉取本地摄像头的流_꧁白杨树下꧂的博客-优快云博客
Qt+openCV学习笔记(十五)openCV4.6.0+android-ndk-r22-windows-x86_64编译动、静态库_꧁白杨树下꧂的博客-优快云博客
关键代码如下
cv::VideoCapture cap;
cap.open(0);
// check if we succeeded
if (!cap.isOpened()) {
std::cerr << "ERROR! Unable to open camera\n";
return ;
}
while(1)
{
cv::Mat frame;
cap.read(frame);
if (frame.empty()) {
std::cerr << "ERROR! blank frame grabbed\n";
return;
}
cvtColor(frame, frame, cv::COLOR_YUV2RGBA_NV12);
const int size = frame.rows * frame.cols * 4;
QVideoFrameFormat frameFormat(QSize(frame.cols, frame.rows),
QVideoFrameFormat::Format_RGBA8888);
QVideoFrame f(frameFormat);
if (f.map(QVideoFrame::WriteOnly)) {
memcpy(f.bits(0), frame.data, size);
f.setStartTime(0);
f.unmap();
emit newFrame(f);
}
}
代码基本与windows的相同,但注意需要摄像头相关的权限
笔者使用鸿蒙平板测试的,获取的视频帧是yuv格式的。限于条件,笔者无其他测试设备,请该读者自行测试
遇到的问题:
1.笔者使用openCV测试,鸿蒙平板可以正常运行,但win10经常出现无法正常打开,需要更换下摄像头的USB插口
2.android存在旋转的问题
3.android下,无法打开USB外插摄像头,但Qt可以识别到
笔者测试使用的源码
后记
笔者测试时发现,鸿蒙平板默认是自动对焦的,获取的视频帧是默认是最低分辨率的