当前位置: 首页 > 知识库问答 >
问题:

将openCV C视频流化到浏览器

曹钊
2023-03-14

我正试图用C语言中的openCV捕捉我的内置摄像头,做一些处理。到目前为止,这项工作仍在进行中。

现在我想将网络摄像头传输到浏览器。我该怎么做?

  • 我应该创建WebSocket吗?还是使用UPD Socket?
    • Poco::网::WebSocket

    非常感谢。

共有2个答案

巫墨一
2023-03-14

所以我自己找到了解决办法。概念是这样的:

我的服务器是使用POCO库构建的WebSocket服务器

服务器:
在主线程中初始化摄像机(摄像机必须在主线程中初始化)。建立WebSocket连接后,服务器从cv::VideoCapture捕获一帧,将帧转换为JPEG,并将图像编码为Base64字符串,最后将该字符串发送回客户端。

浏览器:
在浏览器中,接收的Base64字符串可以通过img标记解释为图像。

<img id="image" src="" width="1280" height="720"/>  
ws.onmessage = function(evt)
{
  $("#image").attr('src',  'data:image/jpg;base64,'+ evt.data);
};

因此,如果服务器现在在一秒钟内发送30帧,浏览器中就会出现流畅的livestream

慕容昊焜
2023-03-14

我可能有点晚了,但由于我在StackOverflow中没有找到C和mjpeg的完全更新的解决方案,我考虑写一个新的答案。

现在有一些很好且简单的库用于C语言中的任务(C mjpg流到html)

https://github.com/nadjieb/cpp-mjpeg-streamer

https://github.com/jacksonliam/mjpg-streamer

https://github.com/codewithpassion/mjpg-streamer/tree/master/mjpg-streamer

我发现第一个很简单。您需要CMake,并在系统中安装make。

git clone https://github.com/nadjieb/cpp-mjpeg-streamer.git;
cd cpp-mjpeg-streamer;
mkdir build && cd build;
cmake ../;
make;
sudo make install;
  • 确保安装了正确版本的OpenCV

现在,写下拖缆:

mjpeg_服务器。抄送

#include <opencv2/opencv.hpp>

#include <nadjieb/mjpeg_streamer.hpp>

// for convenience
using MJPEGStreamer = nadjieb::MJPEGStreamer;

int main()
{
    cv::VideoCapture cap;
    cap.open("demo.mp4"); 
    if (!cap.isOpened())
    {
        std::cerr << "VideoCapture not opened\n";
        exit(EXIT_FAILURE);
    }

    std::vector<int> params = {cv::IMWRITE_JPEG_QUALITY, 90};

    MJPEGStreamer streamer;

    // By default 1 worker is used for streaming
    // if you want to use 4 workers:
    //      streamer.start(8080, 4);
    streamer.start(8000);

    // Visit /shutdown or another defined target to stop the loop and graceful shutdown
    while (streamer.isAlive())
    {
        cv::Mat frame;
        cap >> frame;
        if (frame.empty())
        {
            std::cerr << "frame not grabbed\n";
            //continue;
            exit(EXIT_FAILURE);
        }

        // http://localhost:8080/bgr
        std::vector<uchar> buff_bgr;
        cv::imencode(".jpg", frame, buff_bgr, params);
        streamer.publish("/bgr", std::string(buff_bgr.begin(), buff_bgr.end()));

        cv::Mat hsv;
        cv::cvtColor(frame, hsv, cv::COLOR_BGR2HSV);

        // http://localhost:8080/hsv
        std::vector<uchar> buff_hsv;
        cv::imencode(".jpg", hsv, buff_hsv, params);
        streamer.publish("/hsv", std::string(buff_hsv.begin(), buff_hsv.end()));

        // std::cout<< "published" << std::endl;
    }

    streamer.stop();
}

编写CMakeLists.txt

cmake_minimum_required(VERSION 3.1)

project(mjpeg_streamer CXX)

