├── README.md ├── .gitignore ├── img ├── urjc.gif ├── kurento.png ├── naevatec.png ├── pipeline.png ├── spinner.gif ├── webrtc.png └── transparent-1px.png ├── bower.json ├── css └── kurento.css ├── js ├── console.js └── index.js ├── index.html └── Readme.md /README.md: -------------------------------------------------------------------------------- 1 | # webrtc-camera-rtsp 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bower_components 2 | bower_components/* 3 | -------------------------------------------------------------------------------- /img/urjc.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/georgekuruvillak/webrtc-camera-rtsp/HEAD/img/urjc.gif -------------------------------------------------------------------------------- /img/kurento.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/georgekuruvillak/webrtc-camera-rtsp/HEAD/img/kurento.png -------------------------------------------------------------------------------- /img/naevatec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/georgekuruvillak/webrtc-camera-rtsp/HEAD/img/naevatec.png -------------------------------------------------------------------------------- /img/pipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/georgekuruvillak/webrtc-camera-rtsp/HEAD/img/pipeline.png -------------------------------------------------------------------------------- /img/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/georgekuruvillak/webrtc-camera-rtsp/HEAD/img/spinner.gif -------------------------------------------------------------------------------- /img/webrtc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/georgekuruvillak/webrtc-camera-rtsp/HEAD/img/webrtc.png -------------------------------------------------------------------------------- /img/transparent-1px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/georgekuruvillak/webrtc-camera-rtsp/HEAD/img/transparent-1px.png -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kurento-hello-world", 3 | "version": "5.1.1-dev", 4 | "description": "Kurento Browser JavaScript Tutorial 1: Hello World (WebRTC in loopback)", 5 | "authors": [ 6 | "Kurento " 7 | ], 8 | "main": "index.html", 9 | "moduleType": [ 10 | "globals" 11 | ], 12 | "license": "LGPL", 13 | "homepage": "http://www.kurento.org/", 14 | "private": true, 15 | "ignore": [ 16 | "**/.*", 17 | "node_modules", 18 | "bower_components", 19 | "test", 20 | "tests" 21 | ], 22 | "dependencies": { 23 | "bootstrap": "~3.3.0", 24 | "ekko-lightbox": "~3.2.3", 25 | "adapter.js": "v0.2.9", 26 | "kurento-client": "master", 27 | "kurento-utils": "master" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /css/kurento.css: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2014 Kurento (http://kurento.org/) 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the GNU Lesser General Public License 6 | * (LGPL) version 2.1 which accompanies this distribution, and is available at 7 | * http://www.gnu.org/licenses/lgpl-2.1.html 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | */ 15 | @CHARSET "UTF-8"; 16 | 17 | html { 18 | position: relative; 19 | min-height: 100%; 20 | } 21 | 22 | body { 23 | padding-top: 40px; 24 | body 25 | } 26 | 27 | video,#console { 28 | display: block; 29 | font-size: 14px; 30 | line-height: 1.42857143; 31 | color: #555; 32 | background-color: #fff; 33 | background-image: none; 34 | border: 1px solid #ccc; 35 | border-radius: 4px; 36 | -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); 37 | box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); 38 | -webkit-transition: border-color ease-in-out .15s, box-shadow 39 | ease-in-out .15s; 40 | transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; 41 | } 42 | 43 | #console { 44 | overflow-y: auto; 45 | width: 100%; 46 | height: 120px; 47 | } 48 | 49 | .col-md-2 { 50 | width: 80px; 51 | padding-top: 190px; 52 | } 53 | -------------------------------------------------------------------------------- /js/console.js: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2013 Kurento (http://kurento.org/) 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the GNU Lesser General Public License 6 | * (LGPL) version 2.1 which accompanies this distribution, and is available at 7 | * http://www.gnu.org/licenses/lgpl-2.1.html 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | */ 15 | 16 | /** 17 | * Object that piggy-back the browser console and show their messages on a DIV 18 | * 19 | * Inspired by Node.js ClIM module (https://github.com/epeli/node-clim) 20 | * 21 | * @constructor 22 | * 23 | * @param {String} 24 | * id: id attribute of the DIV tag where to show the messages 25 | * @param console: 26 | * reference to the original browser console 27 | */ 28 | function Console(id, console) { 29 | var div = document.getElementById(id); 30 | 31 | function createMessage(msg, color) { 32 | // Sanitize the input 33 | msg = msg.toString().replace(/ 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | Kurento RTSP to WebRTC player 28 | 29 | 30 | 31 |
32 | 43 |
44 |
45 | 48 |
49 |
50 |

