webrtc-streamer tutorial for accessing camera video streams

Time:2023-10-24

catalogs

preamble

I. The API of webrtc-streamer

II. Introduction to webrtc-streamer startup commands

1. Original text

2. Translation

Installation and deployment of webrtc-streamer

1.Download Address

    https://github.com/mpromonet/webrtc-streamer/releases

2.windows version deployment

3. Linux version deployment

springboot integrates webrtc-streamer

V. Public network access to camera video using webrtc-streamer


preamble

Recently, the company is engaged in streaming media, I recommended webrtc-streamer to build, after using for a period of time, a new demand, the need for public access to the camera on the intranet, I queried almost all the posts and github responses to the question, did not give me an accurate answer, after continuous attempts and groping, I finally succeeded, I would like to document the process of my I hope to record my process so that more Chinese developers can take the road less traveled. I don’t know much about webrtc, but it doesn’t affect my development with the open source webrtc-streamer.

I. The API of webrtc-streamer

Service address of webrtc-streamer: 192.168.1.8:8000
Query all api: http 8000/api/help
[
	"/api/addIceCandidate",
	"/api/call",
	"/api/createOffer",
	"/api/getAudioDeviceList",
	"/api/getIceCandidate",
	"/api/getIceServers",
	"/api/getMediaList",
	"/api/getPeerConnectionList",
	"/api/getStreamList",
	"/api/getVideoDeviceList",
	"/api/hangup",
	"/api/help",
	"/api/log",
	"/api/setAnswer",
	"/api/version"
]

Key api:/api/getPeerConnectionList

I use it to determine which channel the current webrtc-streamer is connecting to

2 channels:

ICE: Interactive Connectivity Establishment

ice_state: interactive connection state (2: connected/5: disconnected)

pc_state: client connection state (2: normal/3: disconnected)

  • Connected:

"ice_state": 2

"pc_state": 2

  • Disconnecting:

"ice_state": 5

"pc_state": 3

  • This state is unknown:

"ice_state": 0

"pc_state": 0

  • Disconnect:

No json data

The json for a normal connection is as follows (too much sdp content has been removed):

[

  {

    "0.07123060004985127": {

      "ice_state": 2,

      "pc_state": 2,

      "sdp": "",

      "signaling_state": 0,

      "streams": {

        "15661718658374446496": {

          "15661718658374446496_video": {

            "kind": "video",

            "state": 1

          }

        }

      }

    }

  }

  ]

II. Introduction to webrtc-streamer startup commands

1. Original text


./webrtc-streamer [-H http port] [-S[embeded stun address]] -[v[v]]  [url1]...[urln]
./webrtc-streamer [-H http port] [-s[external stun address]] -[v[v]] [url1]...[urln]
./webrtc-streamer -V
    	-v[v[v]]           : verbosity
    	-V                 : print version
    	-H [hostname:]port : HTTP server binding (default 0.0.0.0:8000)
	-w webroot         : path to get files
	-c sslkeycert      : path to private key and certificate for HTTPS
	-N nbthreads       : number of threads for HTTP server
	-A passwd          : password file for HTTP server access
	-D authDomain      : authentication domain for HTTP server access (default:mydomain.com)

	-S[stun_address]                   : start embeded STUN server bind to address (default 0.0.0.0:3478)
	-s[stun_address]                   : use an external STUN server (default:stun.l.google.com:19302 , -:means no STUN)
	-t[username:password@]turn_address : use an external TURN relay server (default:disabled)
	-T[username:password@]turn_address : start embeded TURN server (default:disabled)

	-a                    : spefify audio capture layer to use (default:0)		
	-q[filter]                         : spefify publish filter (default:.*)
	-o                                 : use null codec (keep frame encoded)

	-C config.json                     : load urls from JSON config file 
	-R [Udp port range min:max]        : Set the webrtc udp port range (default 0:65535)

	-n name -u videourl -U audiourl    : register a name for a video url and an audio url
[url]                              : url to register in the source list

2. Translation