find_package(OpenCV 4.2 REQUIRED)
find_package(nadjieb_mjpeg_streamer REQUIRED)

include_directories(${OpenCV_INCLUDE_DIRS})

add_executable(stream_test
  "mjpeg_server.cc")
target_compile_features(stream_test PRIVATE cxx_std_11)
target_link_libraries(stream_test PRIVATE nadjieb_mjpeg_streamer::nadjieb_mjpeg_streamer
                     ${OpenCV_LIBS})


| --- mjpeg_server.cc
| --- CMakeLists.txt
| --- ...
| --- build  
      | --- demo.mp4
      | --- ...

现在,我们可以制作拖缆了。

mkdir build && cd build;
cmake ../;
make;
./stream_test

现在,如果您转到”http://ip_address:port/bgr“或,”http://ip_address:port/hsv“您应该能够看到流。在我的例子中,ip=192.168.1.7/localhost,port=8000。

如果你想用另一台服务器获取流,

index.html代码

<html>
  <body>
    <img src="http://localhost:8000/bgr">
    <img src="http://localhost:8000/hsv">
  </body>
</html>

发球。py

import http.server
import socketserver

class MyHttpRequestHandler(http.server.SimpleHTTPRequestHandler):
    def do_GET(self):
        if self.path == '/':
            self.path = 'index.html'
        return http.server.SimpleHTTPRequestHandler.do_GET(self)

# Create an object of the above class
handler_object = MyHttpRequestHandler

PORT = 8080
my_server = socketserver.TCPServer(("", PORT), handler_object)

# Star the server
my_server.serve_forever()

python3发球。py

最后,尽管它非常简单,但并不安全。

 类似资料:
  • 我正在开发一个网络应用程序,从网络摄像头捕捉视频,并将流保存到Amazon Kinesis。我提出的第一个方法是getUserMedia/mediaRecorder/XMLHttpRequest,它将分块的MKV发布到我的unix服务器(而不是AWS),在那里简单的PHP后端代理通过PutMedia传输到Kinesis。 这应该工作,但所有媒体流从用户将通过我的服务器,这可能成为一个瓶颈。据我所知

  • 我想实现如下内容: 使用RTSP从IP-Camera读取视频流(已完成) 使用OpenCV处理图像(已完成) 将图像发送到浏览器以显示(这是问题所在) 第三部分利用RTSP协议将图像作为视频流发送。 注意:服务器端使用的语言是Java(OpenCV也在Java中),服务器是Tomcat。 如果有人认为用RTSP来实现不是更好,那么最好的方法是什么来实现这个功能,因为RTSP对于视频流来说是特殊的,

  • 我有一个基于AWS的web应用程序。客户端使用Angular 1.5.3用JavaScript编写 null 我已经找到了这篇教程:http://docs.aws.amazon.com/amazoncloudfront/latest/developerguide/tutorialstreamingjwplayer.html,但不幸的是,这篇教程没有多大用处,因为它描述了如何从公共bucket进行流

  • 问题内容: 我想将录制的音频从浏览器实时流传输到服务器并播放。该服务器最终将成为播放这些音频流的嵌入式设备。 到目前为止,我已经成功地录制了音频并将其编码为WAVE文件,并使用网络音频API并按照本教程在浏览器上播放。 现在,我有了.WAV编码的Blob流。我试图找到通过Web套接字连接将其流式传输到Node.js后端并使用npm模块播放它们的方法。但是我没有运气。 有人知道我应该遵循的任何资源或

  • 音频和视频都能在第一次正确播放,在音频播放完成时视频循环(因为它更短)。唯一的问题是音频循环不工作,一旦音频第一次完成,流就停止了。 以下是日志: ffmpeg version 4.3.1版权所有(c)2000-2020 ffmpeg开发人员 使用Apple clang version 12.0.0(clang-1200.0.32.27) 配置构建:--prefix=/usr/local/cell

  • 比如基于cef搞的浏览器,如何拿到最终播放的文件流? 这样不管网站怎么加密,都能拿到视频文件。