Remote stream

51 | 53 |
54 | Set source URL: 55 |

56 |
57 |
58 | Start

Stop 62 |
63 |
64 | 65 |
66 |
67 |
68 | 69 |
70 |
71 |
72 |
73 | 74 | 96 |
97 | 98 | 99 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | [![][KurentoImage]][website] 2 | 3 | Copyright © 2014 Kurento. Licensed under [LGPL License]. 4 | 5 | Kurento RTSP/HTTP URI to WebRTC example 6 | =========================== 7 | Kurento Client JavaScript demos 8 | 9 | This project is a simple example showing how to tranform a RTSP URI or an HTTP video URI 10 | feeds into a WebRTC stream. 11 | 12 | Installation instructions 13 | ------------------------- 14 | 15 | Be sure to have installed [Node.js] in your system: 16 | 17 | ```bash 18 | curl -sL https://deb.nodesource.com/setup | sudo bash - 19 | sudo apt-get install -y nodejs 20 | ``` 21 | 22 | Also be sure to have installed [Bower] in your system: 23 | 24 | ```bash 25 | sudo npm install -g bower 26 | ``` 27 | 28 | To launch the demo, run: 29 | 30 | ```bash 31 | cd kurento-rtsp2webrtc 32 | bower install 33 | ``` 34 | 35 | An HTTP server is required for these demos. A very simple way of doing this is 36 | by means of a NodeJS server. This server can be installed as follows: 37 | 38 | ```bash 39 | sudo npm install -g http-server 40 | ``` 41 | 42 | Then, in each demo folder execute this command: 43 | 44 | ```bash 45 | http-server 46 | ``` 47 | 48 | Finally, open this URL in your browser: http://localhost:8080/ 49 | 50 | Insert the RTSP or HTTP video feed into the input text and press "start" 51 | 52 | Optional parameters 53 | ------------------- 54 | 55 | The demos accept some optional GET parameters given on the URL, you only need to 56 | add them to the query string in the same way you would add them to the Node.js 57 | executable on your command line: 58 | 59 | ``` 60 | http://example.com/index.html?ws_url=ws://example.org/kurento 61 | ``` 62 | 63 | All the demos accept the *ws_url* parameter to set the WebSocket Kurento 64 | MediaServer endpoint, other parameters specific to each demo can be found at the 65 | top of their index.js files. 66 | 67 | 68 | Kurento 69 | ======= 70 | 71 | What is Kurento 72 | --------------- 73 | Kurento provides an open platform for video processing and streaming based on 74 | standards. 75 | 76 | This platform has several APIs and components which provide solutions to the 77 | requirements of multimedia content application developers. These include: 78 | 79 | * Kurento Media Server (KMS). A full featured media server providing 80 | the capability to create and manage dynamic multimedia pipelines. 81 | * Kurento Clients. Libraries to create applications with media 82 | capabilities. Kurento provides libraries for Java, browser JavaScript, 83 | and Node.js. 84 | 85 | Downloads 86 | --------- 87 | To download binary releases of Kurento components visit http://kurento.org 88 | 89 | Code for other Kurento projects can be found in the [GitHub Kurento group]. 90 | 91 | News and Website 92 | ---------------- 93 | Information about Kurento can be found on our [website]. 94 | Follow us on Twitter @[kurentoms]. 95 | 96 | [Bower]: http://bower.io 97 | [co]: https://github.com/visionmedia/co 98 | [GitHub Kurento group]: https://github.com/kurento 99 | [GitHub repository]: https://github.com/Kurento/kurento-tutorial-js 100 | [KurentoImage]: https://secure.gravatar.com/avatar/21a2a12c56b2a91c8918d5779f1778bf?s=120 101 | [kurentoms]: http://twitter.com/kurentoms 102 | [kurento-client-js]: https://github.com/Kurento/kurento-client-js 103 | [kurento-utils-js]: https://github.com/Kurento/kurento-utils-js 104 | [LGPL License]: http://www.gnu.org/licenses/lgpl-2.1.html 105 | [Node.js]: http://nodejs.org/ 106 | [website]: http://kurento.org 107 | -------------------------------------------------------------------------------- /js/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * (C) Copyright 2014 Kurento (http://kurento.org/) 3 | * 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the GNU Lesser General Public License 6 | * (LGPL) version 2.1 which accompanies this distribution, and is available at 7 | * http://www.gnu.org/licenses/lgpl-2.1.html 8 | * 9 | * This library is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * Lesser General Public License for more details. 13 | * 14 | */ 15 | 16 | var ws = new WebSocket('ws://139.59.4.43:8443/camera'); 17 | var webRtcPeer; 18 | var remoteIceCandidates = []; 19 | var sdpAnswerReceived = false; 20 | ws.onmessage = function(message) { 21 | var parsedMessage = JSON.parse(message.data); 22 | //console.info('Received message: ' + message.data); 23 | 24 | switch (parsedMessage.id) { 25 | case 'registerResponse': 26 | registerResponse(parsedMessage); 27 | break; 28 | 29 | case 'iceCandidate': 30 | console.log("Setting remote icecandidate " + JSON.stringify(parsedMessage.candidate)); 31 | if(sdpAnswerReceived == true){ 32 | webRtcPeer.addIceCandidate(parsedMessage.candidate) 33 | }else{ 34 | remoteIceCandidates.push(parsedMessage.candidate); 35 | } 36 | 37 | break; 38 | case 'sdpAnswer': 39 | console.log("Setting sdp answer " + JSON.stringify(parsedMessage.sdpAnswer)); 40 | webRtcPeer.processAnswer(parsedMessage.sdpAnswer); 41 | sdpAnswerReceived = true; 42 | console.log("Pushing received remote ice candidates to WebRtcPeer."); 43 | for(var i = 0; i < remoteIceCandidates.length; i++){ 44 | webRtcPeer.addIceCandidate(remoteIceCandidates[i]); 45 | } 46 | break; 47 | default: 48 | onError('Unrecognized message', parsedMessage); 49 | } 50 | } 51 | 52 | window.addEventListener('load', function(){ 53 | console = new Console('console', console); 54 | var videoOutput = document.getElementById('videoOutput'); 55 | var address = document.getElementById('address'); 56 | address.value = 'rtsp://admin:admin_123@192.168.2.183:554/Streaming/Channels/102?transportmode=unicast&profile=Profile_1'; 57 | //address.value = 'http://www.w3schools.com/TAGS/movie.mp4'; 58 | var pipeline; 59 | 60 | 61 | startButton = document.getElementById('start'); 62 | startButton.addEventListener('click', start); 63 | 64 | stopButton = document.getElementById('stop'); 65 | stopButton.addEventListener('click', stop); 66 | 67 | function start() { 68 | if(!address.value){ 69 | window.alert("You must set the video source URL first"); 70 | return; 71 | } 72 | address.disabled = true; 73 | //showSpinner(videoOutput); 74 | var options = { 75 | remoteVideo : videoOutput, 76 | configuration: { 77 | iceServers:[ 78 | { "url": "turn:139.59.4.43:3478", 79 | "username": "kurento", 80 | "credential": "kurento" 81 | }, 82 | { "url": "stun:139.59.4.43:3478" } 83 | ] 84 | } 85 | }; 86 | 87 | register(); 88 | 89 | webRtcPeer = kurentoUtils.WebRtcPeer.WebRtcPeerRecvonly(options, 90 | function(error){ 91 | if(error){ 92 | return console.error(error); 93 | } 94 | webRtcPeer.generateOffer(onOffer); 95 | webRtcPeer.peerConnection.addEventListener('iceconnectionstatechange', function(event){ 96 | if(webRtcPeer && webRtcPeer.peerConnection){ 97 | console.log("oniceconnectionstatechange -> " + webRtcPeer.peerConnection.iceConnectionState); 98 | console.log('icegatheringstate -> ' + webRtcPeer.peerConnection.iceGatheringState); 99 | } 100 | }); 101 | setIceCandidateCallbacks(); 102 | }); 103 | 104 | 105 | } 106 | 107 | function onOffer(error, sdpOffer){ 108 | if(error) return onError(error); 109 | 110 | var message = { 111 | id : 'sdpOffer', 112 | name: 'peer', 113 | cam_url: address.value, 114 | sdpOffer : sdpOffer 115 | }; 116 | sendMessage(message); 117 | 118 | } 119 | 120 | 121 | function stop() { 122 | address.disabled = false; 123 | if (webRtcPeer) { 124 | webRtcPeer.dispose(); 125 | webRtcPeer = null; 126 | } 127 | if(pipeline){ 128 | pipeline.release(); 129 | pipeline = null; 130 | } 131 | hideSpinner(videoOutput); 132 | } 133 | 134 | }); 135 | 136 | 137 | function registerResponse(response){ 138 | console.log("Response: " + JSON.stringify(response)); 139 | var status = response.status; 140 | var result = response.result; 141 | if (status == 'error'){ 142 | //setRegisterState(NOT_REGISTERING); 143 | return; 144 | } 145 | 146 | if (result == 'registered'){ 147 | //setRegisterState(NOT_REGISTERING); 148 | return; 149 | } 150 | } 151 | 152 | 153 | function register() { 154 | var name = 'peer'; 155 | 156 | //setRegisterState(REGISTERING); 157 | 158 | var message = { 159 | id : 'register', 160 | isKMS: false, 161 | name : name 162 | }; 163 | sendMessage(message); 164 | } 165 | 166 | function sendMessage(message) { 167 | var jsonMessage = JSON.stringify(message); 168 | console.log('Sending message: ' + jsonMessage); 169 | ws.send(jsonMessage); 170 | } 171 | 172 | function setIceCandidateCallbacks(){ 173 | webRtcPeer.on('icecandidate', function(candidate){ 174 | console.log("Sending local icecandidate " + JSON.stringify(candidate)); 175 | 176 | candidate = kurentoClient.register.complexTypes.IceCandidate(candidate); 177 | 178 | var message = { 179 | id : 'iceCandidate', 180 | name: 'peer', 181 | iceCandidate : candidate 182 | }; 183 | sendMessage(message); 184 | 185 | }); 186 | 187 | } 188 | 189 | function onError(error) { 190 | if(error) 191 | { 192 | console.error(error); 193 | stop(); 194 | } 195 | } 196 | 197 | function showSpinner() { 198 | for (var i = 0; i < arguments.length; i++) { 199 | arguments[i].poster = 'img/transparent-1px.png'; 200 | arguments[i].style.background = "center transparent url('img/spinner.gif') no-repeat"; 201 | } 202 | } 203 | 204 | function hideSpinner() { 205 | for (var i = 0; i < arguments.length; i++) { 206 | arguments[i].src = ''; 207 | arguments[i].poster = 'img/webrtc.png'; 208 | arguments[i].style.background = ''; 209 | } 210 | } 211 | 212 | /** 213 | * Lightbox utility (to display media pipeline image in a modal dialog) 214 | */ 215 | $(document).delegate('*[data-toggle="lightbox"]', 'click', function(event) { 216 | event.preventDefault(); 217 | $(this).ekkoLightbox(); 218 | }); 219 | --------------------------------------------------------------------------------