./webrtc-streamer [-H http port] [-S[embeded stun address]] -[v[v]]  [url1]...[urln] 
./webrtc-streamer [-H http port] [-s[external stun address]] -[v[v]] [url1]...[urln]
./webrtc-streamer -V
    -v[v[v]]           : verbosity
    -V : Print version
    -H [hostname:]port: HTTPServer binding (default 0.0.0.0:8000)
	-w webroot : get the path to the file
	-c sslkeycert : private key and certificate path for HTTPS
	-N nbthreads : number of threads in the HTTP server
	-A passwd : Password file for HTTP server access
	-D authDomain : Authentication domain for HTTP server access (default: mydomain.com)
	-S[stun_address] : Use the embedded STUN server to bind to the address (default value is 0.0.0.0:3478)
	-s[stun_address] : use an external STUN server to bind to the address (default value is 0.0.0.0:3478)
	-t[username:password@]turn_address : use external TURN relay server (default: disabled)
	-T[username:password@]turn_address : use embedded TURN relay server (default: disabled)
	-a : Specify the audio capture layer to use (default: 0)	
	-q[filter] : Specify the posting filter (default: . *)
	-o : use null codec (keep frame encoding)
	-C config.json : load URL from JSON config file
	-R [Udp port range min:max] : set webrtc-udp port range (default is 0:65535)
	-n name -u videourl -U audiourl : register the name of the video url and audio url
	[url] : the url to register in the source list

Examples:

Specify the bind ip port: . /webrtc-streamer -H 192.168.1.8:8123

webrtc-streamer tutorial for accessing camera video streams

Pay attention to a few details:

1, -o this command must be added, do not add if you will find your cpu preview several ways immediately soared to 100%.

2. -s/-S/-t/-T commands should not be followed by spaces.

3, only supports H264 video streams, H265 is not supported.

Installation and deployment of webrtc-streamer

1.Download Address

    https://github.com/mpromonet/webrtc-streamer/releases

Currently latest version 0.7.2

webrtc-streamer tutorial for accessing camera video streams     

The red boxes show the windows version and the Linux version respectively.

2.windows version deployment

Download the windows version of the zip package, unzip the following figure

webrtc-streamer tutorial for accessing camera video streams

Enter the command webrtc-streamer.exe in the current directory -H 192.168.1.227:8000 -o

Again -o in order not to transcode and thus reduce cpu load.

webrtc-streamer tutorial for accessing camera video streams

3. Linux version deployment

Installation steps for cases where all system environments are normal are as follows:

1.webrtc-streamer package: webrtc-streamer-v0.72-linux-x86_64-release.tar.gz

2. Copy to root and extract: tar -xvf webrtc-streamer-v0.7.2-Linux-x86_64-Release.tar.gz

3. Enter webrtc-streamer-v0.72-linux-x86_64-release: cd webrtc-streamer-v0.72-linux-x86_64-release

        webrtc-streamer tutorial for accessing camera video streams

4. Run./webrtc-streamer -H 192.168.1.10:8000 -o

        webrtc-streamer tutorial for accessing camera video streams

Linux probability will report the lack of environment, this self-search to solve. If you really can’t solve it, leave me a message.

springboot integrates webrtc-streamer

I’ll just quickly post the code for this part.

1. Front-end section:

Project needs to introduce js: webrtcstreamer.js, adapter.min.js, jquery-1.7.1.min.js

I have 24 videos configured here for testing, supporting RTSP streams from YUVAD, Dahua, and Hikvon.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="adapter.min.js"></script>
    <script type="text/javascript" src="webrtcstreamer.js"></script>
    <script type="text/javascript" src="jquery-1.7.1.min.js"></script>
    <style>
        video {
            width: 300px;
            height: 200px;
        }
    </style>
</head>
<body>
<p>Video playback</p
<div>
    <video id="video1" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video2" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video3" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video4" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video5" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video6" muted autoplay loop controls>muted controls disablePictureInPicture</video>
</div>
<div>
    <video id="video7" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video8" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video9" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video10" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video11" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video12" muted autoplay loop controls>muted controls disablePictureInPicture</video>
</div>
<div>
    <video id="video13" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video14" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video15" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video16" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video17" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video18" muted autoplay loop controls>muted controls disablePictureInPicture</video>
</div>
<div>
    <video id="video19" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video20" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video21" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video22" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video23" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video24" muted autoplay loop controls>muted controls disablePictureInPicture</video>
