Adds Janus options Profile-ID Override and Use RTSP Restream to work around camera issues
parent
cad80eb37d
commit
d41792ae00
|
|
@ -465,6 +465,8 @@ CREATE TABLE `Monitors` (
|
|||
`Decoding` enum('None','Ondemand','KeyFrames','KeyFrames+Ondemand', 'Always') NOT NULL default 'Always',
|
||||
`JanusEnabled` BOOLEAN NOT NULL default false,
|
||||
`JanusAudioEnabled` BOOLEAN NOT NULL default false,
|
||||
`Janus_Profile_Override` VARCHAR(30) NOT NULL DEFAULT '',
|
||||
`Janus_Use_RTSP_Restream` BOOLEAN NOT NULL default false,
|
||||
`LinkedMonitors` varchar(255),
|
||||
`Triggers` set('X10') NOT NULL default '',
|
||||
`EventStartCommand` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
--
|
||||
-- Update Monitors Table to include Janus_Profile_Override
|
||||
--
|
||||
|
||||
SELECT 'Checking for Janus_Profile_Override in Monitors';
|
||||
SET @s = (SELECT IF(
|
||||
(SELECT COUNT(*)
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE table_name = 'Monitors'
|
||||
AND table_schema = DATABASE()
|
||||
AND column_name = 'Janus_Profile_Override'
|
||||
) > 0,
|
||||
"SELECT 'Column Janus_Profile_Override already exists in Monitors'",
|
||||
"ALTER TABLE Monitors ADD Janus_Profile_Override varchar(30) DEFAULT '' AFTER `JanusAudioEnabled`"
|
||||
));
|
||||
|
||||
PREPARE stmt FROM @s;
|
||||
EXECUTE stmt;
|
||||
|
||||
--
|
||||
-- Update Monitors Table to include Janus_Use_RTSP_Restream
|
||||
--
|
||||
|
||||
SELECT 'Checking for Janus_Use_RTSP_Restream in Monitors';
|
||||
SET @s = (SELECT IF(
|
||||
(SELECT COUNT(*)
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE table_name = 'Monitors'
|
||||
AND table_schema = DATABASE()
|
||||
AND column_name = 'Janus_Use_RTSP_Restream'
|
||||
) > 0,
|
||||
"SELECT 'Column Janus_Use_RTSP_Restream already exists in Monitors'",
|
||||
"ALTER TABLE Monitors ADD Janus_Use_RTSP_Restream BOOLEAN NOT NULL DEFAULT false AFTER `Janus_Profile_Override`"
|
||||
));
|
||||
|
||||
PREPARE stmt FROM @s;
|
||||
EXECUTE stmt;
|
||||
|
|
@ -82,7 +82,7 @@ struct Namespace namespaces[] =
|
|||
std::string load_monitor_sql =
|
||||
"SELECT `Id`, `Name`, `ServerId`, `StorageId`, `Type`, `Capturing`+0, `Analysing`+0, `AnalysisSource`+0, `AnalysisImage`+0,"
|
||||
"`Recording`+0, `RecordingSource`+0, `Decoding`+0, "
|
||||
"`JanusEnabled`, `JanusAudioEnabled`, "
|
||||
"`JanusEnabled`, `JanusAudioEnabled`, `Janus_Profile_Override`, `Janus_Use_RTSP_Restream`,"
|
||||
"`LinkedMonitors`, `EventStartCommand`, `EventEndCommand`, `AnalysisFPSLimit`, `AnalysisUpdateDelay`, `MaxFPS`, `AlarmMaxFPS`,"
|
||||
"`Device`, `Channel`, `Format`, `V4LMultiBuffer`, `V4LCapturesPerFrame`, " // V4L Settings
|
||||
"`Protocol`, `Method`, `Options`, `User`, `Pass`, `Host`, `Port`, `Path`, `SecondPath`, `Width`, `Height`, `Colours`, `Palette`, `Orientation`+0, `Deinterlacing`, "
|
||||
|
|
@ -166,6 +166,8 @@ Monitor::Monitor()
|
|||
decoding(DECODING_ALWAYS),
|
||||
janus_enabled(false),
|
||||
janus_audio_enabled(false),
|
||||
janus_profile_override(""),
|
||||
janus_use_rtsp_restream(false),
|
||||
//protocol
|
||||
//method
|
||||
//options
|
||||
|
|
@ -313,8 +315,7 @@ Monitor::Monitor()
|
|||
/*
|
||||
std::string load_monitor_sql =
|
||||
"SELECT `Id`, `Name`, `ServerId`, `StorageId`, `Type`, `Capturing`+0, `Analysing`+0, `AnalysisSource`+0, `AnalysisImage`+0,"
|
||||
"`Recording`+0, `RecordingSource`+0,
|
||||
`Decoding`+0, JanusEnabled, JanusAudioEnabled, "
|
||||
"`Recording`+0, `RecordingSource`+0, `Decoding`+0, JanusEnabled, JanusAudioEnabled, Janus_Profile_Override, Janus_Use_RTSP_Restream"
|
||||
"LinkedMonitors, `EventStartCommand`, `EventEndCommand`, "
|
||||
"AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS,"
|
||||
"Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, " // V4L Settings
|
||||
|
|
@ -375,6 +376,8 @@ void Monitor::Load(MYSQL_ROW dbrow, bool load_zones=true, Purpose p = QUERY) {
|
|||
// See below after save_jpegs for a recalculation of decoding_enabled
|
||||
janus_enabled = dbrow[col] ? atoi(dbrow[col]) : false; col++;
|
||||
janus_audio_enabled = dbrow[col] ? atoi(dbrow[col]) : false; col++;
|
||||
janus_profile_override = std::string(dbrow[col] ? dbrow[col] : ""); col++;
|
||||
janus_use_rtsp_restream = dbrow[col] ? atoi(dbrow[col]) : false; col++;
|
||||
|
||||
linked_monitors_string = dbrow[col] ? dbrow[col] : ""; col++;
|
||||
event_start_command = dbrow[col] ? dbrow[col] : ""; col++;
|
||||
|
|
|
|||
|
|
@ -338,6 +338,7 @@ protected:
|
|||
//helper class for CURL
|
||||
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp);
|
||||
bool Janus_Healthy;
|
||||
bool Use_RTSP_Restream;
|
||||
std::string janus_session;
|
||||
std::string janus_handle;
|
||||
std::string janus_endpoint;
|
||||
|
|
@ -345,6 +346,7 @@ protected:
|
|||
std::string rtsp_username;
|
||||
std::string rtsp_password;
|
||||
std::string rtsp_path;
|
||||
std::string profile_override;
|
||||
|
||||
public:
|
||||
explicit JanusManager(Monitor *parent_);
|
||||
|
|
@ -375,6 +377,8 @@ protected:
|
|||
DecodingOption decoding; // Whether the monitor will decode h264/h265 packets
|
||||
bool janus_enabled; // Whether we set the h264/h265 stream up on janus
|
||||
bool janus_audio_enabled; // Whether we tell Janus to try to include audio.
|
||||
std::string janus_profile_override; // The Profile-ID to force the stream to use.
|
||||
bool janus_use_rtsp_restream; // Point Janus at the ZM RTSP output, rather than the camera directly.
|
||||
|
||||
std::string protocol;
|
||||
std::string method;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,9 @@ Monitor::JanusManager::JanusManager(Monitor *parent_) :
|
|||
Janus_Healthy(false)
|
||||
{
|
||||
//constructor takes care of init and calls add_to
|
||||
parent = parent_;
|
||||
//parent = parent_;
|
||||
Use_RTSP_Restream = parent->janus_use_rtsp_restream;
|
||||
profile_override = parent->janus_profile_override;
|
||||
if ((config.janus_path != nullptr) && (config.janus_path[0] != '\0')) {
|
||||
janus_endpoint = config.janus_path;
|
||||
//remove the trailing slash if present
|
||||
|
|
@ -33,22 +35,29 @@ Monitor::JanusManager::JanusManager(Monitor *parent_) :
|
|||
} else {
|
||||
janus_endpoint = "127.0.0.1:8088/janus";
|
||||
}
|
||||
std::size_t at_pos = parent->path.find("@", 7);
|
||||
if (at_pos != std::string::npos) {
|
||||
//If we find an @ symbol, we have a username/password. Otherwise, passwordless login.
|
||||
std::size_t colon_pos = parent->path.find(":", 7); //Search for the colon, but only after the rtsp:// text.
|
||||
if (colon_pos == std::string::npos) {
|
||||
//Looks like an invalid url
|
||||
throw std::runtime_error("Cannot Parse URL for Janus.");
|
||||
}
|
||||
rtsp_username = parent->path.substr(7, colon_pos-7);
|
||||
rtsp_password = parent->path.substr(colon_pos+1, at_pos - colon_pos - 1);
|
||||
rtsp_path = "rtsp://";
|
||||
rtsp_path += parent->path.substr(at_pos + 1);
|
||||
} else {
|
||||
if (Use_RTSP_Restream) {
|
||||
int restream_port = config.min_rtsp_port;
|
||||
rtsp_username = "";
|
||||
rtsp_password = "";
|
||||
rtsp_path = parent->path;
|
||||
rtsp_path = "rtsp://127.0.0.1:" + std::to_string(restream_port) + "/" + parent->rtsp_streamname;
|
||||
} else {
|
||||
std::size_t at_pos = parent->path.find("@", 7);
|
||||
if (at_pos != std::string::npos) {
|
||||
//If we find an @ symbol, we have a username/password. Otherwise, passwordless login.
|
||||
std::size_t colon_pos = parent->path.find(":", 7); //Search for the colon, but only after the rtsp:// text.
|
||||
if (colon_pos == std::string::npos) {
|
||||
//Looks like an invalid url
|
||||
throw std::runtime_error("Cannot Parse URL for Janus.");
|
||||
}
|
||||
rtsp_username = parent->path.substr(7, colon_pos-7);
|
||||
rtsp_password = parent->path.substr(colon_pos+1, at_pos - colon_pos - 1);
|
||||
rtsp_path = "rtsp://";
|
||||
rtsp_path += parent->path.substr(at_pos + 1);
|
||||
} else {
|
||||
rtsp_username = "";
|
||||
rtsp_password = "";
|
||||
rtsp_path = parent->path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -108,7 +117,7 @@ int Monitor::JanusManager::check_janus() {
|
|||
curl_easy_cleanup(curl);
|
||||
|
||||
if (res != CURLE_OK) { //may mean an error code thrown by Janus, because of a bad session
|
||||
Warning("Attempted %s got %s", endpoint.c_str(), curl_easy_strerror(res));
|
||||
Warning("Attempted to send %s to %s and got %s", postData.c_str(), endpoint.c_str(), curl_easy_strerror(res));
|
||||
janus_session = "";
|
||||
janus_handle = "";
|
||||
return -1;
|
||||
|
|
@ -151,6 +160,10 @@ int Monitor::JanusManager::add_to_janus() {
|
|||
postData += "\", \"type\" : \"rtsp\", \"rtsp_quirk\" : true, ";
|
||||
postData += "\"url\" : \"";
|
||||
postData += rtsp_path;
|
||||
if (profile_override[0] != '\0') {
|
||||
postData += "\", \"videofmtp\" : \"";
|
||||
postData += profile_override;
|
||||
}
|
||||
if (rtsp_username != "") {
|
||||
postData += "\", \"rtsp_user\" : \"";
|
||||
postData += rtsp_username;
|
||||
|
|
|
|||
|
|
@ -146,6 +146,8 @@ public static function getStatuses() {
|
|||
'Decoding' => 'Always',
|
||||
'JanusEnabled' => array('type'=>'boolean','default'=>0),
|
||||
'JanusAudioEnabled' => array('type'=>'boolean','default'=>0),
|
||||
'Janus_Profile_Override' => '',
|
||||
'Janus_Use_RTSP_Restream' => array('type'=>'boolean','default'=>0),
|
||||
'LinkedMonitors' => array('type'=>'set', 'default'=>null),
|
||||
'Triggers' => array('type'=>'set','default'=>''),
|
||||
'EventStartCommand' => '',
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ if ($action == 'save') {
|
|||
'DecodingEnabled' => 0,
|
||||
'JanusEnabled' => 0,
|
||||
'JanusAudioEnabled' => 0,
|
||||
'Janus_Use_RTSP_Restream' => 0,
|
||||
'Exif' => 0,
|
||||
'RTSPDescribe' => 0,
|
||||
'V4LMultiBuffer' => '',
|
||||
|
|
|
|||
|
|
@ -891,6 +891,16 @@ None: No frames will be decoded, live view and thumbnails will not be available~
|
|||
Attempt to enable audio in the Janus stream. Has no effect for cameras without audio support,
|
||||
but can prevent a stream playing if your camera sends an audio format unsupported by the browser.'
|
||||
),
|
||||
'FUNCTION_JANUS_PROFILE_OVERRIDE' => array(
|
||||
'Help' => '
|
||||
Manually set a Profile-ID, which can force a browser to try to play a given stream. Try "42e01f"
|
||||
for a universally supported value, or leave this blank to use the Profile-ID specified by the source.'
|
||||
),
|
||||
'FUNCTION_JANUS_USE_RTSP_RESTREAM' => array(
|
||||
'Help' => '
|
||||
If your camera will not work under Janus with any other options, enable this to use the ZoneMinder
|
||||
RTSP restream as the Janus source.'
|
||||
),
|
||||
'ImageBufferCount' => array(
|
||||
'Help' => '
|
||||
Number of raw images available in /dev/shm. Currently should be set in the 3-5 range. Used for live viewing.'
|
||||
|
|
|
|||
|
|
@ -1180,6 +1180,7 @@ echo htmlSelect('newMonitor[OutputContainer]', $videowriter_containers, $monitor
|
|||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<div name="JanusSettings">
|
||||
<tr id="FunctionJanusAudioEnabled">
|
||||
<td class="text-right pr-3"><?php echo translate('Janus Live Stream Audio') ?></td>
|
||||
<td><input type="checkbox" name="newMonitor[JanusAudioEnabled]" value="1"<?php echo $monitor->JanusAudioEnabled() ? ' checked="checked"' : '' ?>/>
|
||||
|
|
@ -1190,6 +1191,27 @@ echo htmlSelect('newMonitor[OutputContainer]', $videowriter_containers, $monitor
|
|||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="FunctionJanusProfileOverride">
|
||||
<td class="text-right pr-3"><?php echo translate('Janus Profile-ID Override') ?></td>
|
||||
<td><input type="text" name="newMonitor[Janu_Profile_Override]" value="<?php echo $monitor->Janus_Profile_Override()?>"/>
|
||||
<?php
|
||||
if ( isset($OLANG['FUNCTION_JANUS_PROFILE_OVERRIDE']) ) {
|
||||
echo '<div class="form-text">'.$OLANG['FUNCTION_JANUS_PROFILE_OVERRIDE']['Help'].'</div>';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="FunctionJanusUseRTSPRestream">
|
||||
<td class="text-right pr-3"><?php echo translate('Janus Use RTSP Restream') ?></td>
|
||||
<td><input type="checkbox" name="newMonitor[Janus_Use_RTSP_Restream]" value="1"<?php echo $monitor->Janus_Use_RTSP_Restream() ? ' checked="checked"' : '' ?>/>
|
||||
<?php
|
||||
if ( isset($OLANG['FUNCTION_JANUS_USE_RTSP_RESTREAM']) ) {
|
||||
echo '<div class="form-text">'.$OLANG['FUNCTION_JANUS_USE_RTSP_RESTREAM']['Help'].'</div>';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
</div>
|
||||
<tr>
|
||||
<td class="text-right pr-3"><?php echo translate('DefaultRate') ?></td>
|
||||
<td><?php echo htmlSelect('newMonitor[DefaultRate]', $rates, $monitor->DefaultRate()); ?></td>
|
||||
|
|
|
|||
Loading…
Reference in New Issue