Merge branch 'speed_ai' of github.com:ZoneMinder/zoneminder into speed_ai

speed_ai
Isaac Connor 2025-03-12 13:38:35 -07:00
commit 5e9f2bdba7
12 changed files with 66 additions and 12 deletions

View File

@ -2,8 +2,9 @@ task:
name: freebsd-build name: freebsd-build
freebsd_instance: freebsd_instance:
matrix: matrix:
- image_family: freebsd-14-0 - image_family: freebsd-15-0
- image_family: freebsd-13-3 - image_family: freebsd-14-2
- image_family: freebsd-13-5
prepare_script: prepare_script:
- pkg install -yq git cmake pkgconf jpeg-turbo mysql80-client ffmpeg libvncserver libjwt catch2 p5-DBI p5-DBD-mysql p5-Date-Manip p5-Test-LWP-UserAgent p5-Sys-Mmap v4l_compat - pkg install -yq git cmake pkgconf jpeg-turbo mysql80-client ffmpeg libvncserver libjwt catch2 p5-DBI p5-DBD-mysql p5-Date-Manip p5-Test-LWP-UserAgent p5-Sys-Mmap v4l_compat

View File

@ -343,6 +343,8 @@ void Event::createNotes(std::string &notes) {
notes += ", "; notes += ", ";
notes += *setIter; notes += *setIter;
} }
if (mapIter != noteSetMap.begin())
notes += ", ";
} }
} // void Event::createNotes(std::string &notes) } // void Event::createNotes(std::string &notes)

View File

@ -49,6 +49,7 @@ static CodecData dec_codecs[] = {
#endif #endif
{ AV_CODEC_ID_AV1, "av1", "libsvtav1", AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P, AV_HWDEVICE_TYPE_NONE, nullptr }, { AV_CODEC_ID_AV1, "av1", "libsvtav1", AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P, AV_HWDEVICE_TYPE_NONE, nullptr },
{ AV_CODEC_ID_AV1, "av1", "libaom-av1", AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P, AV_HWDEVICE_TYPE_NONE, nullptr }, { AV_CODEC_ID_AV1, "av1", "libaom-av1", AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P, AV_HWDEVICE_TYPE_NONE, nullptr },
{ AV_CODEC_ID_AV1, "av1", "av1_vaapi", AV_PIX_FMT_YUV420P, AV_PIX_FMT_VAAPI, AV_HWDEVICE_TYPE_VAAPI, nullptr },
{ AV_CODEC_ID_MJPEG, "mjpeg", "mjpeg", AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ422P, AV_HWDEVICE_TYPE_NONE, nullptr }, { AV_CODEC_ID_MJPEG, "mjpeg", "mjpeg", AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ422P, AV_HWDEVICE_TYPE_NONE, nullptr },
{ AV_CODEC_ID_H264, "h264", "h264", AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P, AV_HWDEVICE_TYPE_NONE, nullptr }, { AV_CODEC_ID_H264, "h264", "h264", AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P, AV_HWDEVICE_TYPE_NONE, nullptr },
{ AV_CODEC_ID_H264, "h264", "h264_v4lm2m", AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P, AV_HWDEVICE_TYPE_NONE, nullptr }, { AV_CODEC_ID_H264, "h264", "h264_v4lm2m", AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P, AV_HWDEVICE_TYPE_NONE, nullptr },
@ -80,6 +81,7 @@ static CodecData enc_codecs[] = {
{ AV_CODEC_ID_H264, "h264", "libx264", AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P, AV_HWDEVICE_TYPE_NONE, nullptr }, { AV_CODEC_ID_H264, "h264", "libx264", AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P, AV_HWDEVICE_TYPE_NONE, nullptr },
{ AV_CODEC_ID_MJPEG, "mjpeg", "mjpeg", AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ420P, AV_HWDEVICE_TYPE_NONE, nullptr }, { AV_CODEC_ID_MJPEG, "mjpeg", "mjpeg", AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ420P, AV_HWDEVICE_TYPE_NONE, nullptr },
{ AV_CODEC_ID_VP9, "vp9", "libvpx-vp9", AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P, AV_HWDEVICE_TYPE_NONE, nullptr }, { AV_CODEC_ID_VP9, "vp9", "libvpx-vp9", AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P, AV_HWDEVICE_TYPE_NONE, nullptr },
{ AV_CODEC_ID_AV1, "av1", "av1_vaapi", AV_PIX_FMT_YUV420P, AV_PIX_FMT_VAAPI, AV_HWDEVICE_TYPE_VAAPI, nullptr },
{ AV_CODEC_ID_AV1, "av1", "libsvtav1", AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P, AV_HWDEVICE_TYPE_NONE, nullptr }, { AV_CODEC_ID_AV1, "av1", "libsvtav1", AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P, AV_HWDEVICE_TYPE_NONE, nullptr },
{ AV_CODEC_ID_AV1, "av1", "libaom-av1", AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P, AV_HWDEVICE_TYPE_NONE, nullptr }, { AV_CODEC_ID_AV1, "av1", "libaom-av1", AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P, AV_HWDEVICE_TYPE_NONE, nullptr },
}; };