</div>
<script>
    var cameralist = new Array();
    var camera64 = {type: "hik", ipaddr: "192.168.1.64", username: "admin", password: "hik12345", port: 554};
    window.onload = function () {
        // Initialize content
        cameralist.push(camera64);
        console.log(cameralist);
    }
    let num = 0;

    function getCamera() {
        let obj = cameralist[num];
        console.log(obj);
        num++;
        if (num == 1) {
            num = 0;
        }
        return obj;
    }

    let webRtcServer = null;
    let videoMap = new Map();
    $('video').click(function (e) {
        let ID = e.target.id;//get the current element of the click event
        console.log(ID);
        if (videoMap.get(ID) != null) {
            closeVideo(ID, videoMap.get(ID));
        } else {
            let camera = getCamera();
            console.log(camera);
            if (camera.type == "ys") {
                realViewYs("192.168.1.11", ID, camera.username, camera.password, camera.ipaddr, camera.port);
            } else if (camera.type == "dh") {
                realViewDh("192.168.1.11", ID, camera.username, camera.password, camera.ipaddr, camera.port);
            } else {
                realViewHik("112.98.126.2", ID, camera.username, camera.password, camera.ipaddr, camera.port);
            }
        }
    });


    //Preview Hikvision Camera
    function realViewHik(serverip, elem, username, password, ipaddr, port) {
        webRtcServer = new WebRtcStreamer(elem, "http://" + serverip + ":28000");
        let rtspUrl = "rtsp://" + username + ":" + password + "@" + ipaddr + ":" + port + "/ch1/main/av_stream";
        let option = "rtptransport=tcp";
        console.log("rtsp address: " + rtspUrl);
        webRtcServer.connect(rtspUrl, null, option, null);
        videoMap.set(elem, webRtcServer);
    }

    //Preview Dahua Camera
    function realViewDh(serverip, elem, username, password, ipaddr, port) {
        webRtcServer = new WebRtcStreamer(elem, "http://" + serverip + ":8000");
        let rtspUrl = "rtsp://" + username + ":" + password + "@" + ipaddr + ":" + port + "/cam/realmonitor?channel=1&subtype=0";
        let option = "rtptransport=tcp";
        console.log("rtsp address: " + rtspUrl);

        webRtcServer.connect(rtspUrl, null, option, null);
        videoMap.set(elem, webRtcServer);
    }

    //Preview Transpacific Camera
    function realViewYs(serverip, elem, username, password, ipaddr, port) {
        webRtcServer = new WebRtcStreamer(elem, "http://" + serverip + ":8000");
        let rtspUrl = "rtsp://" + username + ":" + password + "@" + ipaddr + ":" + port + "/media/video1/multicast";
        console.log("rtsp address: " + rtspUrl);
        let option = "rtptransport=tcp";
        webRtcServer.connect(rtspUrl, null, option, null);
        videoMap.set(elem, webRtcServer);
    }

    function closeVideo(id, webrtc) {
        webrtc.disconnect();
        videoMap.delete(id);
    }

    // Destroy on page exit
    // window.onbeforeunload = function () {
    // alert("Page closed");
    //     webRtcServer.disconnect();
    // }
    //Triggered when the page leaves or the browser closes.
    window.onbeforeunload = function (event) {
        $.ajax({
            // url: "../getIp",
            url: "http://127.0.0.1:12344/ard/videocall",
            type: "post",
            contentType: "application/json",
            dataType: "json",
            data: JSON.stringify({"cmd": "close", "url": "https://anruida.app.zihai.shop/?id=zns&pass=ard"}),
            success: function (data) {
            }
        });
        webRtcServer.disconnect();
    };

</script>

2. Back-end section

The back-end part is much simpler, beginners should be right, directly configure a controller to find this html on the line.

@GetMapping("/")
    String index() {
        return "view";
    }

Start the project to open 127.0.0.1:8080

webrtc-streamer tutorial for accessing camera video streams

At this point, accessing the camera video on the LAN is complete.

V. Public network access to camera video using webrtc-streamer

Accessing the camera video stream on the LAN is already possible with the above steps, but not if you want to deploy the project to the public network for access.

Public network deployment steps:

1. Configure the intranet penetration address of the server where webrtc-streamer is located, for example, intranet 192.168.1.8:8000 maps to the public network as 110.154.21.14:18000.

2. Deploy a local coturn server, configure the conturn server configuration file, and at the same time, map the tcp and udp ports of 3478 of the conturn server to the public network.

3, the front-end js page using the public address is 110.154.21.14:18000 configuration webrtc-streamer

4. Start the command to add turn and stun servers: webrtc-streamer.exe -o -H 192.168.1.8:8000 -S110.154.21.14:3478 -Tadmin 3478

It’s official:

The first step is to map the webrtc intranet to the public network using a router, which I’m sure you will do playing with this, different switches are configured differently.

The second step is to build a private turn/stun service for WebRTC under Linux, currently coturn only supports linux.

