Merge branch 'master' into multistream
This commit is contained in:
commit
3835087c9d
|
@ -3,7 +3,7 @@
|
|||
module.exports = {
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true,
|
||||
"es2017": true,
|
||||
},
|
||||
"extends": ["google"],
|
||||
"overrides": [{
|
||||
|
|
|
@ -321,7 +321,7 @@ if(NOT ZM_NO_CURL)
|
|||
find_package(CURL)
|
||||
if(CURL_FOUND)
|
||||
set(HAVE_LIBCURL 1)
|
||||
#list(APPEND ZM_BIN_LIBS ${CURL_LIBRARIES})
|
||||
list(APPEND ZM_BIN_LIBS ${CURL_LIBRARIES})
|
||||
include_directories(${CURL_INCLUDE_DIRS})
|
||||
set(CMAKE_REQUIRED_INCLUDES ${CURL_INCLUDE_DIRS})
|
||||
check_include_file("curl/curl.h" HAVE_CURL_CURL_H)
|
||||
|
|
|
@ -4,7 +4,6 @@ ZoneMinder
|
|||
[![Build Status](https://travis-ci.org/ZoneMinder/zoneminder.png)](https://travis-ci.org/ZoneMinder/zoneminder)
|
||||
[![Bounty Source](https://api.bountysource.com/badge/team?team_id=204&style=bounties_received)](https://www.bountysource.com/teams/zoneminder/issues?utm_source=ZoneMinder&utm_medium=shield&utm_campaign=bounties_received)
|
||||
[![Join Slack](https://github.com/ozonesecurity/ozonebase/blob/master/img/slacksm.png?raw=true)](https://join.slack.com/t/zoneminder-chat/shared_invite/enQtNTU0NDkxMDM5NDQwLTdhZmQ5Y2M2NWQyN2JkYTBiN2ZkMzIzZGQ0MDliMTRmM2FjZWRlYzUwYTQ2MjMwMTVjMzQ1NjYxOTdmMjE2MTE)
|
||||
[![IRC Network](https://img.shields.io/badge/irc-%23zoneminder-blue.svg "IRC Freenode")](https://webchat.freenode.net/?channels=zoneminder)
|
||||
|
||||
All documentation for ZoneMinder is now online at https://zoneminder.readthedocs.org
|
||||
|
||||
|
|
|
@ -459,6 +459,7 @@ CREATE TABLE `Monitors` (
|
|||
`Recording` enum('None', 'OnMotion', 'Always') NOT NULL default 'Always',
|
||||
`Enabled` tinyint(3) unsigned NOT NULL default '1',
|
||||
`DecodingEnabled` tinyint(3) unsigned NOT NULL default '1',
|
||||
`JanusEnabled` BOOLEAN NOT NULL default false,
|
||||
`LinkedMonitors` varchar(255),
|
||||
`Triggers` set('X10') NOT NULL default '',
|
||||
`EventStartCommand` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
--
|
||||
-- Update Monitors table to have JanusEnabled
|
||||
--
|
||||
|
||||
SELECT 'Checking for JanusEnabled in Monitors';
|
||||
SET @s = (SELECT IF(
|
||||
(SELECT COUNT(*)
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE table_name = 'Monitors'
|
||||
AND table_schema = DATABASE()
|
||||
AND column_name = 'JanusEnabled'
|
||||
) > 0,
|
||||
"SELECT 'Column JanusEnabled already exists in Monitors'",
|
||||
"ALTER TABLE `Monitors` ADD COLUMN `JanusEnabled` BOOLEAN NOT NULL default false AFTER `DecodingEnabled`"
|
||||
));
|
||||
|
||||
PREPARE stmt FROM @s;
|
||||
EXECUTE stmt;
|
|
@ -0,0 +1,50 @@
|
|||
general: {
|
||||
configs_folder = "/usr/local/etc/janus" # Configuration files folder
|
||||
plugins_folder = "/usr/local/lib/janus/plugins" # Plugins folder
|
||||
transports_folder = "/usr/local/lib/janus/transports" # Transports folder
|
||||
events_folder = "/usr/local/lib/janus/events" # Event handlers folder
|
||||
loggers_folder = "/usr/local/lib/janus/loggers" # External loggers folder
|
||||
debug_level = 4 # Debug/logging level, valid values are 0-7
|
||||
admin_secret = "janusoverlord" # String that all Janus requests must contain
|
||||
protected_folders = [
|
||||
"/bin",
|
||||
"/boot",
|
||||
"/dev",
|
||||
"/etc",
|
||||
"/initrd",
|
||||
"/lib",
|
||||
"/lib32",
|
||||
"/lib64",
|
||||
"/proc",
|
||||
"/sbin",
|
||||
"/sys",
|
||||
"/usr",
|
||||
"/var",
|
||||
"/opt/janus/bin",
|
||||
"/opt/janus/etc",
|
||||
"/opt/janus/include",
|
||||
"/opt/janus/lib",
|
||||
"/opt/janus/lib32",
|
||||
"/opt/janus/lib64",
|
||||
"/opt/janus/sbin"
|
||||
]
|
||||
}
|
||||
media: {
|
||||
#ipv6 = true
|
||||
#ipv6_linklocal = true
|
||||
rtp_port_range = "20000-40000"
|
||||
}
|
||||
nat: {
|
||||
nice_debug = false
|
||||
ignore_mdns = true
|
||||
keep_private_host = true
|
||||
ice_ignore_list = "vmnet"
|
||||
}
|
||||
|
||||
plugins: {
|
||||
disable = "libjanus_audiobridge.so,libjanus_echotest.so,libjanus_recordplay.so,libjanus_sip.so,libjanus_textroom.so,libjanus_videocall.so,libjanus_videoroom.so,libjanus_voicemail.so,
|
||||
libjanus_nosip.so"
|
||||
}
|
||||
transports: {
|
||||
disable = "libjanus_rabbitmq.so, libjanus_pfunix.so,libjanus_websockets.so"
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
general: {
|
||||
admin_key = "supersecret"
|
||||
rtp_port_range = "20000-40000"
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
general: {
|
||||
json = "indented" # Whether the JSON messages should be indented (default),
|
||||
base_path = "/janus" # Base path to bind to in the web server (plain HTTP only)
|
||||
http = true # Whether to enable the plain HTTP interface
|
||||
port = 8088 # Web server HTTP port
|
||||
https = false # Whether to enable HTTPS (default=false)
|
||||
}
|
||||
|
||||
# Janus can also expose an admin/monitor endpoint, to allow you to check
|
||||
# which sessions are up, which handles they're managing, their current
|
||||
# status and so on. This provides a useful aid when debugging potential
|
||||
# issues in Janus. The configuration is pretty much the same as the one
|
||||
# already presented above for the webserver stuff, as the API is very
|
||||
# similar: choose the base bath for the admin/monitor endpoint (/admin
|
||||
# by default), ports, etc. Besides, you can specify
|
||||
# a secret that must be provided in all requests as a crude form of
|
||||
# authorization mechanism, and partial or full source IPs if you want to
|
||||
# limit access basing on IP addresses. For security reasons, this
|
||||
# endpoint is disabled by default, enable it by setting admin_http=true.
|
||||
admin: {
|
||||
admin_base_path = "/admin" # Base path to bind to in the admin/monitor web server (plain HTTP only)
|
||||
admin_http = false # Whether to enable the plain HTTP interface
|
||||
admin_port = 7088 # Admin/monitor web server HTTP port
|
||||
admin_https = false # Whether to enable HTTPS (default=false)
|
||||
}
|
|
@ -132,6 +132,7 @@ class Event {
|
|||
|
||||
SystemTimePoint StartTime() const { return start_time; }
|
||||
SystemTimePoint EndTime() const { return end_time; }
|
||||
TimePoint::duration Duration() const { return end_time - start_time; };
|
||||
|
||||
void AddPacket(const std::shared_ptr<ZMPacket> &p);
|
||||
void AddPacket_(const std::shared_ptr<ZMPacket> &p);
|
||||
|
@ -178,18 +179,6 @@ class Event {
|
|||
return pre_alarm_count;
|
||||
}
|
||||
static void EmptyPreAlarmFrames() {
|
||||
#if 0
|
||||
while ( pre_alarm_count > 0 ) {
|
||||
int i = pre_alarm_count - 1;
|
||||
delete pre_alarm_data[i].image;
|
||||
pre_alarm_data[i].image = nullptr;
|
||||
if ( pre_alarm_data[i].alarm_frame ) {
|
||||
delete pre_alarm_data[i].alarm_frame;
|
||||
pre_alarm_data[i].alarm_frame = nullptr;
|
||||
}
|
||||
pre_alarm_count--;
|
||||
}
|
||||
#endif
|
||||
pre_alarm_count = 0;
|
||||
}
|
||||
static void AddPreAlarmFrame(
|
||||
|
@ -198,28 +187,10 @@ class Event {
|
|||
int score=0,
|
||||
Image *alarm_frame=nullptr
|
||||
) {
|
||||
#if 0
|
||||
pre_alarm_data[pre_alarm_count].image = new Image(*image);
|
||||
pre_alarm_data[pre_alarm_count].timestamp = timestamp;
|
||||
pre_alarm_data[pre_alarm_count].score = score;
|
||||
if ( alarm_frame ) {
|
||||
pre_alarm_data[pre_alarm_count].alarm_frame = new Image(*alarm_frame);
|
||||
}
|
||||
#endif
|
||||
pre_alarm_count++;
|
||||
}
|
||||
void SavePreAlarmFrames() {
|
||||
#if 0
|
||||
for ( int i = 0; i < pre_alarm_count; i++ ) {
|
||||
AddFrame(
|
||||
pre_alarm_data[i].image,
|
||||
pre_alarm_data[i].timestamp,
|
||||
pre_alarm_data[i].score,
|
||||
pre_alarm_data[i].alarm_frame);
|
||||
}
|
||||
#endif
|
||||
EmptyPreAlarmFrames();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // ZM_EVENT_H
|
||||
|
|
|
@ -1126,7 +1126,8 @@ bool EventStream::send_file(const std::string &filepath) {
|
|||
} else {
|
||||
Debug(1, "Failed to sendfile?");
|
||||
}
|
||||
Warning("Unable to send raw frame %ld: %s rc %d", curr_frame_id, strerror(errno), rc);
|
||||
Warning("Unable to send raw frame %ld: %s rc %d != %d",
|
||||
curr_frame_id, strerror(errno), rc, (int)filestat.st_size);
|
||||
#endif
|
||||
|
||||
static unsigned char temp_img_buffer[ZM_MAX_IMAGE_SIZE];
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -34,6 +34,7 @@
|
|||
#include <memory>
|
||||
#include <sys/time.h>
|
||||
#include <vector>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#ifdef WITH_GSOAP
|
||||
#include "soapPullPointSubscriptionBindingProxy.h"
|
||||
|
@ -47,6 +48,7 @@ class Group;
|
|||
#define MOTION_CAUSE "Motion"
|
||||
#define LINKED_CAUSE "Linked"
|
||||
|
||||
|
||||
//
|
||||
// This is the main class for monitors. Each monitor is associated
|
||||
// with a camera and is effectively a collector for events.
|
||||
|
@ -305,6 +307,7 @@ protected:
|
|||
RecordingSourceOption recording_source; // Primary, Secondary, Both
|
||||
|
||||
bool decoding_enabled; // Whether the monitor will decode h264/h265 packets
|
||||
bool janus_enabled; // Whether we set the h264/h265 stream up on janus
|
||||
|
||||
std::string protocol;
|
||||
std::string method;
|
||||
|
@ -485,6 +488,13 @@ protected:
|
|||
void set_credentials(struct soap *soap);
|
||||
#endif
|
||||
|
||||
//curl stuff for Janus
|
||||
CURL *curl;
|
||||
//helper class for CURL
|
||||
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp);
|
||||
int add_to_janus();
|
||||
int remove_from_janus();
|
||||
|
||||
// Used in check signal
|
||||
uint8_t red_val;
|
||||
uint8_t green_val;
|
||||
|
|
|
@ -69,6 +69,16 @@ if ( !canEdit('Monitors') ) return;
|
|||
}
|
||||
?>
|
||||
|
||||
</div>
|
||||
<div class="form-group" id="FunctionJanusEnabled">
|
||||
<label for="newJanusEnabled"><?php echo translate('Janus Enabled') ?></label>
|
||||
<input type="checkbox" name="newJanusEnabled" id="newJanusEnabled" value="1"/>
|
||||
<?php
|
||||
if ( isset($OLANG['FUNCTION_JANUS_ENABLED']) ) {
|
||||
echo '<div class="form-text">'.$OLANG['FUNCTION_JANUS_ENABLED']['Help'].'</div>';
|
||||
}
|
||||
?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
|
|
@ -116,6 +116,7 @@ class Monitor extends ZM_Object {
|
|||
'Recording' => 'Always',
|
||||
'Enabled' => array('type'=>'boolean','default'=>1),
|
||||
'DecodingEnabled' => array('type'=>'boolean','default'=>1),
|
||||
'JanusEnabled' => array('type'=>'boolean','default'=>0),
|
||||
'LinkedMonitors' => array('type'=>'set', 'default'=>null),
|
||||
'Triggers' => array('type'=>'set','default'=>''),
|
||||
'EventStartCommand' => '',
|
||||
|
|
|
@ -2094,6 +2094,8 @@ function getStreamHTML($monitor, $options = array()) {
|
|||
'format' => ZM_MPEG_LIVE_FORMAT
|
||||
) );
|
||||
return getVideoStreamHTML( 'liveStream'.$monitor->Id(), $streamSrc, $options['width'], $options['height'], ZM_MPEG_LIVE_FORMAT, $monitor->Name() );
|
||||
} else if ( $monitor->JanusEnabled() ) {
|
||||
return '<video id="liveStream'.$monitor->Id().'" width="'.$options['width'].'"autoplay muted playsinline=""></video>';
|
||||
} else if ( $options['mode'] == 'stream' and canStream() ) {
|
||||
$options['mode'] = 'jpeg';
|
||||
$streamSrc = $monitor->getStreamSrc($options);
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -1124,6 +1124,11 @@ Always: A zmc process will run and immediately connect and stay connected.~~~~
|
|||
optionally choose to not decode the H264/H265 packets. This will drastically reduce cpu use
|
||||
but will make live view unavailable for this monitor.'
|
||||
),
|
||||
'FUNCTION_JANUS_ENABLED' => array(
|
||||
'Help' => '
|
||||
Attempt to use Janus streaming server for h264/h265 live view. Experimental, but allows
|
||||
for significantly better performance.'
|
||||
),
|
||||
'ImageBufferCount' => array(
|
||||
'Help' => '
|
||||
Number of raw images available in /dev/shm. Currently should be set in the 3-5 range. Used for live viewing.'
|
||||
|
|
|
@ -192,4 +192,6 @@ xhtmlHeaders(__FILE__, translate('CycleWatch'));
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="<?php echo cache_bust('js/adapter.min.js') ?>"></script>
|
||||
<script src="<?php echo cache_bust('js/janus.js') ?>"></script>
|
||||
<?php xhtmlFooter() ?>
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
var server;
|
||||
var janus = null;
|
||||
var streaming2;
|
||||
var intervalId;
|
||||
var pauseBtn = $j('#pauseBtn');
|
||||
var playBtn = $j('#playBtn');
|
||||
|
@ -46,6 +49,69 @@ function initCycle() {
|
|||
intervalId = setInterval(nextCycleView, cycleRefreshTimeout);
|
||||
var scale = $j('#scale').val();
|
||||
if ( scale == '0' || scale == 'auto' ) changeScale();
|
||||
|
||||
if (monitorData[monIdx].janusEnabled) {
|
||||
server = "http://" + window.location.hostname + ":8088/janus";
|
||||
opaqueId = "streamingtest-"+Janus.randomString(12);
|
||||
Janus.init({debug: "all", callback: function() {
|
||||
janus = new Janus({
|
||||
server: server,
|
||||
success: function() {
|
||||
janus.attach({
|
||||
plugin: "janus.plugin.streaming",
|
||||
opaqueId: opaqueId,
|
||||
success: function(pluginHandle) {
|
||||
streaming2 = pluginHandle;
|
||||
var body = {"request": "watch", "id": monitorData[monIdx].id};
|
||||
streaming2.send({"message": body});
|
||||
},
|
||||
error: function(error) {
|
||||
Janus.error(" -- Error attaching plugin... ", error);
|
||||
},
|
||||
onmessage: function(msg, jsep) {
|
||||
Janus.debug(" ::: Got a message :::");
|
||||
Janus.debug(msg);
|
||||
var result = msg["result"];
|
||||
if (result !== null && result !== undefined) {
|
||||
if (result["status"] !== undefined && result["status"] !== null) {
|
||||
const status = result["status"];
|
||||
console.log(status);
|
||||
}
|
||||
} else if (msg["error"] !== undefined && msg["error"] !== null) {
|
||||
Janus.debug(msg["error"]);
|
||||
return;
|
||||
}
|
||||
if (jsep !== undefined && jsep !== null) {
|
||||
Janus.debug("Handling SDP as well...");
|
||||
Janus.debug(jsep);
|
||||
// Offer from the plugin, let's answer
|
||||
streaming2.createAnswer({
|
||||
jsep: jsep,
|
||||
// We want recvonly audio/video and, if negotiated, datachannels
|
||||
media: {audioSend: false, videoSend: false, data: true},
|
||||
success: function(jsep) {
|
||||
Janus.debug("Got SDP!");
|
||||
Janus.debug(jsep);
|
||||
var body = {"request": "start"};
|
||||
streaming2.send({"message": body, "jsep": jsep});
|
||||
},
|
||||
error: function(error) {
|
||||
Janus.error("WebRTC error:", error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, //onmessage function
|
||||
onremotestream: function(stream) {
|
||||
Janus.debug(" ::: Got a remote track :::");
|
||||
Janus.debug(stream);
|
||||
Janus.attachMediaStream(document.getElementById("liveStream" + monitorData[monIdx].id), stream);
|
||||
document.getElementById("liveStream" + monitorData[monIdx].id).play();
|
||||
}
|
||||
});// attach
|
||||
} //Success functio
|
||||
}); //new Janus
|
||||
}}); //janus.init callback
|
||||
} //if janus
|
||||
}
|
||||
|
||||
function changeSize() {
|
||||
|
|
|
@ -20,7 +20,8 @@ monitorData[monitorData.length] = {
|
|||
'url': '<?php echo $monitor->UrlToIndex() ?>',
|
||||
'onclick': function(){window.location.assign( '?view=watch&mid=<?php echo $monitor->Id() ?>' );},
|
||||
'type': '<?php echo $monitor->Type() ?>',
|
||||
'refresh': '<?php echo $monitor->Refresh() ?>'
|
||||
'refresh': '<?php echo $monitor->Refresh() ?>',
|
||||
'janusEnabled': <?php echo $monitor->JanusEnabled() ?>
|
||||
};
|
||||
<?php
|
||||
} // end foreach monitor
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
var server;
|
||||
var janus = null;
|
||||
var opaqueId;
|
||||
var globalCount = 0;
|
||||
var streamingList = [];
|
||||
var janusMonitors = [];
|
||||
/**
|
||||
* called when the layoutControl select element is changed, or the page
|
||||
* is rendered
|
||||
|
@ -300,20 +306,43 @@ function initPage() {
|
|||
$j("#flipMontageHeader").slideToggle("fast");
|
||||
$j("#hdrbutton").toggleClass('glyphicon-menu-down').toggleClass('glyphicon-menu-up');
|
||||
}
|
||||
|
||||
var initJanus = false;
|
||||
//var streamingMonitors = [];
|
||||
for ( var i = 0, length = monitorData.length; i < length; i++ ) {
|
||||
monitors[i] = new MonitorStream(monitorData[i]);
|
||||
|
||||
// Start the fps and status updates. give a random delay so that we don't assault the server
|
||||
var delay = Math.round( (Math.random()+0.5)*statusRefreshTimeout );
|
||||
console.log("delay: " + delay);
|
||||
monitors[i].start(delay);
|
||||
|
||||
var interval = monitors[i].refresh;
|
||||
if ( monitors[i].type == 'WebSite' && interval > 0 ) {
|
||||
setInterval(reloadWebSite, interval*1000, i);
|
||||
if (monitorData[i].janusEnabled) {
|
||||
initJanus = true;
|
||||
janusMonitors.push(monitorData[i]);
|
||||
}
|
||||
}
|
||||
if (initJanus) {
|
||||
server = "http://" + window.location.hostname + ":8088/janus";
|
||||
opaqueId = "streamingtest-"+Janus.randomString(12);
|
||||
Janus.init({debug: "all", callback: function() {
|
||||
janus = new Janus({
|
||||
server: server,
|
||||
success: function() {
|
||||
for ( var i = 0, length = janusMonitors.length; i < length; i++ ) {
|
||||
attachVideo(janus, i);
|
||||
}
|
||||
}
|
||||
});
|
||||
}});
|
||||
}
|
||||
for ( var i = 0, length = monitorData.length; i < length; i++ ) {
|
||||
if (!monitorData[i].janusEnabled) {
|
||||
monitors[i] = new MonitorStream(monitorData[i]);
|
||||
|
||||
// Start the fps and status updates. give a random delay so that we don't assault the server
|
||||
var delay = Math.round( (Math.random()+0.5)*statusRefreshTimeout );
|
||||
console.log("delay: " + delay);
|
||||
monitors[i].start(delay);
|
||||
|
||||
var interval = monitors[i].refresh;
|
||||
if ( monitors[i].type == 'WebSite' && interval > 0 ) {
|
||||
setInterval(reloadWebSite, interval*1000, i);
|
||||
}
|
||||
monitors[i].setup_onclick();
|
||||
}
|
||||
monitors[i].setup_onclick();
|
||||
}
|
||||
selectLayout('#zmMontageLayout');
|
||||
}
|
||||
|
@ -322,5 +351,59 @@ function watchFullscreen() {
|
|||
const content = document.getElementById('content');
|
||||
openFullscreen(content);
|
||||
}
|
||||
|
||||
function attachVideo(janus, i) {
|
||||
janus.attach({
|
||||
plugin: "janus.plugin.streaming",
|
||||
opaqueId: "streamingtest-"+Janus.randomString(12),
|
||||
success: function(pluginHandle) {
|
||||
janusMonitors[i].streaming = pluginHandle;
|
||||
var body = {"request": "watch", "id": parseInt(janusMonitors[i].id)};
|
||||
janusMonitors[i].streaming.send({"message": body});
|
||||
},
|
||||
error: function(error) {
|
||||
Janus.error(" -- Error attaching plugin... ", error);
|
||||
},
|
||||
onmessage: function(msg, jsep) {
|
||||
Janus.debug(" ::: Got a message :::");
|
||||
Janus.debug(msg);
|
||||
var result = msg["result"];
|
||||
if (result !== null && result !== undefined) {
|
||||
if (result["status"] !== undefined && result["status"] !== null) {
|
||||
const status = result["status"];
|
||||
console.log(status);
|
||||
}
|
||||
} else if (msg["error"] !== undefined && msg["error"] !== null) {
|
||||
Janus.error(msg["error"]);
|
||||
return;
|
||||
}
|
||||
if (jsep !== undefined && jsep !== null) {
|
||||
Janus.debug("Handling SDP as well...");
|
||||
Janus.debug(jsep);
|
||||
// Offer from the plugin, let's answer
|
||||
janusMonitors[i].streaming.createAnswer({
|
||||
jsep: jsep,
|
||||
// We want recvonly audio/video and, if negotiated, datachannels
|
||||
media: {audioSend: false, videoSend: false, data: true},
|
||||
success: function(jsep) {
|
||||
Janus.debug("Got SDP!");
|
||||
Janus.debug(jsep);
|
||||
var body = {"request": "start"};
|
||||
janusMonitors[i].streaming.send({"message": body, "jsep": jsep});
|
||||
},
|
||||
error: function(error) {
|
||||
Janus.error("WebRTC error:", error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, //onmessage function
|
||||
onremotestream: function(ourstream) {
|
||||
Janus.debug(" ::: Got a remote track :::");
|
||||
Janus.debug(ourstream);
|
||||
Janus.attachMediaStream(document.getElementById("liveStream" + janusMonitors[i].id), ourstream);
|
||||
document.getElementById("liveStream" + janusMonitors[i].id).play();
|
||||
}
|
||||
});// attach
|
||||
}
|
||||
// Kick everything off
|
||||
$j(document).ready(initPage);
|
||||
|
|
|
@ -24,6 +24,7 @@ monitorData[monitorData.length] = {
|
|||
'connKey': <?php echo $monitor->connKey() ?>,
|
||||
'width': <?php echo $monitor->ViewWidth() ?>,
|
||||
'height':<?php echo $monitor->ViewHeight() ?>,
|
||||
'janusEnabled':<?php echo $monitor->JanusEnabled() ?>,
|
||||
'url': '<?php echo $monitor->UrlToIndex( ZM_MIN_STREAMING_PORT ? ($monitor->Id() + ZM_MIN_STREAMING_PORT) : '') ?>',
|
||||
'onclick': function(){window.location.assign( '?view=watch&mid=<?php echo $monitor->Id() ?>' );},
|
||||
'type': '<?php echo $monitor->Type() ?>',
|
||||
|
|
|
@ -9,6 +9,10 @@ var forceAlmBtn = $j('#forceAlmBtn');
|
|||
var table = $j('#eventList');
|
||||
var filterQuery = '&filter[Query][terms][0][attr]=MonitorId&filter[Query][terms][0][op]=%3d&filter[Query][terms][0][val]='+monitorId;
|
||||
|
||||
var server;
|
||||
var janus = null;
|
||||
var opaqueId;
|
||||
var streaming2;
|
||||
/*
|
||||
This is the format of the json object sent by bootstrap-table
|
||||
|
||||
|
@ -899,15 +903,77 @@ function initPage() {
|
|||
}
|
||||
|
||||
if (monitorType != 'WebSite') {
|
||||
if (streamMode == 'single') {
|
||||
statusCmdTimer = setTimeout(statusCmdQuery, 200);
|
||||
setInterval(watchdogCheck, statusRefreshTimeout*2, 'status');
|
||||
} else {
|
||||
streamCmdTimer = setTimeout(streamCmdQuery, 200);
|
||||
setInterval(watchdogCheck, statusRefreshTimeout*2, 'stream');
|
||||
if (streamMode != 'janus') {
|
||||
if (streamMode == 'single') {
|
||||
statusCmdTimer = setTimeout(statusCmdQuery, 200);
|
||||
setInterval(watchdogCheck, statusRefreshTimeout*2, 'status');
|
||||
} else {
|
||||
streamCmdTimer = setTimeout(streamCmdQuery, 200);
|
||||
setInterval(watchdogCheck, statusRefreshTimeout*2, 'stream');
|
||||
}
|
||||
}
|
||||
|
||||
if (canStreamNative || (streamMode == 'single')) {
|
||||
if (streamMode == 'janus') {
|
||||
server = "http://" + window.location.hostname + ":8088/janus";
|
||||
opaqueId = "streamingtest-"+Janus.randomString(12);
|
||||
Janus.init({debug: "all", callback: function() {
|
||||
janus = new Janus({
|
||||
server: server,
|
||||
success: function() {
|
||||
janus.attach({
|
||||
plugin: "janus.plugin.streaming",
|
||||
opaqueId: opaqueId,
|
||||
success: function(pluginHandle) {
|
||||
streaming2 = pluginHandle;
|
||||
var body = {"request": "watch", "id": monitorId};
|
||||
streaming2.send({"message": body});
|
||||
},
|
||||
error: function(error) {
|
||||
Janus.error(" -- Error attaching plugin... ", error);
|
||||
},
|
||||
onmessage: function(msg, jsep) {
|
||||
Janus.debug(" ::: Got a message :::");
|
||||
Janus.debug(msg);
|
||||
var result = msg["result"];
|
||||
if (result !== null && result !== undefined) {
|
||||
if (result["status"] !== undefined && result["status"] !== null) {
|
||||
var status = result["status"];
|
||||
console.log(status);
|
||||
}
|
||||
} else if (msg["error"] !== undefined && msg["error"] !== null) {
|
||||
Janus.error(msg["error"]);
|
||||
return;
|
||||
}
|
||||
if (jsep !== undefined && jsep !== null) {
|
||||
Janus.debug("Handling SDP as well...");
|
||||
Janus.debug(jsep);
|
||||
// Offer from the plugin, let's answer
|
||||
streaming2.createAnswer({
|
||||
jsep: jsep,
|
||||
// We want recvonly audio/video and, if negotiated, datachannels
|
||||
media: {audioSend: false, videoSend: false, data: true},
|
||||
success: function(jsep) {
|
||||
Janus.debug("Got SDP!");
|
||||
Janus.debug(jsep);
|
||||
var body = {"request": "start"};
|
||||
streaming2.send({"message": body, "jsep": jsep});
|
||||
},
|
||||
error: function(error) {
|
||||
Janus.error("WebRTC error:", error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, //onmessage function
|
||||
onremotestream: function(stream) {
|
||||
Janus.debug(" ::: Got a remote track :::");
|
||||
Janus.debug(stream);
|
||||
Janus.attachMediaStream(document.getElementById("liveStream" + monitorId), stream);
|
||||
document.getElementById("liveStream" + monitorId).play();
|
||||
}
|
||||
}); // attach
|
||||
} //Success functio
|
||||
}); //new Janus
|
||||
}}); //janus.init callback
|
||||
} else if (canStreamNative || (streamMode == 'single')) {
|
||||
var streamImg = $j('#imageFeed img');
|
||||
if (!streamImg) streamImg = $j('#imageFeed object');
|
||||
if (!streamImg) {
|
||||
|
|
|
@ -66,6 +66,7 @@ monitorData[monitorData.length] = {
|
|||
'id': <?php echo $m->Id() ?>,
|
||||
'width': <?php echo $m->ViewWidth() ?>,
|
||||
'height':<?php echo $m->ViewHeight() ?>,
|
||||
'janusEnabled':<?php echo $m->JanusEnabled() ?>,
|
||||
'url': '<?php echo $m->UrlToIndex() ?>',
|
||||
'onclick': function(){window.location.assign( '?view=watch&mid=<?php echo $m->Id() ?>' );},
|
||||
'type': '<?php echo $m->Type() ?>',
|
||||
|
|
|
@ -1279,6 +1279,16 @@ echo htmlSelect('newMonitor[ReturnLocation]', $return_options, $monitor->ReturnL
|
|||
<?php echo translate('frames')?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="FunctionJanusEnabled">
|
||||
<td class="text-right pr-3"><?php echo translate('Janus Live Stream') ?></td>
|
||||
<td><input type="checkbox" name="newMonitor[JanusEnabled]" value="1"<?php echo $monitor->JanusEnabled() ? ' checked="checked"' : '' ?>/>
|
||||
<?php
|
||||
if ( isset($OLANG['FUNCTION_JANUS_ENABLED']) ) {
|
||||
echo '<div class="form-text">'.$OLANG['FUNCTION_JANUS_ENABLED']['Help'].'</div>';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-right pr-3"><?php echo translate('DefaultRate') ?></td>
|
||||
<td><?php echo htmlSelect('newMonitor[DefaultRate]', $rates, $monitor->DefaultRate()); ?></td>
|
||||
|
|
|
@ -325,5 +325,7 @@ foreach (array_reverse($zones) as $zone) {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="<?php echo cache_bust('js/adapter.min.js') ?>"></script>
|
||||
<script src="<?php echo cache_bust('js/janus.js') ?>"></script>
|
||||
<script src="<?php echo cache_bust('js/MonitorStream.js') ?>"></script>
|
||||
<?php xhtmlFooter() ?>
|
||||
|
|
|
@ -135,7 +135,11 @@ if (isset($_REQUEST['height'])) {
|
|||
}
|
||||
|
||||
$connkey = generateConnKey();
|
||||
$streamMode = getStreamMode();
|
||||
if ( $monitor->JanusEnabled() ) {
|
||||
$streamMode = 'janus';
|
||||
} else {
|
||||
$streamMode = getStreamMode();
|
||||
}
|
||||
|
||||
noCacheHeaders();
|
||||
xhtmlHeaders(__FILE__, $monitor->Name().' - '.translate('Feed'));
|
||||
|
@ -407,4 +411,6 @@ if ( ZM_WEB_SOUND_ON_ALARM ) {
|
|||
?>
|
||||
</div>
|
||||
</div>
|
||||
<script src="<?php echo cache_bust('js/adapter.min.js') ?>"></script>
|
||||
<script src="<?php echo cache_bust('js/janus.js') ?>"></script>
|
||||
<?php xhtmlFooter() ?>
|
||||
|
|
Loading…
Reference in New Issue