Remote video transmission software platform based on web

Project Name: web based remote video transmission

Software platform: Ubuntu
Hardware platform: NanoPi Duo2
Note: there are many hardware platforms, such as mini2440, NanoPi series, raspberry pie, etc.

mjpg-streamerMJPG-streamer
It is an open source video streaming server based on IP address. Its input plug-in reads video data from the camera. This input plug-in generates video data and copies the video data into memory. It has several output plug-ins to process these video data. The most important output plug-in is the website server plug-in, which transmits the video data to the user's browser. Mjpg streamer's job is to bind one input plug-in and multiple output plug-ins together, and all the work is completed through its plug-ins.

Step 1:

Download source code address: https://sourceforge.net/p/mjpg-streamer/code/HEAD/tree/
You can directly download the compressed file of the source package: mjpg-streamer-code-r182 zip
Or download through SVN: svn checkout https://svn.code.sf.net/p/mjpg-streamer/code/ mjpg-streamer-code
Note: svn needs to be installed in the environment first

If you don't want trouble, baidu online disk: link: https://pan.baidu.com/s/1B29YOHRYDkzGpkD0h8HsmA Extraction code: qjpd, get it directly!

To install mjpg streamer, you need to install libjpeg first. The source address of libjpeg https://sourceforge.net/projects/libjpeg/ You can use wget to download directly.

Step 2:

Cross compilation
1. Install cross compilation environment (take NanoPi Duo2 platform as an example)
*Download cross compiler
arm-cortexa9-linux-gnueabihf-4.9.3-20160512.tar.xz
Note: the NanoPi official website provides a download link
*Put it in the opt directory of Ubuntu and unzip it

tar -xf arm-cortexa9-linux-gnueabihf-4.9.3-20160512.tar.xz
*Modify file / root / bashrc´╝î
*Add export PATH=$PATH:/opt/4.9.3/bin at the end
*Make the modified file effective source / root / bashrc

2. Compile libjpeg
*Unzip and enter the directory;
*Configuring the compilation environment
./configure --host=arm-linux- --prefix=/home/jpeg-install
*Compile make
*Install make install
*After installation, you will see the JPEG install directory in the / home directory.

3. Compile mjpg streamer

  • Makefile modify top level
    CC=arm-linux-gcc

  • Modify the Makefile of the plug-in (plugins/input_uvc/Makefile)
    CC = arm linux GCC and dynamic library path $(CC) $(cflags) - L / home / jpeg install - ljpeg - o $@ input_ uvc. so

  • Modify the plugin Makefile (plugins/output_http/Makefile)
    CC=arm-linux-gcc

    • Compile make

The final generated files are packaged and copied to the development board. libjpeg needs to be installed, and mjpg streamer does not need to be installed.

Step 3:

function
1. Configure the network to ensure that NanoPi and computer can form a LAN;
ifconfig

wlan0Link encap:Ethernet HWaddr c0:84:7d:a0:27:14 
inetaddr:192.168.0.105 Bcast:192.168.0.255 
Mask:255.255.255.0inet6addr: fe80::9e9a:8bbc:69f1:24f0/64 
Scope:LinkUPBROADCAST RUNNING MULTICAST MTU:1500 Metric:1RXpackets:8731 errors:0 dropped:0 
overruns:0 frame:0TXpackets:3727 errors:0 dropped:0 
overruns:0 carrier:0collisions:0 txqueuelen:1000 
RXbytes:6593454 (6.5 MB) TX bytes:502413 (502.4 KB)

The address of the development board is 192.168.0.105, which is very important.

2. Open the browser of the notebook and enter: http://192.168.0.105:8080/ Select Stream

Source code analysis
1. Several important documents

  • input_testpicture.so: This is an image test plug-in. It compiles the preset image into a header file, which can transmit the image without a camera, so as to facilitate the debugging of the program.
  • input_uvc.so: this file calls the USB camera driver V4L2 to read video data from the camera.
  • output_http.so: This is a fully functional web server. It can not only process files from a single folder, but also execute certain commands. It can process an image from the input plug-in, or output the video files of the input plug-in in in the form of HTTP video data service stream according to the existing M-JPEG standard.
  • input_control.so: this file realizes the control of camera parameters.
  • output_file.so: the function of this plug-in is to store the JPEG image of the input plug-in in a specific folder, which can be used to capture the image.

2. Command parsing