View File

@ -6,7 +6,7 @@ add_subdirectory(api)
configure_file(includes/config.php.in "${CMAKE_CURRENT_BINARY_DIR}/includes/config.php" @ONLY) configure_file(includes/config.php.in "${CMAKE_CURRENT_BINARY_DIR}/includes/config.php" @ONLY)
# Install the web files # Install the web files
install(DIRECTORY vendor api ajax css fonts graphics includes js lang skins views DESTINATION "${ZM_WEBDIR}" PATTERN "*.in" EXCLUDE PATTERN "*Make*" EXCLUDE PATTERN "*cmake*" EXCLUDE) install(DIRECTORY vendor api ajax css fonts graphics includes js lang skins sounds views DESTINATION "${ZM_WEBDIR}" PATTERN "*.in" EXCLUDE PATTERN "*Make*" EXCLUDE PATTERN "*cmake*" EXCLUDE)
install(FILES index.php robots.txt DESTINATION "${ZM_WEBDIR}") install(FILES index.php robots.txt DESTINATION "${ZM_WEBDIR}")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/includes/config.php" DESTINATION "${ZM_WEBDIR}/includes") install(FILES "${CMAKE_CURRENT_BINARY_DIR}/includes/config.php" DESTINATION "${ZM_WEBDIR}/includes")

View File

