Javascript 来自多个摄像头的流式视频
我正在从事一个webRCT项目。我正在使用Janus webRtc gateway video room功能和RestAPI+Mysql数据库来处理相机细节,使用AngularJs来流式传输视频,并使用客户端应用程序来捕获视频 我创建了一个HomeController.js来处理相机细节。和一个janucontroller.js来处理流式视频 现在,在目前的情况下,我可以从单个摄像头流式传输视频。如果我在html5页面中手动创建多个div,那么多个摄像头也支持。但那不是我想做的。我想用angularJs“ng repeat”在htlm5页面中创建div,并为每个div提供唯一的Id 这里我的代码是我的重要部分 HomeController.jsJavascript 来自多个摄像头的流式视频,javascript,angularjs,html,webrtc,janus,Javascript,Angularjs,Html,Webrtc,Janus,我正在从事一个webRCT项目。我正在使用Janus webRtc gateway video room功能和RestAPI+Mysql数据库来处理相机细节,使用AngularJs来流式传输视频,并使用客户端应用程序来捕获视频 我创建了一个HomeController.js来处理相机细节。和一个janucontroller.js来处理流式视频 现在,在目前的情况下,我可以从单个摄像头流式传输视频。如果我在html5页面中手动创建多个div,那么多个摄像头也支持。但那不是我想做的。我想用angul
$scope.getPeripheralList = function (devHardwareId){
HomeService.getPeripheralList(devHardwareId)
.then (function success(response){
$scope.peripheralDetails = response.data;
$scope.errorMessage = '';
},
function error(response) {
$mdDialog.show(
$mdDialog.alert()
.parent(angular.element(document.querySelector('#popupContainer')))
.clickOutsideToClose(true)
.title('Error occured!!!!!!')
.textContent(response.data.message)
.ariaLabel('')
.ok('Ok')
);
});
}
'use strict';
App.controller('JanusController', ['$scope', 'HomeService','uiGridConstants',"$mdDialog", function($scope, HomeService,uiGridConstants,$mdDialog) {
var server = null;
if(window.location.protocol === 'http:')
server = "http://" + "192.168.2.10" + ":8088/janus";
else
server = "https://" +"192.168.2.10" + ":8089/janus";
var janus = null;
var sfutest = null;
var opaqueId = "videoroomtest-"+Janus.randomString(12);
var started = false;
var myroom = 1234; // Demo room
var myusername = null;
var myid = null;
var mystream = null;
// We use this other ID just to map our subscriptions to us
var mypvtid = null;
var feeds = [];
var bitrateTimer = [];
var doSimulcast = (getQueryStringValue("simulcast") === "no" || getQueryStringValue("simulcast") === "false");
// Initialize the library (all console debuggers enabled)
Janus.init({debug: "all", callback: function() {
started = true;
if(!Janus.isWebrtcSupported()) {
bootbox.alert("No WebRTC support... ");
return;
}
// Create session
janus = new Janus(
{
server: server,
success: function() {
// Attach to video room test plugin
janus.attach(
{
plugin: "janus.plugin.videoroom",//the unique package name of the plugin
opaqueId: opaqueId, // an optional opaque string meaningful to application
success: function(pluginHandle) { //the handle was successfully created and is ready to be used;
sfutest = pluginHandle;
Janus.log("Plugin attached! (" + sfutest.getPlugin() + ", id=" + sfutest.getId() + ")");
Janus.log(" -- This is a publisher/manager");
registerUsername()
angular.element('#start').removeAttr('disabled').html("Stop")
.click(function() {
$(this).attr('disabled', true);
janus.destroy();
});
},
error: function(error) { //the handle was NOT successfully created;
Janus.error(" -- Error attaching plugin...", error);
bootbox.alert("Error attaching plugin... " + error);
},
mediaState: function(medium, on) {
Janus.log("Janus " + (on ? "started" : "stopped") + " receiving our " + medium);
},
webrtcState: function(on) {
Janus.log("Janus says our WebRTC PeerConnection is " + (on ? "up" : "down") + " now");
//write codes to change bitrate here.
},
onmessage: function(msg, jsep) { //a message/event has been received from the plugin;
Janus.debug(" ::: Got a message (publisher) :::");
Janus.debug(msg);
var event = msg["videoroom"];
Janus.debug("Event: " + event);
if(event != undefined && event != null) {
if(event === "joined") {
// Publisher/manager created, negotiate WebRTC and attach to existing feeds, if any
myid = msg["id"];
mypvtid = msg["private_id"];
Janus.log("Successfully joined room " + msg["room"] + " with ID " + myid);
publishOwnFeed(false); //not publishing a video
// Any new feed to attach to?
if(msg["publishers"] !== undefined && msg["publishers"] !== null) {
var list = msg["publishers"];
Janus.debug("Got a list of available publishers/feeds:");
Janus.debug(list);
for(var f in list) {
var id = list[f]["id"];
var display = list[f]["display"];
var audio = list[f]["audio_codec"];
var video = list[f]["video_codec"];
Janus.debug(" >> [" + id + "] " + display + " (audio: " + audio + ", video: " + video + ")");
newRemoteFeed(id, display, audio, video);
}
}
} else if(event === "destroyed") {
// The room has been destroyed
Janus.warn("The room has been destroyed!");
bootbox.alert("The room has been destroyed", function() {
window.location.reload();
});
} else if(event === "event") {
// Any new feed to attach to?
if(msg["publishers"] !== undefined && msg["publishers"] !== null) {
var list = msg["publishers"];
Janus.debug("Got a list of available publishers/feeds:");
Janus.debug(list);
for(var f in list) {
var id = list[f]["id"];
var display = list[f]["display"];
var audio = list[f]["audio_codec"];
var video = list[f]["video_codec"];
Janus.debug(" >> [" + id + "] " + display + " (audio: " + audio + ", video: " + video + ")");
newRemoteFeed(id, display, audio, video);
}
} else if(msg["leaving"] !== undefined && msg["leaving"] !== null) {
// One of the publishers has gone away?
var leaving = msg["leaving"];
Janus.log("Publisher left: " + leaving);
var remoteFeed = null;
for(var i=1; i<6; i++) {
if(feeds[i] != null && feeds[i] != undefined && feeds[i].rfid == leaving) {
remoteFeed = feeds[i];
break;
}
}
if(remoteFeed != null) {
Janus.debug("Feed " + remoteFeed.rfid + " (" + remoteFeed.rfdisplay + ") has left the room, detaching");
//$('#remote'+remoteFeed.rfindex).empty().hide();
$('#videoremote'+remoteFeed.rfindex).empty();
feeds[remoteFeed.rfindex] = null;
remoteFeed.detach();
}
} else if(msg["unpublished"] !== undefined && msg["unpublished"] !== null) {
// One of the publishers has unpublished?
var unpublished = msg["unpublished"];
Janus.log("Publisher left: " + unpublished);
if(unpublished === 'ok') {
// That's us
sfutest.hangup();
return;
}
var remoteFeed = null;
for(var i=1; i<6; i++) {
if(feeds[i] != null && feeds[i] != undefined && feeds[i].rfid == unpublished) {
remoteFeed = feeds[i];
break;
}
}
if(remoteFeed != null) {
Janus.debug("Feed " + remoteFeed.rfid + " (" + remoteFeed.rfdisplay + ") has left the room, detaching");
// $('#remote'+remoteFeed.rfindex).empty().hide();
$('#videoremote'+remoteFeed.rfindex).empty();
//document.getElementById('videoremote'+remoteFeed.rfindex).empty();
feeds[remoteFeed.rfindex] = null;
remoteFeed.detach();
}
}
else if(msg["error"] !== undefined && msg["error"] !== null) {
bootbox.alert(msg["error_code" + "error"]);
}
}
}
if(jsep !== undefined && jsep !== null) {
Janus.debug("Handling SDP as well...");
Janus.debug(jsep);
sfutest.handleRemoteJsep({jsep: jsep});
}
},
onlocalstream: function(stream) {
//we don't publish our stream here
},
onremotestream: function(stream) {
// The publisher stream is sendonly, we don't expect anything here
},
oncleanup: function() {
//
}
});
},
error: function(error) {
Janus.error(error);
bootbox.alert(error, function() {
window.location.reload();
});
},
destroyed: function() {
window.location.reload();
}
});
}
});
/////////////////////////////////////////////////////////
function registerUsername() {
var username = "stream";
var register = { "request": "join", "room": myroom, "ptype": "publisher", "display": username };
myusername = username;
sfutest.send({"message": register});
}
//////////////////////////////////////////////////////////
function publishOwnFeed(useAudio) {
// Publish our stream
//$('#publish').attr('disabled', true).unbind('click');
sfutest.createOffer(
{
// Add data:true here if you want to publish datachannels as well
media: { audioRecv: false, videoRecv: false, audioSend: false, videoSend: false }, // Publishers are sendonly
simulcast: doSimulcast,
success: function(jsep) {
Janus.debug("Got publisher SDP!");
Janus.debug(jsep);
var publish = { "request": "configure", "audio": useAudio, "video": true };
sfutest.send({"message": publish, "jsep": jsep});
},
error: function(error) {
Janus.error("WebRTC error:", error);
if (useAudio) {
publishOwnFeed(false);
} else {
bootbox.alert("WebRTC error... " + JSON.stringify(error));
angular.element('#publish').removeAttr('disabled').click(function() { publishOwnFeed(true); });
}
}
});
}
function toggleMute() {
//to mute
}
function unpublishOwnFeed() {
// Unpublish our stream
}
function newRemoteFeed(id, display, audio, video) {
// A new feed has been published, create a new plugin handle and attach to it as a listener
var remoteFeed = null;
janus.attach(
{
plugin: "janus.plugin.videoroom",
opaqueId: opaqueId,
success: function(pluginHandle) {
remoteFeed = pluginHandle;
Janus.log("Plugin attached! (" + remoteFeed.getPlugin() + ", id=" + remoteFeed.getId() + ")");
// We wait for the plugin to send us an offer
var listen = { "request": "join", "room": myroom, "ptype": "listener", "feed": id, "private_id": mypvtid };
// In case you don't want to receive audio, video or data, even if the
// publisher is sending them, set the 'offer_audio', 'offer_video' or
// 'offer_data' properties to false (they're true by default), e.g.:
// listen["offer_video"] = false;
// For example, if the publisher is VP8 and this is Safari, let's avoid video
if(video !== "h264" && Janus.webRTCAdapter.browserDetails.browser === "safari") {
if(video)
video = video.toUpperCase()
toastr.warning("Publisher is using " + video + ", but Safari doesn't support it: disabling video");
listen["offer_video"] = false;
}
remoteFeed.send({"message": listen});
},
error: function(error) {
Janus.error(" -- Error attaching plugin...", error);
bootbox.alert("Error attaching plugin... " + error);
},
onmessage: function(msg, jsep) {
Janus.debug(" ::: Got a message (listener) :::");
Janus.debug(msg);
var event = msg["videoroom"];
Janus.debug("Event: " + event);
if(msg["error"] !== undefined && msg["error"] !== null) {
bootbox.alert(msg["error"]);
}
else if(event != undefined && event != null) {
if(event === "attached") {
// Subscriber created and attached
for(var i=1;i<6;i++) {
if(feeds[i] === undefined || feeds[i] === null) {
feeds[i] = remoteFeed;
remoteFeed.rfindex = i;
break;
}
}
remoteFeed.rfid = msg["id"];
remoteFeed.rfdisplay = msg["display"];
Janus.log("Successfully attached to feed " + remoteFeed.rfid + " (" + remoteFeed.rfdisplay + ") in room " + msg["room"]);
} else if(msg["error"] !== undefined && msg["error"] !== null) {
Janus.error(msg["error"]);
} else {
// What has just happened?
}
}
if(jsep !== undefined && jsep !== null) {
Janus.debug("Handling SDP as well...");
Janus.debug(jsep);
// Answer and attach
remoteFeed.createAnswer(
{
jsep: jsep,
// Add data:true here if you want to subscribe to datachannels as well
// (obviously only works if the publisher offered them in the first place)
media: { audioSend: false, videoSend: false }, // We want recvonly audio/video
success: function(jsep) {
Janus.debug("Got SDP!");
Janus.debug(jsep);
var body = { "request": "start", "room": myroom };
remoteFeed.send({"message": body, "jsep": jsep});
},
error: function(error) {
Janus.error("WebRTC error:", error);
bootbox.alert("WebRTC error... " + JSON.stringify(error));
}
});
}
},
webrtcState: function(on) {
Janus.log("Janus says this WebRTC PeerConnection (feed #" + remoteFeed.rfindex + ") is " + (on ? "up" : "down") + " now");
},
onlocalstream: function(stream) {
// The subscriber stream is recvonly, we don't expect anything here
},
onremotestream: function(stream) {
Janus.debug("Remote feed #" + remoteFeed.rfindex);
if(angular.element('#remotevideo'+remoteFeed.rfindex).length > 0) {
// Been here already: let's see if anything changed
var videoTracks = stream.getVideoTracks();
if(videoTracks && videoTracks.length > 0 && !videoTracks[0].muted) {
$('#novideo'+remoteFeed.rfindex).remove();
if($("#remotevideo"+remoteFeed.rfindex).get(0).videoWidth)
$('#remotevideo'+remoteFeed.rfindex).show();
}
return;
}
// No remote video yet
$('#videoremote'+remoteFeed.rfindex).append('<video class="rounded centered" id="waitingvideo' + remoteFeed.rfindex + '" width=320 height=240 />');
$('#videoremote'+remoteFeed.rfindex).append('<video class="rounded centered relative hide" id="remotevideo' + remoteFeed.rfindex + '" width="100%" height="100%" autoplay/>');
$('#videoremote'+remoteFeed.rfindex).append(
'<span class="label label-primary hide" id="curres'+remoteFeed.rfindex+'" style="position: absolute; bottom: 0px; left: 0px; margin: 15px;"></span>' +
'<span class="label label-info hide" id="curbitrate'+remoteFeed.rfindex+'" style="position: absolute; bottom: 0px; right: 0px; margin: 15px;"></span>');
// Show the video, hide the spinner and show the resolution when we get a playing event
$("#remotevideo"+remoteFeed.rfindex).bind("playing", function () {
if(remoteFeed.spinner !== undefined && remoteFeed.spinner !== null)
remoteFeed.spinner.stop();
remoteFeed.spinner = null;
$('#waitingvideo'+remoteFeed.rfindex).remove();
if(this.videoWidth)
$('#remotevideo'+remoteFeed.rfindex).removeClass('hide').show();
var width = this.videoWidth;
var height = this.videoHeight;
$('#curres'+remoteFeed.rfindex).removeClass('hide').text(width+'x'+height).show();
if(Janus.webRTCAdapter.browserDetails.browser === "firefox") {
// Firefox Stable has a bug: width and height are not immediately available after a playing
setTimeout(function() {
var width = $("#remotevideo"+remoteFeed.rfindex).get(0).videoWidth;
var height = $("#remotevideo"+remoteFeed.rfindex).get(0).videoHeight;
$('#curres'+remoteFeed.rfindex).removeClass('hide').text(width+'x'+height).show();
}, 2000);
}
});
Janus.attachMediaStream($('#remotevideo'+remoteFeed.rfindex).get(0), stream);
var videoTracks = stream.getVideoTracks();
if(videoTracks === null || videoTracks === undefined || videoTracks.length === 0 || videoTracks[0].muted) {
// No remote video
$('#remotevideo'+remoteFeed.rfindex).hide();
$('#videoremote'+remoteFeed.rfindex).append(
'<div id="novideo'+remoteFeed.rfindex+'" class="no-video-container">' +
'<i class="fa fa-video-camera fa-5 no-video-icon" style="height: 100%;"></i>' +
'<span class="no-video-text" style="font-size: 16px;">No remote video available</span>' +
'</div>');
}
if(Janus.webRTCAdapter.browserDetails.browser === "chrome" || Janus.webRTCAdapter.browserDetails.browser === "firefox" ||
Janus.webRTCAdapter.browserDetails.browser === "safari") {
$('#curbitrate'+remoteFeed.rfindex).removeClass('hide').show();
bitrateTimer[remoteFeed.rfindex] = setInterval(function() {
// Display updated bitrate, if supported
var bitrate = remoteFeed.getBitrate();
$('#curbitrate'+remoteFeed.rfindex).text(bitrate);
// Check if the resolution changed too
var width = $("#remotevideo"+remoteFeed.rfindex).get(0).videoWidth;
var height = $("#remotevideo"+remoteFeed.rfindex).get(0).videoHeight;
if(width > 0 && height > 0)
$('#curres'+remoteFeed.rfindex).removeClass('hide').text(width+'x'+height).show();
}, 1000);
}
},
oncleanup: function() {
Janus.log(" ::: Got a cleanup notification (remote feed " + id + ") :::");
if(remoteFeed.spinner !== undefined && remoteFeed.spinner !== null)
remoteFeed.spinner.stop();
remoteFeed.spinner = null;
$('#remotevideo'+remoteFeed.rfindex).remove();
$('#waitingvideo'+remoteFeed.rfindex).remove();
$('#novideo'+remoteFeed.rfindex).remove();
$('#curbitrate'+remoteFeed.rfindex).remove();
$('#curres'+remoteFeed.rfindex).remove();
if(bitrateTimer[remoteFeed.rfindex] !== null && bitrateTimer[remoteFeed.rfindex] !== null)
clearInterval(bitrateTimer[remoteFeed.rfindex]);
bitrateTimer[remoteFeed.rfindex] = null;
remoteFeed.simulcastStarted = false;
$('#simulcast'+remoteFeed.rfindex).remove();
}
});
}
}]);
上述电话的回应
[{"peripheralId":7,"perHardwareId":"Logitech HD Webcam C270","peripheralName":"Logitech HD Webcam C270","peripheralType":"Video","isActive":true,"device":{"deviceId":13,"deviceName":"DESKTOP-NJ02GI1","devHardwareId":"0A0027000007","isActive":true,"deviceIp":"192.168.2.19","creationDate":"2018-03-09T10:54:40.000+0000","lastModifiedDate":"2018-03-09T10:54:40.000+0000"}},{"peripheralId":8,"perHardwareId":"A4TECH USB2.0 PC Camera","peripheralName":"A4TECH USB2.0 PC Camera","peripheralType":"Video","isActive":true,"device":{"deviceId":13,"deviceName":"DESKTOP-NJ02GI1","devHardwareId":"0A0027000007","isActive":true,"deviceIp":"192.168.2.19","creationDate":"2018-03-09T10:54:40.000+0000","lastModifiedDate":"2018-03-09T10:54:40.000+0000"}}]
janucontroller.js
$scope.getPeripheralList = function (devHardwareId){
HomeService.getPeripheralList(devHardwareId)
.then (function success(response){
$scope.peripheralDetails = response.data;
$scope.errorMessage = '';
},
function error(response) {
$mdDialog.show(
$mdDialog.alert()
.parent(angular.element(document.querySelector('#popupContainer')))
.clickOutsideToClose(true)
.title('Error occured!!!!!!')
.textContent(response.data.message)
.ariaLabel('')
.ok('Ok')
);
});
}
'use strict';
App.controller('JanusController', ['$scope', 'HomeService','uiGridConstants',"$mdDialog", function($scope, HomeService,uiGridConstants,$mdDialog) {
var server = null;
if(window.location.protocol === 'http:')
server = "http://" + "192.168.2.10" + ":8088/janus";
else
server = "https://" +"192.168.2.10" + ":8089/janus";
var janus = null;
var sfutest = null;
var opaqueId = "videoroomtest-"+Janus.randomString(12);
var started = false;
var myroom = 1234; // Demo room
var myusername = null;
var myid = null;
var mystream = null;
// We use this other ID just to map our subscriptions to us
var mypvtid = null;
var feeds = [];
var bitrateTimer = [];
var doSimulcast = (getQueryStringValue("simulcast") === "no" || getQueryStringValue("simulcast") === "false");
// Initialize the library (all console debuggers enabled)
Janus.init({debug: "all", callback: function() {
started = true;
if(!Janus.isWebrtcSupported()) {
bootbox.alert("No WebRTC support... ");
return;
}
// Create session
janus = new Janus(
{
server: server,
success: function() {
// Attach to video room test plugin
janus.attach(
{
plugin: "janus.plugin.videoroom",//the unique package name of the plugin
opaqueId: opaqueId, // an optional opaque string meaningful to application
success: function(pluginHandle) { //the handle was successfully created and is ready to be used;
sfutest = pluginHandle;
Janus.log("Plugin attached! (" + sfutest.getPlugin() + ", id=" + sfutest.getId() + ")");
Janus.log(" -- This is a publisher/manager");
registerUsername()
angular.element('#start').removeAttr('disabled').html("Stop")
.click(function() {
$(this).attr('disabled', true);
janus.destroy();
});
},
error: function(error) { //the handle was NOT successfully created;
Janus.error(" -- Error attaching plugin...", error);
bootbox.alert("Error attaching plugin... " + error);
},
mediaState: function(medium, on) {
Janus.log("Janus " + (on ? "started" : "stopped") + " receiving our " + medium);
},
webrtcState: function(on) {
Janus.log("Janus says our WebRTC PeerConnection is " + (on ? "up" : "down") + " now");
//write codes to change bitrate here.
},
onmessage: function(msg, jsep) { //a message/event has been received from the plugin;
Janus.debug(" ::: Got a message (publisher) :::");
Janus.debug(msg);
var event = msg["videoroom"];
Janus.debug("Event: " + event);
if(event != undefined && event != null) {
if(event === "joined") {
// Publisher/manager created, negotiate WebRTC and attach to existing feeds, if any
myid = msg["id"];
mypvtid = msg["private_id"];
Janus.log("Successfully joined room " + msg["room"] + " with ID " + myid);
publishOwnFeed(false); //not publishing a video
// Any new feed to attach to?
if(msg["publishers"] !== undefined && msg["publishers"] !== null) {
var list = msg["publishers"];
Janus.debug("Got a list of available publishers/feeds:");
Janus.debug(list);
for(var f in list) {
var id = list[f]["id"];
var display = list[f]["display"];
var audio = list[f]["audio_codec"];
var video = list[f]["video_codec"];
Janus.debug(" >> [" + id + "] " + display + " (audio: " + audio + ", video: " + video + ")");
newRemoteFeed(id, display, audio, video);
}
}
} else if(event === "destroyed") {
// The room has been destroyed
Janus.warn("The room has been destroyed!");
bootbox.alert("The room has been destroyed", function() {
window.location.reload();
});
} else if(event === "event") {
// Any new feed to attach to?
if(msg["publishers"] !== undefined && msg["publishers"] !== null) {
var list = msg["publishers"];
Janus.debug("Got a list of available publishers/feeds:");
Janus.debug(list);
for(var f in list) {
var id = list[f]["id"];
var display = list[f]["display"];
var audio = list[f]["audio_codec"];
var video = list[f]["video_codec"];
Janus.debug(" >> [" + id + "] " + display + " (audio: " + audio + ", video: " + video + ")");
newRemoteFeed(id, display, audio, video);
}
} else if(msg["leaving"] !== undefined && msg["leaving"] !== null) {
// One of the publishers has gone away?
var leaving = msg["leaving"];
Janus.log("Publisher left: " + leaving);
var remoteFeed = null;
for(var i=1; i<6; i++) {
if(feeds[i] != null && feeds[i] != undefined && feeds[i].rfid == leaving) {
remoteFeed = feeds[i];
break;
}
}
if(remoteFeed != null) {
Janus.debug("Feed " + remoteFeed.rfid + " (" + remoteFeed.rfdisplay + ") has left the room, detaching");
//$('#remote'+remoteFeed.rfindex).empty().hide();
$('#videoremote'+remoteFeed.rfindex).empty();
feeds[remoteFeed.rfindex] = null;
remoteFeed.detach();
}
} else if(msg["unpublished"] !== undefined && msg["unpublished"] !== null) {
// One of the publishers has unpublished?
var unpublished = msg["unpublished"];
Janus.log("Publisher left: " + unpublished);
if(unpublished === 'ok') {
// That's us
sfutest.hangup();
return;
}
var remoteFeed = null;
for(var i=1; i<6; i++) {
if(feeds[i] != null && feeds[i] != undefined && feeds[i].rfid == unpublished) {
remoteFeed = feeds[i];
break;
}
}
if(remoteFeed != null) {
Janus.debug("Feed " + remoteFeed.rfid + " (" + remoteFeed.rfdisplay + ") has left the room, detaching");
// $('#remote'+remoteFeed.rfindex).empty().hide();
$('#videoremote'+remoteFeed.rfindex).empty();
//document.getElementById('videoremote'+remoteFeed.rfindex).empty();
feeds[remoteFeed.rfindex] = null;
remoteFeed.detach();
}
}
else if(msg["error"] !== undefined && msg["error"] !== null) {
bootbox.alert(msg["error_code" + "error"]);
}
}
}
if(jsep !== undefined && jsep !== null) {
Janus.debug("Handling SDP as well...");
Janus.debug(jsep);
sfutest.handleRemoteJsep({jsep: jsep});
}
},
onlocalstream: function(stream) {
//we don't publish our stream here
},
onremotestream: function(stream) {
// The publisher stream is sendonly, we don't expect anything here
},
oncleanup: function() {
//
}
});
},
error: function(error) {
Janus.error(error);
bootbox.alert(error, function() {
window.location.reload();
});
},
destroyed: function() {
window.location.reload();
}
});
}
});
/////////////////////////////////////////////////////////
function registerUsername() {
var username = "stream";
var register = { "request": "join", "room": myroom, "ptype": "publisher", "display": username };
myusername = username;
sfutest.send({"message": register});
}
//////////////////////////////////////////////////////////
function publishOwnFeed(useAudio) {
// Publish our stream
//$('#publish').attr('disabled', true).unbind('click');
sfutest.createOffer(
{
// Add data:true here if you want to publish datachannels as well
media: { audioRecv: false, videoRecv: false, audioSend: false, videoSend: false }, // Publishers are sendonly
simulcast: doSimulcast,
success: function(jsep) {
Janus.debug("Got publisher SDP!");
Janus.debug(jsep);
var publish = { "request": "configure", "audio": useAudio, "video": true };
sfutest.send({"message": publish, "jsep": jsep});
},
error: function(error) {
Janus.error("WebRTC error:", error);
if (useAudio) {
publishOwnFeed(false);
} else {
bootbox.alert("WebRTC error... " + JSON.stringify(error));
angular.element('#publish').removeAttr('disabled').click(function() { publishOwnFeed(true); });
}
}
});
}
function toggleMute() {
//to mute
}
function unpublishOwnFeed() {
// Unpublish our stream
}
function newRemoteFeed(id, display, audio, video) {
// A new feed has been published, create a new plugin handle and attach to it as a listener
var remoteFeed = null;
janus.attach(
{
plugin: "janus.plugin.videoroom",
opaqueId: opaqueId,
success: function(pluginHandle) {
remoteFeed = pluginHandle;
Janus.log("Plugin attached! (" + remoteFeed.getPlugin() + ", id=" + remoteFeed.getId() + ")");
// We wait for the plugin to send us an offer
var listen = { "request": "join", "room": myroom, "ptype": "listener", "feed": id, "private_id": mypvtid };
// In case you don't want to receive audio, video or data, even if the
// publisher is sending them, set the 'offer_audio', 'offer_video' or
// 'offer_data' properties to false (they're true by default), e.g.:
// listen["offer_video"] = false;
// For example, if the publisher is VP8 and this is Safari, let's avoid video
if(video !== "h264" && Janus.webRTCAdapter.browserDetails.browser === "safari") {
if(video)
video = video.toUpperCase()
toastr.warning("Publisher is using " + video + ", but Safari doesn't support it: disabling video");
listen["offer_video"] = false;
}
remoteFeed.send({"message": listen});
},
error: function(error) {
Janus.error(" -- Error attaching plugin...", error);
bootbox.alert("Error attaching plugin... " + error);
},
onmessage: function(msg, jsep) {
Janus.debug(" ::: Got a message (listener) :::");
Janus.debug(msg);
var event = msg["videoroom"];
Janus.debug("Event: " + event);
if(msg["error"] !== undefined && msg["error"] !== null) {
bootbox.alert(msg["error"]);
}
else if(event != undefined && event != null) {
if(event === "attached") {
// Subscriber created and attached
for(var i=1;i<6;i++) {
if(feeds[i] === undefined || feeds[i] === null) {
feeds[i] = remoteFeed;
remoteFeed.rfindex = i;
break;
}
}
remoteFeed.rfid = msg["id"];
remoteFeed.rfdisplay = msg["display"];
Janus.log("Successfully attached to feed " + remoteFeed.rfid + " (" + remoteFeed.rfdisplay + ") in room " + msg["room"]);
} else if(msg["error"] !== undefined && msg["error"] !== null) {
Janus.error(msg["error"]);
} else {
// What has just happened?
}
}
if(jsep !== undefined && jsep !== null) {
Janus.debug("Handling SDP as well...");
Janus.debug(jsep);
// Answer and attach
remoteFeed.createAnswer(
{
jsep: jsep,
// Add data:true here if you want to subscribe to datachannels as well
// (obviously only works if the publisher offered them in the first place)
media: { audioSend: false, videoSend: false }, // We want recvonly audio/video
success: function(jsep) {
Janus.debug("Got SDP!");
Janus.debug(jsep);
var body = { "request": "start", "room": myroom };
remoteFeed.send({"message": body, "jsep": jsep});
},
error: function(error) {
Janus.error("WebRTC error:", error);
bootbox.alert("WebRTC error... " + JSON.stringify(error));
}
});
}
},
webrtcState: function(on) {
Janus.log("Janus says this WebRTC PeerConnection (feed #" + remoteFeed.rfindex + ") is " + (on ? "up" : "down") + " now");
},
onlocalstream: function(stream) {
// The subscriber stream is recvonly, we don't expect anything here
},
onremotestream: function(stream) {
Janus.debug("Remote feed #" + remoteFeed.rfindex);
if(angular.element('#remotevideo'+remoteFeed.rfindex).length > 0) {
// Been here already: let's see if anything changed
var videoTracks = stream.getVideoTracks();
if(videoTracks && videoTracks.length > 0 && !videoTracks[0].muted) {
$('#novideo'+remoteFeed.rfindex).remove();
if($("#remotevideo"+remoteFeed.rfindex).get(0).videoWidth)
$('#remotevideo'+remoteFeed.rfindex).show();
}
return;
}
// No remote video yet
$('#videoremote'+remoteFeed.rfindex).append('<video class="rounded centered" id="waitingvideo' + remoteFeed.rfindex + '" width=320 height=240 />');
$('#videoremote'+remoteFeed.rfindex).append('<video class="rounded centered relative hide" id="remotevideo' + remoteFeed.rfindex + '" width="100%" height="100%" autoplay/>');
$('#videoremote'+remoteFeed.rfindex).append(
'<span class="label label-primary hide" id="curres'+remoteFeed.rfindex+'" style="position: absolute; bottom: 0px; left: 0px; margin: 15px;"></span>' +
'<span class="label label-info hide" id="curbitrate'+remoteFeed.rfindex+'" style="position: absolute; bottom: 0px; right: 0px; margin: 15px;"></span>');
// Show the video, hide the spinner and show the resolution when we get a playing event
$("#remotevideo"+remoteFeed.rfindex).bind("playing", function () {
if(remoteFeed.spinner !== undefined && remoteFeed.spinner !== null)
remoteFeed.spinner.stop();
remoteFeed.spinner = null;
$('#waitingvideo'+remoteFeed.rfindex).remove();
if(this.videoWidth)
$('#remotevideo'+remoteFeed.rfindex).removeClass('hide').show();
var width = this.videoWidth;
var height = this.videoHeight;
$('#curres'+remoteFeed.rfindex).removeClass('hide').text(width+'x'+height).show();
if(Janus.webRTCAdapter.browserDetails.browser === "firefox") {
// Firefox Stable has a bug: width and height are not immediately available after a playing
setTimeout(function() {
var width = $("#remotevideo"+remoteFeed.rfindex).get(0).videoWidth;
var height = $("#remotevideo"+remoteFeed.rfindex).get(0).videoHeight;
$('#curres'+remoteFeed.rfindex).removeClass('hide').text(width+'x'+height).show();
}, 2000);
}
});
Janus.attachMediaStream($('#remotevideo'+remoteFeed.rfindex).get(0), stream);
var videoTracks = stream.getVideoTracks();
if(videoTracks === null || videoTracks === undefined || videoTracks.length === 0 || videoTracks[0].muted) {
// No remote video
$('#remotevideo'+remoteFeed.rfindex).hide();
$('#videoremote'+remoteFeed.rfindex).append(
'<div id="novideo'+remoteFeed.rfindex+'" class="no-video-container">' +
'<i class="fa fa-video-camera fa-5 no-video-icon" style="height: 100%;"></i>' +
'<span class="no-video-text" style="font-size: 16px;">No remote video available</span>' +
'</div>');
}
if(Janus.webRTCAdapter.browserDetails.browser === "chrome" || Janus.webRTCAdapter.browserDetails.browser === "firefox" ||
Janus.webRTCAdapter.browserDetails.browser === "safari") {
$('#curbitrate'+remoteFeed.rfindex).removeClass('hide').show();
bitrateTimer[remoteFeed.rfindex] = setInterval(function() {
// Display updated bitrate, if supported
var bitrate = remoteFeed.getBitrate();
$('#curbitrate'+remoteFeed.rfindex).text(bitrate);
// Check if the resolution changed too
var width = $("#remotevideo"+remoteFeed.rfindex).get(0).videoWidth;
var height = $("#remotevideo"+remoteFeed.rfindex).get(0).videoHeight;
if(width > 0 && height > 0)
$('#curres'+remoteFeed.rfindex).removeClass('hide').text(width+'x'+height).show();
}, 1000);
}
},
oncleanup: function() {
Janus.log(" ::: Got a cleanup notification (remote feed " + id + ") :::");
if(remoteFeed.spinner !== undefined && remoteFeed.spinner !== null)
remoteFeed.spinner.stop();
remoteFeed.spinner = null;
$('#remotevideo'+remoteFeed.rfindex).remove();
$('#waitingvideo'+remoteFeed.rfindex).remove();
$('#novideo'+remoteFeed.rfindex).remove();
$('#curbitrate'+remoteFeed.rfindex).remove();
$('#curres'+remoteFeed.rfindex).remove();
if(bitrateTimer[remoteFeed.rfindex] !== null && bitrateTimer[remoteFeed.rfindex] !== null)
clearInterval(bitrateTimer[remoteFeed.rfindex]);
bitrateTimer[remoteFeed.rfindex] = null;
remoteFeed.simulcastStarted = false;
$('#simulcast'+remoteFeed.rfindex).remove();
}
});
}
}]);
“严格使用”;
App.controller('janucontroller'、['$scope'、'HomeService'、'uiGridConstants'、“$mdDialog”、函数($scope、HomeService、uiGridConstants、$mdDialog){
var server=null;
如果(window.location.protocol=='http:')
server=“http://“+”192.168.2.10“+”:8088/janus”;
其他的
server=“https://“+”192.168.2.10“+”:8089/janus”;
var-janus=null;
var sfutest=null;
var opaqueId=“videoroomtest-”+Janus.randomString(12);
var=false;
var myroom=1234;//演示室
var myusername=null;
var myid=null;
var mystream=null;
//我们使用另一个ID只是为了将订阅映射到我们
var mypvtid=null;
var提要=[];
var bitrateTimer=[];
var dosismulcast=(getQueryStringValue(“simulcast”)=“否”| getQueryStringValue(“simulcast”)=“假”);
//初始化库(启用所有控制台调试器)
init({debug:“all”,callback:function()){
开始=真;
如果(!Janus.isWebrtcSupported()){
bootbox.alert(“不支持WebRTC…”);
返回;
}
//创建会话
杰纳斯=新杰纳斯(
{
服务器:服务器,
成功:函数(){
//附加到视频室测试插件
janus.附件(
{
plugin:“janus.plugin.videoroom”//插件的唯一包名
opaqueId:opaqueId,//对应用程序有意义的可选不透明字符串
success:function(pluginHandle){//句柄已成功创建,可以使用;
sfutest=插拔手柄;
log(“插件已连接!(“+sfutest.getPlugin()+”,id=“+sfutest.getId()+”));
log(“--这是一个发布者/管理者”);
registerUsername()
angular.element('#start').removeAttr('disabled').html(“Stop”)
。单击(函数(){
$(this.attr('disabled',true);
杰纳斯。摧毁();
});
},
错误:函数(错误){//句柄未成功创建;
Janus.error(“--error attaching plugin…”,error);
警告(“错误附加插件…”+错误);
},
mediaState:功能(中等,打开){
log(“Janus”+(on?)开始“:“停止”)+“接收我们的”+介质);
},
webrtcState:函数(打开){
log(“Janus说我们的WebRTC对等连接是”+(打开?“向上”:“向下”)+“现在”);
//在此处编写代码以更改比特率。
},
onmessage:function(msg,jsep){//从插件接收到消息/事件;
debug(“:::得到一条消息(发布者):”;
Janus.debug(msg);
var事件=消息[“视频室];
调试(事件:+事件);
if(event!=未定义&&event!=null){
如果(事件==“已加入”){
//Publisher/manager已创建、协商WebRTC并附加到现有源(如果有)
myid=msg[“id”];
mypvtid=msg[“private_id”];
Janus.log(“成功加入房间”+msg[“房间”]+”,ID为“+myid”);
publishOwnFeed(false);//不发布视频
//有新的提要要附加到吗?
如果(消息[“发布者”]!==未定义和消息[“发布者”]!==空){
var list=msg[“发布者”];
debug(“获得了可用发布者/提要的列表:”);
调试(列表);
for(列表中的变量f){
变量id=列表[f][“id”];
变量显示=列表[f][“显示”];
var audio=list[f][“audio_codec”];
var video=list[f][“视频编解码器”];
Janus.debug(“>>”[“+id+”)
<td ng-controller="JanusController" ng-show="toggle" ng-repeat="item in peripheralDetails ">
<div class="panel-body relative" id="videoremote_+{{item.perHardwareId}}"></div>
{{item.perHardwareId}}
</td>`
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-6" ng-controller="JanusController" ng-repeat="p in peripheralDetails track by p.perHardwareId">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><span class="glyphicon glyphicon-camera"></span> {{p.perHardwareId}} <span class="label label-info hide" id="remote1"></span></h3>
</div>
<div class="panel-body" id="videoremote_{{p.peripheralId}}">
</div>
<div class="panel-footer">
<button id="startButton" class="btn btn-success" type="submit" ng-click="peripheralRequest(p.device.devHardwareId,p.perHardwareId,'Start')">Start</button>
<button id="stopButton" class = "btn btn-danger" type="submit" ng-click="peripheralRequest(p.device.devHardwareId,p.perHardwareId,'Stop')">Stop</button>
</div>
</div>
</div>
</div>