我正在使用webRCT项目。我正在使用Janus webRtc网关视频室功能和RestAPI + Mysql数据库来处理相机细节,AngularJs用于流式传输视频和客户端应用程序来捕获视频。
我创建了一个HomeController.js来处理相机细节。和janusController.js来处理流媒体视频。
现在在目前的情况下,我可以从单个摄像头流式传输视频。如果我手动在html5页面中创建多个div,则还支持多个摄像头。但这不是我想要做的。我想在htlm5页面中使用angularJs“ng-repeat”创建div,我想为每个div提供唯一的Id。
我的重要部分是我的代码。
HomeController.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')
);
});
}
上述电话的回应。
[{"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"}}]
JanusController.js
'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();
}
});
}
}]);
来自home.html的
<td ng-controller="JanusController" ng-show="toggle">
<div class="panel-body relative" id="videoremote1"></div>
{{$parent.p.perHardwareId}}
</td>
我是这些所有技术的新手,这是我的大学项目。我必须在本周内证明这一点。所以我需要专家的帮助。
如果我使用这个div,那么它会创建一个具有periticular外围id的div。
<td ng-controller="JanusController" ng-show="toggle">
<div class="panel-body relative" id="videoremote" ng-attr-id="{{$parent.p.perHardwareId}}"></div>
{{$parent.p.perHardwareId}}
</td>
这是janus.js文件https://github.com/meetecho/janus-gateway/blob/master/html/janus.js
答案 0 :(得分:1)
如果home.html代码适合您,那么您可以使用ng-repeat
循环它<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>`
您可以使用videoremote_{{perHardwareId}}
例如,如果您的peripheralId is 7
,则元素ID将为videoremote_7
答案 1 :(得分:0)
这对我来说是个问题。
<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>
我已将JanusController.js中的流ID设置为与id="videoremote_{{p.peripheralId}}
相同。