@ -197,15 +197,15 @@ class Monitor extends ZM_Object {
protected static $table = 'Monitors'; protected static $table = 'Monitors';
protected static $RTSP2WebStream = null; protected static $RTSP2WebStreamOptions = null;
public static function getRTSP2WebStream() { public static function getRTSP2WebStreamOptions() {
if (!isset($RTSP2WebStream)) { if (!isset($RTSP2WebStreamOptions)) {
$RTSP2WebStream = array( $RTSP2WebStreamOptions = array(
'Primary' => translate('Primary'), 'Primary' => translate('Primary'),
'Secondary' => translate('Secondary'), 'Secondary' => translate('Secondary'),
); );
} }
return $RTSP2WebStream; return $RTSP2WebStreamOptions;
} }
protected $defaults = array( protected $defaults = array(

View File

@ -1253,8 +1253,28 @@ var doubleClickOnStream = function(event, touchEvent) {
if (target) { if (target) {
if (document.fullscreenElement) { if (document.fullscreenElement) {
if (getCookie('zmEventStats') && typeof eventStats !== "undefined") {
//Event page
eventStats.toggle(true);
wrapperEventVideo.removeClass('col-sm-12').addClass('col-sm-8');
changeScale();
} else if (getCookie('zmCycleShow') && typeof sidebarView !== "undefined") {
//Watch page
sidebarView.toggle(true);
monitorsSetScale(monitorId);
}
closeFullscreen(); closeFullscreen();
} else { } else {
if (getCookie('zmEventStats') && typeof eventStats !== "undefined") {
//Event page
eventStats.toggle(false);
wrapperEventVideo.removeClass('col-sm-8').addClass('col-sm-12');
changeScale();
} else if (getCookie('zmCycleShow') && typeof sidebarView !== "undefined") {
//Watch page
sidebarView.toggle(false);
monitorsSetScale(monitorId);
}
openFullscreen(target); openFullscreen(target);
} }
if (isMobile()) { if (isMobile()) {
@ -1357,3 +1377,23 @@ $j(document).on('keyup.global keydown.global', function(e) {
}); });
loadFontFaceObserver(); loadFontFaceObserver();
function canPlayCodec(filename) {
const re = /\.(\w+)\.(\w+)$/i;
const matches = re.exec(filename);
if (matches.length) {
const video = document.createElement('video');
if (matches[1] == 'av1') matches[1] = 'avc1';
const can = video.canPlayType('video/mp4; codecs="'+matches[1]+'"');
if (can == "probably") {
console.log("can play "+matches[1]);
return true;
} else if (can == "maybe") {
console.log("can maybe play "+matches[1]);
return true;
}
console.log("cannot play "+matches[1]);
return false;
}
return false;
}

View File

@ -153,6 +153,7 @@ if ($user) {
if (isset($c['Type']) and $c['Type'] == 'integer' and $c['Value'] != '') { if (isset($c['Type']) and $c['Type'] == 'integer' and $c['Value'] != '') {
echo 'const '. $name . ' = '.$value.';'.PHP_EOL; echo 'const '. $name . ' = '.$value.';'.PHP_EOL;
} else { } else {
$value = html_entity_decode(validJsStr($value));
echo 'const '. $name . ' = \''.$value.'\';'.PHP_EOL; echo 'const '. $name . ' = \''.$value.'\';'.PHP_EOL;
} }
} }

View File

@ -1346,6 +1346,7 @@ function initPage() {
getAvailableTags(); getAvailableTags();
getSelectedTags(); getSelectedTags();
// Load the event stats // Load the event stats
getStat(); getStat();
zmPanZoom.init(); zmPanZoom.init();
@ -1359,7 +1360,10 @@ function initPage() {
} }
//FIXME prevent blocking...not sure what is happening or best way to unblock //FIXME prevent blocking...not sure what is happening or best way to unblock
if (document.getElementById('videoobj')) { const video_element = document.getElementById('videoobj');
if (video_element) {
canPlayCodec(eventData.DefaultVideo);
vid = videojs('videoobj'); vid = videojs('videoobj');
addVideoTimingTrack(vid, LabelFormat, eventData.MonitorName, eventData.Length, eventData.StartDateTime); addVideoTimingTrack(vid, LabelFormat, eventData.MonitorName, eventData.Length, eventData.StartDateTime);
//$j('.vjs-progress-control').append('<div id="alarmCues" class="alarmCues"></div>');//add a place for videojs only on first load //$j('.vjs-progress-control').append('<div id="alarmCues" class="alarmCues"></div>');//add a place for videojs only on first load

View File

@ -41,6 +41,7 @@ var eventData = {
MaxScore: '<?php echo $Event->MaxScore() ?>', MaxScore: '<?php echo $Event->MaxScore() ?>',
DiskSpace: '<?php echo human_filesize($Event->DiskSpace(null)) ?>', DiskSpace: '<?php echo human_filesize($Event->DiskSpace(null)) ?>',
Storage: '<?php echo validHtmlStr($Event->Storage()->Name()).( $Event->SecondaryStorageId() ? ', '.validHtmlStr($Event->SecondaryStorage()->Name()) : '' ) ?>', Storage: '<?php echo validHtmlStr($Event->Storage()->Name()).( $Event->SecondaryStorageId() ? ', '.validHtmlStr($Event->SecondaryStorage()->Name()) : '' ) ?>',
DefaultVideo: '<?php echo validHtmlStr($Event->DefaultVideo()) ?>',
Archived: <?php echo $Event->Archived?'true':'false' ?>, Archived: <?php echo $Event->Archived?'true':'false' ?>,
Emailed: <?php echo $Event->Emailed?'true':'false' ?>, Emailed: <?php echo $Event->Emailed?'true':'false' ?>,
Path: '<?php echo $Event->Path() ?>', Path: '<?php echo $Event->Path() ?>',

View File

@ -203,6 +203,7 @@ function selectLayout(new_layout_id) {
changeMonitorStatusPosition(); //!!! After loading the saved layer, you must execute. changeMonitorStatusPosition(); //!!! After loading the saved layer, you must execute.
monitorsSetScale(); monitorsSetScale();
*/ */
on_scroll();
setCookie('zmMontageLayout', layout_id); setCookie('zmMontageLayout', layout_id);
} // end function selectLayout(element) } // end function selectLayout(element)

View File

@ -866,6 +866,7 @@ $decoders = array(
'av1' => 'av1', 'av1' => 'av1',
'av1_qsv' => 'av1_qsv', 'av1_qsv' => 'av1_qsv',
'av1_cuvid' => 'av1_cuvid', 'av1_cuvid' => 'av1_cuvid',
'av1_vaapi' => 'av1_vaapi'
#'av1_ni_quadra_dec' => 'av1_ni_quadra', #'av1_ni_quadra_dec' => 'av1_ni_quadra',
); );
echo htmlSelect('newMonitor[Decoder]', $decoders, $monitor->Decoder()); echo htmlSelect('newMonitor[Decoder]', $decoders, $monitor->Decoder());
@ -1189,7 +1190,8 @@ $videowriter_encoders = array(
'libsvtav1' => 'libsvtav1', 'libsvtav1' => 'libsvtav1',
'libaom-av1' => 'libaom-av1', 'libaom-av1' => 'libaom-av1',
'av1_qsv' => 'av1_qsv', 'av1_qsv' => 'av1_qsv',
'av1_ni_quadra_enc' => 'av1_ni_quadra' 'av1_ni_quadra_enc' => 'av1_ni_quadra',
'av1_vaapi' => 'av1_vaapi'
); );
echo htmlSelect('newMonitor[Encoder]', $videowriter_encoders, $monitor->Encoder()); echo htmlSelect('newMonitor[Encoder]', $videowriter_encoders, $monitor->Encoder());
?> ?>
@ -1271,7 +1273,7 @@ echo htmlSelect('newMonitor[OutputContainer]', $videowriter_containers, $monitor
</li> </li>
<li id="RTSP2WebStream"> <li id="RTSP2WebStream">
<label><?php echo translate('Stream source') ?> </label> <label><?php echo translate('Stream source') ?> </label>
<?php echo htmlSelect('newMonitor[RTSP2WebStream]', ZM\Monitor::getRTSP2WebStream(), $monitor->RTSP2WebStream()); ?> <?php echo htmlSelect('newMonitor[RTSP2WebStream]', ZM\Monitor::getRTSP2WebStreamOptions(), $monitor->RTSP2WebStream()); ?>
</li> </li>
<li id="FunctionJanusEnabled"> <li id="FunctionJanusEnabled">
<label><?php echo translate('Janus Live Stream') ?></label> <label><?php echo translate('Janus Live Stream') ?></label>

View File

@ -309,7 +309,7 @@ echo htmlSelect('changeRate', $maxfps_options, $options['maxfps']);
<span id="streamQualityControl"> <span id="streamQualityControl">
<label for="streamQuality"><?php echo translate('Stream quality') ?></label> <label for="streamQuality"><?php echo translate('Stream quality') ?></label>
<?php <?php
echo htmlSelect('streamChannel', ZM\Monitor::getRTSP2WebStream(), $monitor->RTSP2WebStream(), array('data-on-change'=>'monitorChangeStreamChannel','id'=>'streamChannel')); echo htmlSelect('streamChannel', ZM\Monitor::getRTSP2WebStreamOptions(), $monitor->RTSP2WebStream(), array('data-on-change'=>'monitorChangeStreamChannel','id'=>'streamChannel'));
echo htmlSelect('streamQuality', $streamQuality, $streamQualitySelected, array('data-on-change'=>'changeStreamQuality','id'=>'streamQuality')); echo htmlSelect('streamQuality', $streamQuality, $streamQualitySelected, array('data-on-change'=>'changeStreamQuality','id'=>'streamQuality'));
?> ?>
</span> </span>