coturn is a free open source TURN/STUN server. coturn server complete implementation of the STUN/TURN/ICE protocol , support for P2P penetration of firewalls .
The STUN server is used to obtain the external network address of the device.
TURN servers are used for communication relay after a point-to-point failure.
The steps for WebRTC to establish a connection are roughly like this:
The client (browser) tries a direct connection directly;
If if directly connected it is penetrated through the STUN server;
If it is not possible to penetrate it is relayed through the TURN server.

1. Pre-installation preparation
	http://libevent.org/ Download libevent-2.1.12-stable.tar.gz
	wget https://github.com/coturn/coturn/archive/4.5.1.1.tar.gz download conturn-4.5.1.1.tar.gz (stable version)
	(If the undefined reference to `SSL_CTX_up_ref' error is replaced with a stabilized version, it's fine.)
2. Install gcc
	yum install gcc-c++
3. Install openssl-devel 
	yum -y install openssl-devel
4. Install libevent2
	Download libevent-2.1.8-stable.tar.gz at http://libevent.org/
	tar -zxvf libevent-2.1.8-stable.tar.gz
	cd libevent-2.1.8-stable
	. /configure --prefix=/usr --libdir=/usr/lib64 (if it gives an error try this: . /configure --prefix=/usr/local/coturn)
	make
	make install
	Success without error message
5. Installation of conturn-4.5.1.1
	tar -zxvf 4.5.1.1.tar.gz
	cd coturn-4.5.1.1
	./configure
	make
	make install

	This can be verified by using which turnserver. If the path appears, it is successful
	
6. Configure the file and signature, then go to the folder:
	cd /usr/local/etc/ You will see a configuration file called turnserver.conf.default. Back it up:
	cp turnserver.conf.default turnserver.conf
7. Generate a signature in the current folder (enter it yourself):
	openssl req -x509 -newkey rsa:2048 -keyout /usr/local/etc/turn_server_pkey.pem -out /usr/local/etc/turn_server_cert.pem -days 99999 -nodes
8. Modification of configuration files
	Vim turnserver.conf references the following
	relay-device=eth0
	listening-ip=# Intranet IP address
	listening-port=3478
	tls-listening-port=5349
	relay-ip=#internet-ip
	external-ip=# Public IP address
	relay-threads=50
	lt-cred-mech
	min-port=49152
	max-port=65535
	cert=/usr/local/etc/turn_server_cert.pem
	pkey=/usr/local/etc/turn_server_pkey.pem
	pidfile=”/var/run/turnserver.pid”
	user=admin:123456
	cli-password=123456
	Update the configuration file as above.
	   Be sure to set the cli-password item, not setting it will report an error.
	   Pay attention to check the path and name of cert and pkey. Check that the intranet ip and public ip are filled in accurately.
	   Take care that the text is formatted accurately.
9. Start the turnserver
	turnserver -o -a -f -user=admin:123456 -c /usr/local/etc/turnserver.conf -r xiamen
	-It's to make the program start in the background.
	Just put a region after -r.
	-user must be the same as in the configuration file.
	
	ps -ef|grep turnserver command to see if the service is started, if so
10. Validation
	Trickle ICE:https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/
	1、stun:+public IP + port, the test appears public IP on behalf of the deployment is successful
	2、turn:+public IP + port, the test appears public IP on behalf of the deployment is successful!

Possible problems:

1. libevent configure: error: OpenSSL could not be found. You should add the directory

Direct online installation: yum -y install openssl-devel

2. Error message displayed during the yum software installation: There are no enabled repos.

It may be that the relevant yum source was removed:

        wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

        yum clean all && yum makecache


Just do the mapping of tcp port 3478 of the webrtc-streamer server.

The camera’s address does not need to be mapped.

This completes the public access video streaming! Please leave a comment if you have any questions.

Recommended Today

uniapp and applet set tabBar and show and hide tabBar

(1) Set the tabBar: uni.setTabberItem({}); wx.setTabberItem({}); indexnumberisWhich item of the tabBar, counting from the left, is indexed from 0.textstringnoButton text on tabiconPathstringnoImage PathselectedIconPathstringnoImage path when selectedpagePathstringnoPage absolute pathvisiblebooleannotab Whether to display uni.setTabBarItem({ index: 0, text: ‘text’, iconPath: ‘/path/to/iconPath’, selectedIconPath: ‘/path/to/selectedIconPath’, pagePath: ‘pages/home/home’ }) wx.setTabBarItem({ index: 0, text: ‘text’, iconPath: ‘/path/to/iconPath’, selectedIconPath: ‘/path/to/selectedIconPath’, pagePath: ‘pages/home/home’ }) […]