intmain(int argc, char *argv[]){char *input = "input_uvc.so --resolution 640x480 --fps 5 --device /dev/video0";
char *output[MAX_OUTPUT_PLUGINS];//10int daemon=0, i; size_t tmp=0;output[0] = "output_http.so --port 8080";
global.outcnt = 0;global.control = control;/* parameter parsing */while(1) {int option_index = 0, c=0;
staticstruct option long_options[] = \ { {"h", no_argument, 0, 0}, {"help", no_argument, 0, 0}, {"i", required_argument, 0, 0}, {"input", required_argument, 0, 0}, {"o", required_argument, 0, 0}, {"output", required_argument, 0, 0}, {"v", no_argument, 0, 0}, {"version", no_argument, 0, 0}, {"b", no_argument, 0, 0}, {"background", no_argument, 0, 0}, {0, 0, 0, 0} };c = getopt_long_only(argc, argv, "", long_options, &option_index);

Here we mainly encounter a function function getopt_long_only(), which is mainly used to parse the command line options, that is, to parse the parameters of - h -i -o -v -b in input. Please refer to getopt for how to use this function_ long_ only.

3. Call input plug-in

/* open input plugin */ tmp = (size_t)(strchr(input, ' ')-input);global.in.plugin = (tmp > 0)?strndup(input, tmp):strdup(input);global.in.handle = dlopen(global.in.plugin, RTLD_LAZY);if ( !global.in.handle ) { LOG("ERROR: could not find input plugin\n"); LOG(" Perhaps you want to adjust the search path with:\n"); LOG(" # export LD_ LIBRARY_ PATH=/path/to/plugin/folder\n"); LOG(" dlopen: %s\n", dlerror() ); closelog(); exit(EXIT_FAILURE); }global.in.init = dlsym(global.in.handle, "input_init");if ( global.in.init == NULL ) { LOG("%s\n", dlerror()); exit(EXIT_FAILURE); } global. in. stop = dlsym(global.in.handle, "input_stop"); if ( global.in.stop == NULL ) { LOG("%s\n", dlerror()); exit(EXIT_FAILURE); } global. in. run = dlsym(global.in.handle, "input_run"); if ( global.in.run == NULL ) { LOG("%s\n", dlerror()); exit(EXIT_FAILURE); } The dlopen() function is responsible for opening * So plug-in, dlsym() is responsible for calling related functions in the plug-in. When entering/ mjpg_streamer -i "./input_uvc.so" the system will call input_ uvc. Input in so_ Init function to initialize the input device.

4. Call output plug-in

/* open output plugin */for (i=0; i<global.outcnt; i++) { tmp = (size_t)(strchr(output[i], ' ')-output[i]);global.out[i].plugin = (tmp > 0)?strndup(output[i], tmp):strdup(output[i]);global.out[i].handle = dlopen(global.out[i].plugin, RTLD_LAZY);if ( !global.out[i].handle ) { LOG("ERROR: could not find output plugin %s\n", global.out[i].plugin); LOG(" Perhaps you want to adjust the search path with:\n"); LOG(" # export LD_LIBRARY_PATH=/path/to/plugin/folder\n"); LOG(" dlopen: %s\n", dlerror() ); closelog(); exit(EXIT_FAILURE); }global.out[i].init = dlsym(global.out[i].handle, "output_init");if ( global.out[i].init == NULL ) { LOG("%s\n", dlerror()); exit(EXIT_FAILURE); }global.out[i].stop = dlsym(global.out[i].handle, "output_stop");if ( global.out[i].stop == NULL ) { LOG("%s\n", dlerror()); exit(EXIT_FAILURE); }if ( global.out[i].stop == NULL ) { LOG("%s\n", dlerror()); exit(EXIT_FAILURE); }global.out[i].run = dlsym(global.out[i].handle, "output_run");if ( global.out[i].run == NULL ) { LOG("%s\n", dlerror()); exit(EXIT_FAILURE); }

5. Input function analysis
intinput_init(input_parameter *param)
This function code implements some settings for the format, frame, request buf, queue buf, etc. of the usb camera,
The main implementation is also in the function

init_videoIn(videoIn, dev, width, height, fps, format, 1)
int input_stop(void) 
{ 
 	DBG("will cancel input thread\n"); 
	pthread_cancel(cam); 
	return 0;
} 

Input stop, mainly to cancel the thread.

6. Output function

intoutput_init(output_parameter *param)
int output_stop(intid)
int output_run(intid)

Posted by Bijan on Thu, 19 May 2022 17:03:31 +0300