基于Licode demo的屏幕共享功能的实现
基于Licode demo的屏幕共享功能的实现
本文在licode的basicExample基础上添加screensharing功能。主要麻烦的是屏幕共享必须在https协议下传输,需要修改erizo controller的代码,而且https协议的证书问题也比较麻烦,目前的办法是手动添加证书到chrome中。chrome新版本需要使用插件screen capture,licode官方发布的插件不能直接在本地server上使用,需要修改后使用,下文将具体说。
1.index.html 修改,添加两个按钮,分别对应本地视频音频流和屏幕流
<button id="screenSharing" onclick="screenSharing()">Screen Sharing</button> <button id="localVideo" onclick="localVideo()">localVidoe</button>
2.script.js 分别为screenSharing和localVidoe加载不同的localStream流。
function localVideo(){ var config = {audio: true, video: true, data: true, videoSize: [640, 480, 640, 480]}; localStream = Erizo.Stream(config); initialize(); console.info("localVidoe button has been clicked..."); } function screenSharing(){ var config = {screen: true, data: true, attributes: {name:'myStream'}}; config.extensionId = "gieahgoflbnmfamkbfjafjkdgnkjmhch"; localStream = Erizo.Stream(config); initialize(); console.info("screenSharing button has been clicked..."); } var serverUrl = "/"; var localStream, room, recording, recordingId; function getParameterByName(name) { name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]"); var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), results = regex.exec(location.search); return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); } function testConnection () { window.location = "/connection_test.html"; } function startRecording () { if (room !== undefined){ if (!recording){ room.startRecording(localStream, function(id) { recording = true; recordingId = id; }); } else { room.stopRecording(recordingId); recording = false; } } } function localVideo(){ var config = {audio: true, video: true, data: true, videoSize: [640, 480, 640, 480]}; localStream = Erizo.Stream(config); initialize(); console.info("localVidoe button has been clicked..."); } function screenSharing(){ var config = {screen: true, data: true, attributes: {name:'myStream'}}; config.extensionId = "gieahgoflbnmfamkbfjafjkdgnkjmhch"; localStream = Erizo.Stream(config); initialize(); console.info("screenSharing button has been clicked..."); } window.onload=function(){ } function initialize () { recording = false; var createToken = function(userName, role, callback) { var req = new XMLHttpRequest(); var url = serverUrl + 'createToken/'; var body = {username: userName, role: role}; req.onreadystatechange = function () { if (req.readyState === 4) { callback(req.responseText); } }; req.open('POST', url, true); req.setRequestHeader('Content-Type', 'application/json'); req.send(JSON.stringify(body)); }; createToken("user", "presenter", function (response) { var token = response; console.log(token); room = Erizo.Room({token: token}); localStream.addEventListener("access-accepted", function () { console.info('acess-accepted a client...'); var subscribeToStreams = function (streams) { for (var index in streams) { var stream = streams[index]; if (localStream.getID() !== stream.getID()) { room.subscribe(stream); } } }; room.addEventListener("room-connected", function (roomEvent) { console.info('a client room connected...'); room.publish(localStream, {maxVideoBW: 300}); subscribeToStreams(roomEvent.streams); }); room.addEventListener("stream-subscribed", function(streamEvent) { var stream = streamEvent.stream; var div = document.createElement('div'); div.setAttribute("style", " width: 320px; height: 240px;"); div.setAttribute("id", "test" + stream.getID()); document.body.appendChild(div); stream.show("test" + stream.getID()); }); room.addEventListener("stream-added", function (streamEvent) { var streams = []; streams.push(streamEvent.stream); subscribeToStreams(streams); document.getElementById("recordButton").disabled = false; }); room.addEventListener("stream-removed", function (streamEvent) { // Remove stream from DOM var stream = streamEvent.stream; if (stream.elementID !== undefined) { var element = document.getElementById(stream.elementID); document.body.removeChild(element); } }); room.addEventListener("stream-failed", function (streamEvent){ console.log("STREAM FAILED, DISCONNECTION"); room.disconnect(); }); room.connect(); localStream.show("myVideo"); }); localStream.init(); }); };
3.修改licode_config.js ,将erizo controller改成https传输,因为屏幕共享必须在https协议下传输。host.key host.cert是openssl生成的。ip具体具体情况设置
config.erizoController.publicIP = '192.168.0.2'; //default value: '' // Use '' to use the public IP address instead of a hostname config.erizoController.hostname = ''; //default value: '' config.erizoController.port = 8080; //default value: 8080 // Use true if clients communicate with erizoController over SSL config.erizoController.ssl = true; //default value: false config.erizoController.sslKey='/home/xxx/licode/myCert_chen/host.key'; config.erizoController.sslCert='/home/xxx/licode/myCert_chen/host.cert';
4.修改erizoCtroller.js使其支持https
var fs=require('fs'); var http = require('http'); var https=require('https'); var config = require('./../../licode_config'); GLOBAL.config = config || {}; if(GLOBAL.config.erizoController.ssl){ var options = { key: fs.readFileSync(GLOBAL.config.erizoController.sslKey).toString(), cert: fs.readFileSync(GLOBAL.config.erizoController.sslCert).toString() }; var server = https.createServer(options); } else var server = http.createServer();
5.修改chrome插件licode/erizo_controller/erizoClient/extras/chrome-extension/manifest.json,并安装到chrome中。
"externally_connectable":
{
"matches":
["*://192.168.0.2/*"]
},
6.修改extensinID,script.js和erizo.js中。externId可以在chrome插件设置dev模式查看。
7.打开https://192.168.0.2:3004链接,添加信任。然后打开https://192.168.0.2:8080/socket.io,添加到chrome信任列表中。特别是socket.io需要注意,如果不添加信任,则无法使用screen sharing功能,返回不安全的应答错误insecure response