Skip to content

Commit

Permalink
Merge branch 'master' of github.com:ZoneMinder/zoneminder
Browse files Browse the repository at this point in the history
  • Loading branch information
Isaac Connor committed Aug 2, 2023
2 parents b48702c + 80c145d commit 206be0e
Show file tree
Hide file tree
Showing 22 changed files with 549 additions and 32 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ web/skins/classic/js/video.js
web/tools/mootools
web/js/janus.js
web/js/ajaxQueue.js
web/js/hls.js

# Cannot be parsed as JS
web/skins/classic/includes/export_functions.php
Expand Down
2 changes: 2 additions & 0 deletions db/zm_create.sql.in
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,8 @@ CREATE TABLE `Monitors` (
`Enabled` tinyint(3) unsigned NOT NULL default '1',
`DecodingEnabled` tinyint(3) unsigned NOT NULL default '1',
`Decoding` enum('None','Ondemand','KeyFrames','KeyFrames+Ondemand', 'Always') NOT NULL default 'Always',
`RTSP2WebEnabled` BOOLEAN NOT NULL default false,
`RTSP2WebType` enum('HLS','MSE','WebRTC') NOT NULL default 'WebRTC',
`JanusEnabled` BOOLEAN NOT NULL default false,
`JanusAudioEnabled` BOOLEAN NOT NULL default false,
`Janus_Profile_Override` VARCHAR(30) NOT NULL DEFAULT '',
Expand Down
33 changes: 33 additions & 0 deletions db/zm_update-1.37.42.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
--
-- Update Monitors table to have RTSP2Web
--

SELECT 'Checking for RTSP2WebEnabled in Monitors';
SET @s = (SELECT IF(
(SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'Monitors'
AND table_schema = DATABASE()
AND column_name = 'RTSP2WebEnabled'
) > 0,
"SELECT 'Column RTSP2WebEnabled already exists on Monitors'",
"ALTER TABLE `Monitors` ADD COLUMN `RTSP2WebEnabled` BOOLEAN NOT NULL default false AFTER `Decoding`"
));

PREPARE stmt FROM @s;
EXECUTE stmt;

SELECT 'Checking for RTSP2WebType in Monitors';
SET @s = (SELECT IF(
(SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'Monitors'
AND table_schema = DATABASE()
AND column_name = 'RTSP2WebType'
) > 0,
"SELECT 'Column RTSP2WebType already exists on Monitors'",
"ALTER TABLE `Monitors` ADD COLUMN `RTSP2WebType` enum('HLS','MSE','WebRTC') NOT NULL default 'WebRTC' AFTER `RTSP2WebEnabled`"
));

PREPARE stmt FROM @s;
EXECUTE stmt;
12 changes: 12 additions & 0 deletions scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,18 @@ our @options = (
type => $types{boolean},
category => 'system',
},
{
name => 'ZM_RTSP2WEB_PATH',
default => '',
description => 'URL for RTSP2Web port.',
help => q`This value points to the location of the RTSP2Web
install, including username and password. If left blank, this
will default to demo:demo@127.0.0.1:8083
port 8083.
`,
type => $types{string},
category => 'system',
},
{
name => 'ZM_JANUS_SECRET',
default => '',
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ set(ZM_BIN_SRC_FILES
zm_local_camera.cpp
zm_monitor.cpp
zm_monitor_monitorlink.cpp
zm_monitor_rtsp2web.cpp
zm_monitor_janus.cpp
zm_monitor_amcrest.cpp
zm_monitorlink_expression.cpp
Expand Down
7 changes: 5 additions & 2 deletions src/zm_ffmpeg_camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ int FfmpegCamera::OpenFfmpeg() {
mFormatContext->interrupt_callback.opaque = this;
mFormatContext->flags |= AVFMT_FLAG_NOBUFFER | AVFMT_FLAG_FLUSH_PACKETS;

if( mUser.length() > 0 ) {
if (mUser.length() > 0) {
// build the actual uri string with encoded parameters (from the user and pass fields)
mPath = StringToLower(protocol) + "://" + mUser + ":" + UriEncode(mPass) + "@" + mMaskedPath.substr(7, std::string::npos);
Debug(1, "Rebuilt URI with encoded parameters: '%s'", mPath.c_str());
Expand Down Expand Up @@ -472,7 +472,7 @@ int FfmpegCamera::OpenFfmpeg() {

ret = av_hwdevice_ctx_create(&hw_device_ctx, type,
(hwaccel_device != "" ? hwaccel_device.c_str() : nullptr), nullptr, 0);
if ( ret < 0 and hwaccel_device != "" ) {
if (ret < 0 and hwaccel_device != "") {
ret = av_hwdevice_ctx_create(&hw_device_ctx, type, nullptr, nullptr, 0);
}
if (ret < 0) {
Expand Down Expand Up @@ -507,6 +507,9 @@ int FfmpegCamera::OpenFfmpeg() {
}
#endif

if (!mOptions.empty()) {
ret = av_dict_parse_string(&opts, mOptions.c_str(), "=", ",", 0);
}
ret = avcodec_open2(mVideoCodecContext, mVideoCodec, &opts);

e = nullptr;
Expand Down
33 changes: 30 additions & 3 deletions src/zm_monitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ struct Namespace namespaces[] =
// It will be used whereever a Monitor dbrow is needed. WHERE conditions can be appended
std::string load_monitor_sql =
"SELECT `Id`, `Name`, `Deleted`, `ServerId`, `StorageId`, `Type`, `Capturing`+0, `Analysing`+0, `AnalysisSource`+0, `AnalysisImage`+0,"
"`Recording`+0, `RecordingSource`+0, `Decoding`+0, "
"`Recording`+0, `RecordingSource`+0, `Decoding`+0, `RTSP2WebEnabled`, `RTSP2WebType`,"
"`JanusEnabled`, `JanusAudioEnabled`, `Janus_Profile_Override`, `Janus_Use_RTSP_Restream`, `Janus_RTSP_User`, `Janus_RTSP_Session_Timeout`, "
"`LinkedMonitors`, `EventStartCommand`, `EventEndCommand`, `AnalysisFPSLimit`, `AnalysisUpdateDelay`, `MaxFPS`, `AlarmMaxFPS`,"
"`Device`, `Channel`, `Format`, `V4LMultiBuffer`, `V4LCapturesPerFrame`, " // V4L Settings
Expand Down Expand Up @@ -155,6 +155,12 @@ std::string Decoding_Strings[] = {
"Always"
};

std::string RTSP2Web_Strings[] = {
"HLS",
"MSE",
"WebRTC"
};

std::string TriggerState_Strings[] = {
"Cancel", "On", "Off"
};
Expand All @@ -169,6 +175,8 @@ Monitor::Monitor()
analysing(ANALYSING_ALWAYS),
recording(RECORDING_ALWAYS),
decoding(DECODING_ALWAYS),
RTSP2Web_enabled(false),
RTSP2Web_type(WEBRTC),
janus_enabled(false),
janus_audio_enabled(false),
janus_profile_override(""),
Expand Down Expand Up @@ -301,6 +309,7 @@ Monitor::Monitor()
Poll_Trigger_State(false),
Event_Poller_Healthy(false),
Event_Poller_Closes_Event(false),
RTSP2Web_Manager(nullptr),
Janus_Manager(nullptr),
Amcrest_Manager(nullptr),
#ifdef WITH_GSOAP
Expand Down Expand Up @@ -330,7 +339,7 @@ Monitor::Monitor()
/*
std::string load_monitor_sql =
"SELECT `Id`, `Name`, `Deleted`, `ServerId`, `StorageId`, `Type`, `Capturing`+0, `Analysing`+0, `AnalysisSource`+0, `AnalysisImage`+0,"
"`Recording`+0, `RecordingSource`+0, `Decoding`+0, JanusEnabled, JanusAudioEnabled, Janus_Profile_Override, Janus_Use_RTSP_Restream, Janus_RTSP_User, Janus_RTSP_Session_Timeout, "
"`Recording`+0, `RecordingSource`+0, `Decoding`+0, RTSP2WebEnabled, RTSP2WebType, JanusEnabled, JanusAudioEnabled, Janus_Profile_Override, Janus_Use_RTSP_Restream, Janus_RTSP_User, Janus_RTSP_Session_Timeout, "
"LinkedMonitors, `EventStartCommand`, `EventEndCommand`, "
"AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS,"
"Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, " // V4L Settings
Expand Down Expand Up @@ -390,6 +399,8 @@ void Monitor::Load(MYSQL_ROW dbrow, bool load_zones=true, Purpose p = QUERY) {

decoding = (DecodingOption)atoi(dbrow[col]); col++;
// See below after save_jpegs for a recalculation of decoding_enabled
RTSP2Web_enabled = dbrow[col] ? atoi(dbrow[col]) : false; col++;
RTSP2Web_type = (RTSP2WebOption)atoi(dbrow[col]); col++;
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++;
Expand Down Expand Up @@ -1015,6 +1026,9 @@ bool Monitor::connect() {

ReloadLinkedMonitors();

if (RTSP2Web_enabled) {
RTSP2Web_Manager = new RTSP2WebManager(this);
}
if (janus_enabled) {
Janus_Manager = new JanusManager(this);
}
Expand Down Expand Up @@ -1887,6 +1901,13 @@ bool Monitor::Poll() {
#endif
} // end if Amcrest or not
} // end if Healthy
Debug(1, "Trying to check RTSP2Web in Poller");
if (RTSP2Web_enabled and RTSP2Web_Manager) {
Debug(1, "Trying to add stream to RTSP2Web");
if (RTSP2Web_Manager->check_RTSP2Web() == 0) {
RTSP2Web_Manager->add_to_RTSP2Web();
}
}
if (janus_enabled and Janus_Manager) {
if (Janus_Manager->check_janus() == 0) {
Janus_Manager->add_to_janus();
Expand Down Expand Up @@ -3331,7 +3352,7 @@ int Monitor::PrimeCapture() {
} // end if rtsp_server

//Poller Thread
if (onvif_event_listener || janus_enabled || use_Amcrest_API) {
if (onvif_event_listener || janus_enabled || RTSP2Web_enabled ||use_Amcrest_API) {
if (!Poller) {
Debug(1, "Creating unique poller thread");
Poller = zm::make_unique<PollThread>(this);
Expand Down Expand Up @@ -3411,6 +3432,12 @@ int Monitor::Close() {
soap = nullptr;
} //End ONVIF
#endif
//RTSP2Web teardoen
if (RTSP2Web_enabled and (purpose == CAPTURE) and RTSP2Web_Manager) {
delete RTSP2Web_Manager;
RTSP2Web_Manager = nullptr;
}

//Janus Teardown
if (janus_enabled and (purpose == CAPTURE) and Janus_Manager) {
delete Janus_Manager;
Expand Down
31 changes: 31 additions & 0 deletions src/zm_monitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ class Monitor : public std::enable_shared_from_this<Monitor> {
DECODING_ALWAYS
} DecodingOption;

typedef enum {
HLS,
MSE,
WEBRTC
} RTSP2WebOption;

typedef enum {
LOCAL=1,
REMOTE,
Expand Down Expand Up @@ -332,6 +338,28 @@ class Monitor : public std::enable_shared_from_this<Monitor> {
int start_Amcrest();
};

class RTSP2WebManager {
protected:
Monitor *parent;
CURL *curl = nullptr;
//helper class for CURL
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp);
bool RTSP2Web_Healthy;
bool Use_RTSP_Restream;
std::string RTSP2Web_endpoint;
std::string rtsp_username;
std::string rtsp_password;
std::string rtsp_path;

public:
explicit RTSP2WebManager(Monitor *parent_);
~RTSP2WebManager();
void load_from_monitor();
int add_to_RTSP2Web();
int check_RTSP2Web();
int remove_from_RTSP2Web();
};

class JanusManager {
protected:
Monitor *parent;
Expand Down Expand Up @@ -379,6 +407,8 @@ class Monitor : public std::enable_shared_from_this<Monitor> {
RecordingSourceOption recording_source; // Primary, Secondary, Both

DecodingOption decoding; // Whether the monitor will decode h264/h265 packets
bool RTSP2Web_enabled; // Whether we set the h264/h265 stream up on RTSP2Web
int RTSP2Web_type; // Whether we set the h264/h265 stream up on RTSP2Web
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.
Expand Down Expand Up @@ -575,6 +605,7 @@ class Monitor : public std::enable_shared_from_this<Monitor> {
bool Event_Poller_Healthy;
bool Event_Poller_Closes_Event;

RTSP2WebManager *RTSP2Web_Manager;
JanusManager *Janus_Manager;
AmcrestAPI *Amcrest_Manager;

Expand Down
Loading

0 comments on commit 206be0e

Please sign in to comment.