There are a lot of projects on the web to implement a simple Network Cam with Raspberry. The most common implementation is with motion sw, but the performance are very very poor. Using Open CV and C++ is possible to implement an high performance and optimized sw.
My preferred IDE for C/C++ on Raspberry is Code::Blocks. It is a free, open-source integrated development environment (IDE) designed for C, C++, and Fortran. It features a customizable interface, powerful debugging tools, and support for multiple compilers, making it ideal for both beginners and experienced developers. Its plugin-based architecture allows for easy extension and adaptability across platforms.
Before to start the software preparation there are 2 last steps: Connect USB Camera and Install the missing packets.
sudo apt update
sudo apt install codeblocks
sudo apt install -y ffmpeg
sudo apt install libopencv-dev
Create Code::Block projectGo in menu File->New--> Project and select Console Application
Click Go
Select C++ and click Next
Insert the Project title and folder and click Next
Select GNU GCC as compiler and click Finish
Build option project Code::BlockGo in menu Project--> Build Options and add the following libraries on linker settings
Add /usr/include/opencv4 in Search directories
Now we are ready to edit the main.cpp file
RTP Software descriptionIn order to simplify the parameters configuration there is a config file called stream_config.txt. Create a file stream_config.txt and add the followings lines
width=320
height=240
fps=15
ip=192.168.1.224
port=5004
codec=libx264
bitrate=800k
Where the first 3 are used to configure the fideo stream, ip and port are used to define the receiver address, the last 2 are used to define the codec
On main.cpp and the followings include
#include <opencv2/opencv.hpp>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <map>
The main function is very simple, before of all we need to check the connected camera
VideoCapture cap(0);
if (!cap.isOpened()) {
printf("Error: impossible to open webcam.\n");
return -1;
}
After we can load the stream config parameters
auto config = loadConfig("stream_config.txt");
int width = std::stoi(config["width"]);
int height = std::stoi(config["height"]);
int fps = std::stoi(config["fps"]);
std::string ip = config["ip"];
std::string port = config["port"];
std::string codec = config["codec"];
std::string bitrate = config["bitrate"];
Init the camera resolution
// Set resolution
cap.set(CAP_PROP_FRAME_WIDTH, width);
cap.set(CAP_PROP_FRAME_HEIGHT, height);
Configure and open ffmpeg
// Command FFmpeg for RTP
std::ostringstream cmd;
cmd << "ffmpeg -f rawvideo -pix_fmt bgr24 -s "
<< width << "x" << height << " -r " << fps << " -i - "
<< "-c:v " << codec << " -preset ultrafast -tune zerolatency -x264-params bframes=0"
<< " -b:v " << bitrate << " -g 15 "
<< "-fflags nobuffer -flags low_delay -flush_packets 1 "
<< "-f rtp rtp://" << ip << ":" << port << " -sdp_file stream.sdp";
const std::string ffmpegCmdStr = cmd.str();
const char* ffmpegCmd = ffmpegCmdStr.c_str();
// Open pipe FFmpeg
FILE* pipe = popen(ffmpegCmd, "w");
if (!pipe) {
printf("Error: impossible to start FFmpeg.\n");
return -1;
}
Now it is possible to acquire frame and start the stream
Mat frame;
while (true) {
cap >> frame;
if (frame.empty()) break;
// Write frame data raw on pipe
fwrite(frame.data, 1, frame.total() * frame.elemSize(), pipe);
// Show preview
imshow("Streaming RTP", frame);
if (waitKey(1) == 'q') break;
}
Before to close we must free all the resources
pclose(pipe);
cap.release();
destroyAllWindows();
return 0;
Test with VLC Video LanOn Windows PC my favourite video SW is VLC Video Lan. It is possible to create a configuration file to open the video stream.
Create a new file stream.sdp and add these lines
v=0
c=IN IP4 192.168.1.224
m=video 5004 RTP/AVP 96
a=rtpmap:96 H264/90000
where IP4 is the ip address of our Raspberry, instead H264 define the video codec. Save and click on file.
On Left there is the local stream acquire on Raspberry, instead on the right there is the stream captured by VLC Video Lan.
Comments