Hi everybody. So neither of these features were working properly for me. Well, SOUND_ON_ALARM was, but not for montage view. The pop-up on alarm never worked for me either. I spent the last couple of days figure out how to hack them into shape. I don't really know JavaScript or PHP, and I can barely code in C so I realize that these solutions may not be the most graceful, but I noticed a lot of other people have had problems with these for a while too. So if no one else is going to take a whack at it...
Platform Specifications
Zone Minder Machine:
ZoneMinder 1.30.4-xenial1 from Ubuntu repositories
Ubuntu 16.04
Browsing Machine:
Ubuntu 16.04 and Chrome Version 65.0.3325.181.
Patched Against:
1.30.4
What this fixes
So just to clarify, and to bring any pertinent web searches here... Currently the WEB_POPUP_ON_ALARM and WEB_SOUND_ON_ALARM options in zoneminder are not working correctly, or to the satisfaction of most users. WEB_POPUP_ON_ALARM didn't work for any modern browser I tried on Linux. This option says "Should the monitor window jump to the top if an alarm occurs". With these modifications, it will instead open a new window with a list of events from all monitors that occurred in the last minute.
Secondly, the WEB_SOUND_ON_ALARM option does not work in montage view. This option states "Should the monitor window play a sound if an alarm occurs". There seems to be a difference in how supported this across a wide array of browsers, so all I can confirm is that this works on the specified build of Chrome.
Files and Directories
On my Ubuntu installation, the root ZoneMinder directory is at "/usr/share/zoneminder/"
From there, all the files we're going to be working on will be in "/www/skins/classic/views/"
All paths mentioned from here on will be relative to that directory unless otherwise specified.
Files to be edited:
js/watch.js
js/montage.js
js/montage.js.php
watch.php
montage.php
Be sure to apply it with --dry-run first and backup your originals just to be safe. If this doesn't work, I'm including failsafe instructions for manually editing.
Patching with 'diff'
SOUND_ON_ALARM for montage plus POPUP_ON_ALARM for chrome diff...
Code: Select all
diff -Naur ./views/js/montage.js ./views_patched/js/montage.js
--- ./views/js/montage.js 2018-04-15 01:28:35.364986299 -0700
+++ ./views_patched/js/montage.js 2018-04-15 02:54:13.708110910 -0700
@@ -69,24 +69,38 @@
if ( newAlarm )
{
- if ( false && SOUND_ON_ALARM )
+ if ( SOUND_ON_ALARM )
{
- // Enable the alarm sound
- $('alarmSound').removeClass( 'hidden' );
- }
+ // Enable the alarm sound
+ if ( !canPlayPauseAudio )
+ $('alarmSound').removeClass( 'hidden' );
+ else
+ $('MediaPlayer').Play();
+ }
if ( POPUP_ON_ALARM )
{
- windowToFront();
+ if (navigator.userAgent.indexOf('Chrome/') > 0) {
+ if (window.detwin) {
+ window.detwin.close();
+ window.detwin = null;
+ }
+ }
+ window.detwin = window.open('?view=events&page=1&filter[terms][0][attr]=DateTime&filter[terms][0][op]=%3E%3D&filter[terms][0][val]=-1+minute', 'ALARM RAISED', '...');
+ window.detwin.focus();
+ //windowToFront();
}
}
- if ( false && SOUND_ON_ALARM )
- {
- if ( oldAlarm )
+ if ( SOUND_ON_ALARM )
{
- // Disable alarm sound
- $('alarmSound').addClass( 'hidden' );
+ if ( oldAlarm )
+ {
+ // Disable alarm sound
+ if ( !canPlayPauseAudio )
+ $('alarmSound').addClass( 'hidden' );
+ else
+ $('MediaPlayer').Stop();
}
- }
+ }
}
else
{
diff -Naur ./views/js/montage.js.php ./views_patched/js/montage.js.php
--- ./views/js/montage.js.php 2018-04-15 01:29:10.581874297 -0700
+++ ./views_patched/js/montage.js.php 2018-04-15 01:33:34.088661273 -0700
@@ -26,6 +26,8 @@
var canStreamNative = <?php echo canStreamNative()?'true':'false' ?>;
+var canPlayPauseAudio = Browser.ie;
+
var monitorData = new Array();
<?php
foreach ( $monitors as $monitor )
diff -Naur ./views/js/watch.js ./views_patched/js/watch.js
--- ./views/js/watch.js 2018-04-15 01:29:47.650388424 -0700
+++ ./views_patched/js/watch.js 2018-04-15 01:57:51.010680595 -0700
@@ -83,8 +83,15 @@
}
if ( POPUP_ON_ALARM )
{
- window.focus();
- }
+ if (navigator.userAgent.indexOf('Chrome/') > 0) {
+ if (window.detwin) {
+ window.detwin.close();
+ window.detwin = null;
+ }
+ }
+ window.detwin = window.open('?view=events&page=1&filter[terms][0][attr]=DateTime&filter[terms][0][op]=%3E%3D&filter[terms][0][val]=-1+minute', 'ALARM RAISED', '...');
+ window.detwin.focus();
+ }
}
if ( SOUND_ON_ALARM )
{
diff -Naur ./views/montage.php ./views_patched/montage.php
--- ./views/montage.php 2018-04-15 01:27:10.174190704 -0700
+++ ./views_patched/montage.php 2018-04-15 01:33:04.766582472 -0700
@@ -84,6 +84,7 @@
xhtmlHeaders(__FILE__, translate('Montage') );
?>
+<meta http-equiv="refresh" content="60" >
<body>
<div id="page">
<div id="header">
@@ -152,5 +153,50 @@
</div>
</div>
</div>
+ </div>
+ </div>
+
+<?php
+if ( ZM_WEB_SOUND_ON_ALARM )
+{
+ $soundSrc = ZM_DIR_SOUNDS.'/'.ZM_WEB_ALARM_SOUND;
+?>
+ <div id="alarmSound" class="hidden">
+<?php
+ if ( ZM_WEB_USE_OBJECT_TAGS && isWindows() )
+ {
+?>
+ <object id="MediaPlayer" width="0" height="0"
+ classid="CLSID:22D6F312-B0F6-11D0-94AB-0080C74C7E95"
+ codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,0,02,902">
+ <param name="FileName" value="<?php echo $soundSrc ?>"/>
+ <param name="autoStart" value="0"/>
+ <param name="loop" value="1"/>
+ <param name="hidden" value="1"/>
+ <param name="showControls" value="0"/>
+ <embed src="<?php echo $soundSrc ?>"
+ autostart="true"
+ loop="true"
+ hidden="true">
+ </embed>
+ </object>
+<?php
+ }
+ else
+ {
+?>
+ <embed src="<?php echo $soundSrc ?>"
+ autostart="true"
+ loop="true"
+ hidden="true">
+ </embed>
+<?php
+ }
+?>
+ </div>
+<?php
+}
+?>
+
</body>
</html>
diff -Naur ./views/watch.php ./views_patched/watch.php
--- ./views/watch.php 2018-04-15 01:30:35.896645337 -0700
+++ ./views_patched/watch.php 2018-04-15 01:32:55.608431844 -0700
@@ -77,6 +77,7 @@
xhtmlHeaders( __FILE__, $monitor->Name()." - ".translate('Feed') );
?>
+<meta http-equiv="refresh" content="60" >
<body>
<div id="page">
<div id="content">
@@ -240,5 +241,6 @@
?>
</div>
</div>
+
</body>
</html>
Code: Select all
diff -Naur '--exclude=*montage*' ./views/js/watch.js ./views_patched/js/watch.js
--- ./views/js/watch.js 2018-04-15 01:29:47.650388424 -0700
+++ ./views_patched/js/watch.js 2018-04-15 01:57:51.010680595 -0700
@@ -83,8 +83,15 @@
}
if ( POPUP_ON_ALARM )
{
- window.focus();
- }
+ if (navigator.userAgent.indexOf('Chrome/') > 0) {
+ if (window.detwin) {
+ window.detwin.close();
+ window.detwin = null;
+ }
+ }
+ window.detwin = window.open('?view=events&page=1&filter[terms][0][attr]=DateTime&filter[terms][0][op]=%3E%3D&filter[terms][0][val]=-1+minute', 'ALARM RAISED', '...');
+ window.detwin.focus();
+ }
}
if ( SOUND_ON_ALARM )
{
diff -Naur '--exclude=*montage*' ./views/watch.php ./views_patched/watch.php
--- ./views/watch.php 2018-04-15 01:30:35.896645337 -0700
+++ ./views_patched/watch.php 2018-04-15 01:32:55.608431844 -0700
@@ -77,6 +77,7 @@
xhtmlHeaders( __FILE__, $monitor->Name()." - ".translate('Feed') );
?>
+<meta http-equiv="refresh" content="60" >
<body>
<div id="page">
<div id="content">
@@ -240,5 +241,6 @@
?>
</div>
</div>
+
</body>
</html>
Code: Select all
diff -Naur '--exclude=*watch*' ./views/js/montage.js ./views_patched/js/montage.js
--- ./views/js/montage.js 2018-04-15 01:28:35.364986299 -0700
+++ ./views_patched/js/montage.js 2018-04-15 02:01:00.268530676 -0700
@@ -69,24 +69,30 @@
if ( newAlarm )
{
- if ( false && SOUND_ON_ALARM )
+ if ( SOUND_ON_ALARM )
{
- // Enable the alarm sound
- $('alarmSound').removeClass( 'hidden' );
- }
+ // Enable the alarm sound
+ if ( !canPlayPauseAudio )
+ $('alarmSound').removeClass( 'hidden' );
+ else
+ $('MediaPlayer').Play();
+ }
if ( POPUP_ON_ALARM )
{
- windowToFront();
+ windowToFront();
}
}
- if ( false && SOUND_ON_ALARM )
- {
- if ( oldAlarm )
+ if ( SOUND_ON_ALARM )
{
- // Disable alarm sound
- $('alarmSound').addClass( 'hidden' );
+ if ( oldAlarm )
+ {
+ // Disable alarm sound
+ if ( !canPlayPauseAudio )
+ $('alarmSound').addClass( 'hidden' );
+ else
+ $('MediaPlayer').Stop();
}
- }
+ }
}
else
{
diff -Naur '--exclude=*watch*' ./views/js/montage.js.php ./views_patched/js/montage.js.php
--- ./views/js/montage.js.php 2018-04-15 01:29:10.581874297 -0700
+++ ./views_patched/js/montage.js.php 2018-04-15 01:33:34.088661273 -0700
@@ -26,6 +26,8 @@
var canStreamNative = <?php echo canStreamNative()?'true':'false' ?>;
+var canPlayPauseAudio = Browser.ie;
+
var monitorData = new Array();
<?php
foreach ( $monitors as $monitor )
diff -Naur '--exclude=*watch*' ./views/montage.php ./views_patched/montage.php
--- ./views/montage.php 2018-04-15 01:27:10.174190704 -0700
+++ ./views_patched/montage.php 2018-04-15 01:33:04.766582472 -0700
@@ -84,6 +84,7 @@
xhtmlHeaders(__FILE__, translate('Montage') );
?>
+<meta http-equiv="refresh" content="60" >
<body>
<div id="page">
<div id="header">
@@ -152,5 +153,50 @@
</div>
</div>
</div>
+ </div>
+ </div>
+
+<?php
+if ( ZM_WEB_SOUND_ON_ALARM )
+{
+ $soundSrc = ZM_DIR_SOUNDS.'/'.ZM_WEB_ALARM_SOUND;
+?>
+ <div id="alarmSound" class="hidden">
+<?php
+ if ( ZM_WEB_USE_OBJECT_TAGS && isWindows() )
+ {
+?>
+ <object id="MediaPlayer" width="0" height="0"
+ classid="CLSID:22D6F312-B0F6-11D0-94AB-0080C74C7E95"
+ codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,0,02,902">
+ <param name="FileName" value="<?php echo $soundSrc ?>"/>
+ <param name="autoStart" value="0"/>
+ <param name="loop" value="1"/>
+ <param name="hidden" value="1"/>
+ <param name="showControls" value="0"/>
+ <embed src="<?php echo $soundSrc ?>"
+ autostart="true"
+ loop="true"
+ hidden="true">
+ </embed>
+ </object>
+<?php
+ }
+ else
+ {
+?>
+ <embed src="<?php echo $soundSrc ?>"
+ autostart="true"
+ loop="true"
+ hidden="true">
+ </embed>
+<?php
+ }
+?>
+ </div>
+<?php
+}
+?>
+
</body>
</html>
SOUND_ON_ALARM in Montage View: https://pastebin.com/r2sDzfX5
Both: https://pastebin.com/ypuzdSGk
To apply, copy and paste the contents of the pastebin into a text file, and save it as "views.patch" into your "...zoneminder/www/skins/classic/" directory.
Then run
(Note do this as root or with sudo since you won't have write permissions otherwise)
Code: Select all
patch --dry-run -p1 < views.patch
Code: Select all
checking file views/js/montage.js
checking file views/js/montage.js.php
checking file views/js/watch.js
checking file views/montage.php
checking file views/watch.php
Code: Select all
patch -b -p1 < ./views.patch
Code: Select all
patching file views/js/montage.js
patching file views/js/montage.js.php
patching file views/js/watch.js
patching file views/montage.php
patching file views/watch.php
Test it out, see if it works for you. If not, you can reverse the patch.
Code: Select all
patch -R -p1 < ./views.patch
If patching went successful, but things aren't working right...
I made this patch against the 1.30.4 branch from git since I had already modified my files from the Ubuntu repositories, and I didn't want to risk changing something else I didn't intend to by doing a reinstall from packages. So if you have trouble with the patch working against your current installation, try again but applying it against 1.30.4 branch from the git repositories, and then move the "view" directory from there into your package manager's zoneminder installation.
Otherwise, carry on with manual editing.
Manually Editing Instructions
Here's the meat and potatoes of it in case patching doesn't work and you need to edit the files manually. Let's start with the SOUND_ON_ALARM for montage view as this seems to be the most desired thing for most, and requires the most modification.
It is best to create backups before beginning this editing, in case you place something in the wrong spot, or things have changed in the code dramatically since this post.
(Edit these as root or you won't have write permissions)
Open "js/montage.js" in a text editor, and search for "if (newAlarm)" (or go to line 70). It should look like this...
Code: Select all
if ( newAlarm )
{
if ( false && SOUND_ON_ALARM )
{
// Enable the alarm sound
$('alarmSound').removeClass( 'hidden' );
}
if ( POPUP_ON_ALARM )
{
windowToFront();
}
}
if ( false && SOUND_ON_ALARM )
{
if ( oldAlarm )
{
// Disable alarm sound
$('alarmSound').addClass( 'hidden' );
}
}
Code: Select all
if ( false && SOUND_ON_ALARM )
Code: Select all
if ( SOUND_ON_ALARM)
Code: Select all
// Enable the alarm sound
if ( !canPlayPauseAudio )
$('alarmSound').removeClass( 'hidden' );
else
$('MediaPlayer').Play();
Code: Select all
// Disable alarm sound
if ( !canPlayPauseAudio )
$('alarmSound').addClass( 'hidden' );
else
$('MediaPlayer').Stop();
Scroll to the bottom and between the very last div tag, and the closing body tag (beginning after line 156), add this
Code: Select all
<?php
if ( ZM_WEB_SOUND_ON_ALARM )
{
$soundSrc = ZM_DIR_SOUNDS.'/'.ZM_WEB_ALARM_SOUND;
?>
<div id="alarmSound" class="hidden">
<?php
if ( ZM_WEB_USE_OBJECT_TAGS && isWindows() )
{
?>
<object id="MediaPlayer" width="0" height="0"
classid="CLSID:22D6F312-B0F6-11D0-94AB-0080C74C7E95"
codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,0,02,902">
<param name="FileName" value="<?php echo $soundSrc ?>"/>
<param name="autoStart" value="0"/>
<param name="loop" value="1"/>
<param name="hidden" value="1"/>
<param name="showControls" value="0"/>
<embed src="<?php echo $soundSrc ?>"
autostart="true"
loop="true"
hidden="true">
</embed>
</object>
<?php
}
else
{
?>
<embed src="<?php echo $soundSrc ?>"
autostart="true"
loop="true"
hidden="true">
</embed>
<?php
}
?>
</div>
<?php
}
?>
Code: Select all
var canStreamNative = <?php echo canStreamNative()?'true':'false' ?>;
Code: Select all
var canPlayPauseAudio = Browser.ie;
Now for the simpler part, the POPUP_ON_ALARM. The problem with this is both the montage and watch view are using outdated and unsupported methods to bring the window to focus. I'll start with the watch view. Open "js/watch.js"
Search for "if ( POPUP_ON_ALARM )" or go to line 84.
Code: Select all
if ( POPUP_ON_ALARM )
{
window.focus();
}
So replace the pop-up method ( it's different in "js/montage.js" ) with this code block....
Code: Select all
if ( POPUP_ON_ALARM )
{
if (navigator.userAgent.indexOf('Chrome/') > 0) {
if (window.detwin) {
window.detwin.close();
window.detwin = null;
}
}
window.detwin = window.open('?view=events&page=1&filter[terms][0][attr]=DateTime&filter[terms][0][op]=%3E%3D&filter[terms][0][val]=-1+minute', 'ALRM RAISED', '...');
window.detwin.focus();
}
Auto-Refresh
For whatever reason, the modifications to play sound require a page refresh if the POPUP_ON_ALARM option using the new code is on. The simplest thing to do is to edit either/both 'watch.php' and 'montage.php' with a simple meta tag right before the first body tag like so...
Code: Select all
<meta http-equiv="refresh" content="60" >
<body>
Conclusion
So just to wrap up, I didn't intend to make this into a large production or something like that, and was just intending to show how I did a simple fix, but the modifications are a little more extensive than I first thought once I got to writing out how to do it. Just hoping this helps someone down the line, perhaps ( and probably ) a better coder than I who will do a good enough job to get these fixes committed to the main branch.