diff --git a/fhem/contrib/DS_Starter/49_SSCam.pm b/fhem/contrib/DS_Starter/49_SSCam.pm index 08655d1ab..bfef7c2d4 100644 --- a/fhem/contrib/DS_Starter/49_SSCam.pm +++ b/fhem/contrib/DS_Starter/49_SSCam.pm @@ -1,5 +1,5 @@ ######################################################################################################################## -# $Id: 49_SSCam.pm 22363 2020-07-06 21:38:30Z DS_Starter $ +# $Id: 49_SSCam.pm 22382 2020-07-10 20:25:50Z DS_Starter $ ######################################################################################################################### # 49_SSCam.pm # @@ -156,7 +156,8 @@ BEGIN { # Versions History intern my %vNotesIntern = ( - "9.4.2" => "10.07.2020 more changes according PBP level 3, headline PTZ Control ", + "9.4.3" => "12.07.2020 streamDev refactored ", + "9.4.2" => "11.07.2020 more changes according PBP level 3, headline PTZ Control, revised comref ", "9.4.1" => "05.07.2020 new Zoom icons ", "9.4.0" => "01.07.2020 switch to packages, much more changes according PBP ", "9.3.0" => "21.06.2020 SVS device 'inctive' if disabled, add zoom capability, much more internal code changes ", @@ -425,52 +426,60 @@ my %errlist = ( # Tooltipps Textbausteine (http://www.walterzorn.de/tooltip/tooltip.htm#download), §NAME§ wird durch Kameranamen ersetzt my %ttips_en = ( - ttrefresh => "The playback of streaming content of camera of "§NAME§" will be restartet.", - ttrecstart => "Start an endless recording of camera "§NAME§".
You have to stop the recording manually.", - ttrecstop => "Stopp the recording of camera "§NAME§".", - ttsnap => "Take a snapshot of camera "§NAME§".", - ttcmdstop => "Stopp playback of camera "§NAME§"", - tthlsreact => "Reactivate HTTP Livestreaming Interface of camera "§NAME§".
The camera is enforced to restart HLS transmission.", - ttmjpegrun => "Playback the MJPEG Livestream of camera "§NAME§".", - tthlsrun => "Playback the native HTTP Livestream of camera "§NAME§". The browser must have native support for HLS streaming.", - ttlrrun => "Playback of last recording of camera "§NAME§" in an iFrame.
Both MJPEG and H.264 recordings are rendered.", - tth264run => "Playback of last H.264 recording of camera "§NAME§".
It only starts if the recording is type H.264", - ttlmjpegrun => "Playback of last MJPEG recording of camera "§NAME§".
It only starts if the recording is type MJPEG", - ttlsnaprun => "Playback of last snapshot of camera "§NAME§".", - confcam => "The configuration menu of camera "§NAME§" will be opened in a new Browser page", - confsvs => "The configuration page of Synology Surveillance Station will be opened in a new Browser page", - helpsvs => "The online help page of Synology Surveillance Station will be opened in a new Browser page", + ttrefresh => "The playback of streaming content of camera of "§NAME§" will be restartet.", + ttrecstart => "Start an endless recording of camera "§NAME§".
You have to stop the recording manually.", + ttrecstop => "Stopp the recording of camera "§NAME§".", + ttsnap => "Take a snapshot of camera "§NAME§".", + ttcmdstop => "Stopp playback of camera "§NAME§"", + tthlsreact => "Reactivate HTTP Livestreaming Interface of camera "§NAME§".
The camera is enforced to restart HLS transmission.", + ttmjpegrun => "Playback the MJPEG Livestream of camera "§NAME§".", + tthlsrun => "Playback the native HTTP Livestream of camera "§NAME§". The browser must have native support for HLS streaming.", + ttlrrun => "Playback of last recording of camera "§NAME§" in an iFrame.
Both MJPEG and H.264 recordings are rendered.", + tth264run => "Playback of last H.264 recording of camera "§NAME§".
It only starts if the recording is type H.264", + ttlmjpegrun => "Playback of last MJPEG recording of camera "§NAME§".
It only starts if the recording is type MJPEG", + ttlsnaprun => "Playback of last snapshot of camera "§NAME§".", + confcam => "The configuration menu of camera "§NAME§" will be opened in a new Browser page", + confsvs => "The configuration page of Synology Surveillance Station will be opened in a new Browser page", + helpsvs => "The online help page of Synology Surveillance Station will be opened in a new Browser page", ); my %ttips_de = ( - ttrefresh => "Die Wiedergabe des Streams von Kamera "§NAME§" wird neu gestartet.", - ttrecstart => "Startet eine Endlosaufnahme von Kamera "§NAME§".
Die Aufnahme muß manuell gestoppt werden.", - ttrecstop => "Stoppt die laufende Aufnahme von Kamera "§NAME§".", - ttsnap => "Ein Schnappschuß von Kamera "§NAME§" wird aufgenommen.", - ttcmdstop => "Stopp Wiedergabe von Kamera "§NAME§"", - tthlsreact => "Reaktiviert das HTTP Livestreaming Interface von Kamera "§NAME§".
Die Kamera wird aufgefordert die HLS Übertragung zu restarten.", - ttmjpegrun => "Wiedergabe des MJPEG Livestreams von Kamera "§NAME§"", - tthlsrun => "Wiedergabe des HTTP Livestreams von Kamera "§NAME§".
Es wird die HLS Funktion der Synology Surveillance Station verwendet. (der Browser muss HLS nativ unterstützen)", - ttlrrun => "Wiedergabe der letzten Aufnahme von Kamera "§NAME§" in einem iFrame.
Es werden sowohl MJPEG als auch H.264 Aufnahmen wiedergegeben.", - tth264run => "Wiedergabe der letzten H.264 Aufnahme von Kamera "§NAME§".
Die Wiedergabe startet nur wenn die Aufnahme vom Typ H.264 ist.", - ttlmjpegrun => "Wiedergabe der letzten MJPEG Aufnahme von Kamera "§NAME§".
Die Wiedergabe startet nur wenn die Aufnahme vom Typ MJPEG ist.", - ttlsnaprun => "Wiedergabe des letzten Schnappschusses von Kamera "§NAME§".", - confcam => "Das Konfigurationsmenü von Kamera "§NAME§" wird in einer neuen Browserseite geöffnet", - confsvs => "Die Konfigurationsseite der Synology Surveillance Station wird in einer neuen Browserseite geöffnet", - helpsvs => "Die Onlinehilfe der Synology Surveillance Station wird in einer neuen Browserseite geöffnet", + ttrefresh => "Die Wiedergabe des Streams von Kamera "§NAME§" wird neu gestartet.", + ttrecstart => "Startet eine Endlosaufnahme von Kamera "§NAME§".
Die Aufnahme muß manuell gestoppt werden.", + ttrecstop => "Stoppt die laufende Aufnahme von Kamera "§NAME§".", + ttsnap => "Ein Schnappschuß von Kamera "§NAME§" wird aufgenommen.", + ttcmdstop => "Stopp Wiedergabe von Kamera "§NAME§"", + tthlsreact => "Reaktiviert das HTTP Livestreaming Interface von Kamera "§NAME§".
Die Kamera wird aufgefordert die HLS Übertragung zu restarten.", + ttmjpegrun => "Wiedergabe des MJPEG Livestreams von Kamera "§NAME§"", + tthlsrun => "Wiedergabe des HTTP Livestreams von Kamera "§NAME§".
Es wird die HLS Funktion der Synology Surveillance Station verwendet. (der Browser muss HLS nativ unterstützen)", + ttlrrun => "Wiedergabe der letzten Aufnahme von Kamera "§NAME§" in einem iFrame.
Es werden sowohl MJPEG als auch H.264 Aufnahmen wiedergegeben.", + tth264run => "Wiedergabe der letzten H.264 Aufnahme von Kamera "§NAME§".
Die Wiedergabe startet nur wenn die Aufnahme vom Typ H.264 ist.", + ttlmjpegrun => "Wiedergabe der letzten MJPEG Aufnahme von Kamera "§NAME§".
Die Wiedergabe startet nur wenn die Aufnahme vom Typ MJPEG ist.", + ttlsnaprun => "Wiedergabe des letzten Schnappschusses von Kamera "§NAME§".", + confcam => "Das Konfigurationsmenü von Kamera "§NAME§" wird in einer neuen Browserseite geöffnet", + confsvs => "Die Konfigurationsseite der Synology Surveillance Station wird in einer neuen Browserseite geöffnet", + helpsvs => "Die Onlinehilfe der Synology Surveillance Station wird in einer neuen Browserseite geöffnet", ); my %imc = ( # disbled String modellabhängig (SVS / CAM) - 0 => { 0 => "initialized", 1 => "inactive" }, - 1 => { 0 => "off", 1 => "inactive" }, + 0 => { 0 => "initialized", 1 => "inactive" }, + 1 => { 0 => "off", 1 => "inactive" }, ); my %zd = ( # Hash der Zoomsteuerung - ".++" => {dir => "in", sttime => 6, moveType => "Start", panimg => "Zoom_in_wide_w.png", }, - "+" => {dir => "in", sttime => 0.5, moveType => "Start", panimg => "Zoom_in_w.png", }, - "stop" => {dir => undef, sttime => undef, moveType => "Stop" , panimg => "black_btn_CAMBLANK.png", }, - "-" => {dir => "out", sttime => 0.5, moveType => "Start", panimg => "Zoom_out_w.png", }, - "--." => {dir => "out", sttime => 6, moveType => "Start", panimg => "Zoom_out_wide_w.png", } + ".++" => {dir => "in", sttime => 6, moveType => "Start", panimg => "Zoom_in_wide_w.png", }, + "+" => {dir => "in", sttime => 0.5, moveType => "Start", panimg => "Zoom_in_w.png", }, + "stop" => {dir => undef, sttime => undef, moveType => "Stop" , panimg => "black_btn_CAMBLANK.png", }, + "-" => {dir => "out", sttime => 0.5, moveType => "Start", panimg => "Zoom_out_w.png", }, + "--." => {dir => "out", sttime => 6, moveType => "Start", panimg => "Zoom_out_wide_w.png", } +); + +my %sdfn = ( # Funktionshash Streamingdevices + "mjpeg" => {fn => "_streamDevMJPEG" }, + "lastsnap" => {fn => "_streamDevLASTSNAP" }, + "generic" => {fn => "_streamDevGENERIC" }, + "hls" => {fn => "_streamDevHLS" }, + "switched" => {fn => "_streamDevSWITCHED" }, ); # Standardvariablen und Forward-Deklaration @@ -485,8 +494,6 @@ my $valZoom = ".++,+,stop,-,--."; # Inhalt des Setters " #use vars qw($FW_detail); # currently selected device for detail view #use vars qw($FW_wname); # Web instance # sub FW_pH(@); # add href -# use vars qw(%vHintsExt_en); -# use vars qw(%vHintsExt_de); #sub SSChatBot_formString; #sub SSChatBot_addQueue($$$$$$$$); @@ -1201,8 +1208,8 @@ sub Set { my $spec = join(" ",@a); if($spec =~ /STRM:/x) { - $spec =~ m/STRM:(.*)/ix; # Aufnahme durch SSCamSTRM-Device - $hash->{HELPER}{INFORM} = $1; + my ($inf) = $spec =~ m/STRM:(.*)/ix; # Aufnahme durch SSCamSTRM-Device + $hash->{HELPER}{INFORM} = $inf; } my $emtxt = AttrVal($name, "recEmailTxt", ""); @@ -7766,10 +7773,10 @@ sub ptzPanel { $img = $btn[$btnnr]; } - if ($img =~ m/\.svg/x) { # Verwendung für SVG's + if ($img =~ m/\.svg/x) { # Verwendung für SVG's $img = FW_makeImage($img, $cmd, "rc-button"); - } else { # $FW_ME = URL-Pfad unter dem der FHEMWEB-Server via HTTP erreichbar ist, z.B. /fhem + } else { # $FW_ME = URL-Pfad unter dem der FHEMWEB-Server via HTTP erreichbar ist, z.B. /fhem if($ftui) { $img = ""; } else { @@ -7790,13 +7797,11 @@ sub ptzPanel { } $ptz_ret .= "\n"; } - # $ptz_ret .= ""; ### Zoom ############################### - if(IsCapZoom($hash)) { # wenn Zoom Eigenschaft + if(IsCapZoom($hash)) { # wenn Zoom Eigenschaft - # $ptz_ret .= ''; $ptz_ret .= ""; $ptz_ret .= ""; $ptz_ret .= ""; @@ -7818,12 +7823,17 @@ sub ptzPanel { $img = FW_makeImage($img, $cmd, "rc-button"); } else { # $FW_ME = URL-Pfad unter dem der FHEMWEB-Server via HTTP erreichbar ist, z.B. /fhem - my $iPath = FW_iconPath($img); - - if($ftui) { - $img = ""; + my $iPath = FW_iconPath($img); # automatisches Suchen der Icons im FHEMWEB iconPath + if($iPath) { + $iPath = "$FW_ME/$FW_icondir/$iPath"; } else { - $img = ""; + $iPath = "$FW_ME/$iconpath/$img"; + } + + if($ftui) { + $img = ""; + } else { + $img = ""; } } @@ -7836,7 +7846,6 @@ sub ptzPanel { } $ptz_ret .= ""; - # $ptz_ret .= "

"; } $ptz_ret .= ""; @@ -7982,13 +7991,12 @@ return; # # $camname = Name der Kamaera (Parent-Device) # $strmdev = Name des Streaming-Devices -# $fmt = Streaming Format +# $fmt = Streaming Format (Vergleich auf "eq" !) # ###################################################################################### sub streamDev { my ($camname,$strmdev,$fmt,$ftui) = @_; my $hash = $defs{$camname}; - my $wltype = $hash->{HELPER}{WLTYPE}; my $serveraddr = $hash->{SERVERADDR}; my $serverport = $hash->{SERVERPORT}; my $apivideostm = $hash->{HELPER}{APIVIDEOSTM}; @@ -8003,18 +8011,19 @@ sub streamDev { my $camid = $hash->{CAMID}; my $sid = $hash->{HELPER}{SID}; my $proto = $hash->{PROTOCOL}; - $ftui = ($ftui && $ftui eq "ftui")?1:0; + $ftui = ($ftui && $ftui eq "ftui") ? 1 : 0; my $hdrAlign = "center"; - my ($show,$cause,$ret,$link,$audiolink,$devWlink,$wlhash,$wlalias); # Kontext des SSCamSTRM-Devices speichern für roomRefresh - $hash->{HELPER}{STRMDEV} = $strmdev; # Name des aufrufenden SSCamSTRM-Devices - $hash->{HELPER}{STRMROOM} = $FW_room?$FW_room:""; # Raum aus dem das SSCamSTRM-Device die Funktion aufrief - $hash->{HELPER}{STRMDETAIL} = $FW_detail?$FW_detail:""; # Name des SSCamSTRM-Devices (wenn Detailansicht) - my $streamHash = $defs{$strmdev}; # Hash des SSCamSTRM-Devices - my $uuid = $streamHash->{FUUID}; # eindeutige UUID des Streamingdevices + # $hash->{HELPER}{STRMDEV} = $strmdev; # Name des aufrufenden SSCamSTRM-Devices + # $hash->{HELPER}{STRMROOM} = $FW_room?$FW_room:""; # Raum aus dem das SSCamSTRM-Device die Funktion aufrief + # $hash->{HELPER}{STRMDETAIL} = $FW_detail?$FW_detail:""; # Name des SSCamSTRM-Devices (wenn Detailansicht) + my $streamHash = $defs{$strmdev}; # Hash des SSCamSTRM-Devices + my $uuid = $streamHash->{FUUID}; # eindeutige UUID des Streamingdevices delete $streamHash->{HELPER}{STREAM}; - delete $streamHash->{HELPER}{STREAMACTIVE}; # Statusbit ob ein Stream aktiviert ist + delete $streamHash->{HELPER}{STREAMACTIVE}; # Statusbit ob ein Stream aktiviert ist + + my ($show,$cause,$ret); # Definition Tasten my $imgblank = ""; # nicht sichtbare Leertaste @@ -8059,16 +8068,46 @@ sub streamDev { $cmdrefresh = "ftui.setFhemStatus('set $camname refresh STRM:$uuid')"; } - my $ha = AttrVal($camname, "htmlattr", 'width="500" height="325"'); # HTML Attribute der Cam - $ha = AttrVal($strmdev, "htmlattr", $ha); # htmlattr mit htmlattr Streaming-Device übersteuern - if($ftui) { - $ha = AttrVal($strmdev, "htmlattrFTUI", $ha); # wenn aus FTUI aufgerufen divers setzen + # Javascript Bibliothek für Tooltips (http://www.walterzorn.de/tooltip/tooltip.htm#download) und Texte + my $calias = $hash->{CAMNAME}; # Alias der Kamera + my $ttjs = "/fhem/pgm2/sscam_tooltip.js"; + my ($ttrefresh, $ttrecstart, $ttrecstop, $ttsnap, $ttcmdstop, $tthlsreact, $ttmjpegrun, $tthlsrun, $ttlrrun, $tth264run, $ttlmjpegrun, $ttlsnaprun); + + # Hinweis Popups + if(AttrVal("global","language","EN") =~ /EN/x) { + $ttrefresh = $ttips_en{"ttrefresh"}; $ttrefresh =~ s/§NAME§/$calias/gx; + $ttrecstart = $ttips_en{"ttrecstart"}; $ttrecstart =~ s/§NAME§/$calias/gx; + $ttrecstop = $ttips_en{"ttrecstop"}; $ttrecstop =~ s/§NAME§/$calias/gx; + $ttsnap = $ttips_en{"ttsnap"}; $ttsnap =~ s/§NAME§/$calias/gx; + $ttcmdstop = $ttips_en{"ttcmdstop"}; $ttcmdstop =~ s/§NAME§/$calias/gx; + $tthlsreact = $ttips_en{"tthlsreact"}; $tthlsreact =~ s/§NAME§/$calias/gx; + $ttmjpegrun = $ttips_en{"ttmjpegrun"}; $ttmjpegrun =~ s/§NAME§/$calias/gx; + $tthlsrun = $ttips_en{"tthlsrun"}; $tthlsrun =~ s/§NAME§/$calias/gx; + $ttlrrun = $ttips_en{"ttlrrun"}; $ttlrrun =~ s/§NAME§/$calias/gx; + $tth264run = $ttips_en{"tth264run"}; $tth264run =~ s/§NAME§/$calias/gx; + $ttlmjpegrun = $ttips_en{"ttlmjpegrun"}; $ttlmjpegrun =~ s/§NAME§/$calias/gx; + $ttlsnaprun = $ttips_en{"ttlsnaprun"}; $ttlsnaprun =~ s/§NAME§/$calias/gx; + } else { + $ttrefresh = $ttips_de{"ttrefresh"}; $ttrefresh =~ s/§NAME§/$calias/gx; + $ttrecstart = $ttips_de{"ttrecstart"}; $ttrecstart =~ s/§NAME§/$calias/gx; + $ttrecstop = $ttips_de{"ttrecstop"}; $ttrecstop =~ s/§NAME§/$calias/gx; + $ttsnap = $ttips_de{"ttsnap"}; $ttsnap =~ s/§NAME§/$calias/gx; + $ttcmdstop = $ttips_de{"ttcmdstop"}; $ttcmdstop =~ s/§NAME§/$calias/gx; + $tthlsreact = $ttips_de{"tthlsreact"}; $tthlsreact =~ s/§NAME§/$calias/gx; + $ttmjpegrun = $ttips_de{"ttmjpegrun"}; $ttmjpegrun =~ s/§NAME§/$calias/gx; + $tthlsrun = $ttips_de{"tthlsrun"}; $tthlsrun =~ s/§NAME§/$calias/gx; + $ttlrrun = $ttips_de{"ttlrrun"}; $ttlrrun =~ s/§NAME§/$calias/gx; + $tth264run = $ttips_de{"tth264run"}; $tth264run =~ s/§NAME§/$calias/gx; + $ttlmjpegrun = $ttips_de{"ttlmjpegrun"}; $ttlmjpegrun =~ s/§NAME§/$calias/gx; + $ttlsnaprun = $ttips_de{"ttlsnaprun"}; $ttlsnaprun =~ s/§NAME§/$calias/gx; } - my $hb = AttrVal($strmdev, "hideButtons", 0); # Drucktasten im Footer ausblenden ? - my $hau = AttrVal($strmdev, "hideAudio", 0); # Audio Steuerblock im Footer ausblenden ? - - my $pws = AttrVal($strmdev, "popupWindowSize", ""); # Größe eines Popups + my $ha = AttrVal($camname, "htmlattr", 'width="500" height="325"'); # HTML Attribute der Cam + $ha = AttrVal($strmdev, "htmlattr", $ha); # htmlattr mit htmlattr Streaming-Device übersteuern + $ha = AttrVal($strmdev, "htmlattrFTUI", $ha) if($ftui); # wenn aus FTUI aufgerufen divers setzen + my $hb = AttrVal($strmdev, "hideButtons", 0); # Drucktasten im Footer ausblenden ? + my $hau = AttrVal($strmdev, "hideAudio", 0); # Audio Steuerblock im Footer ausblenden ? + my $pws = AttrVal($strmdev, "popupWindowSize", ""); # Größe eines Popups $pws =~ s/"//gx if($pws); $show = $defs{$streamHash->{PARENT}}->{HELPER}{ACTSTRM} if($streamHash->{MODEL} =~ /switched/x); @@ -8080,38 +8119,67 @@ sub streamDev { my $StmKey = ReadingsVal($camname,"StmKey",undef); - # Javascript Bibliothek für Tooltips (http://www.walterzorn.de/tooltip/tooltip.htm#download) und Texte - my $calias = $hash->{CAMNAME}; # Alias der Kamera - my $ttjs = "/fhem/pgm2/sscam_tooltip.js"; - my ($ttrefresh, $ttrecstart, $ttrecstop, $ttsnap, $ttcmdstop, $tthlsreact, $ttmjpegrun, $tthlsrun, $ttlrrun, $tth264run, $ttlmjpegrun, $ttlsnaprun); - - if(AttrVal("global","language","EN") =~ /EN/x) { - $ttrefresh = $ttips_en{"ttrefresh"}; $ttrefresh =~ s/§NAME§/$calias/gx; - $ttrecstart = $ttips_en{"ttrecstart"}; $ttrecstart =~ s/§NAME§/$calias/gx; - $ttrecstop = $ttips_en{"ttrecstop"}; $ttrecstop =~ s/§NAME§/$calias/gx; - $ttsnap = $ttips_en{"ttsnap"}; $ttsnap =~ s/§NAME§/$calias/gx; - $ttcmdstop = $ttips_en{"ttcmdstop"}; $ttcmdstop =~ s/§NAME§/$calias/gx; - $tthlsreact = $ttips_en{"tthlsreact"}; $tthlsreact =~ s/§NAME§/$calias/gx; - $ttmjpegrun = $ttips_en{"ttmjpegrun"}; $ttmjpegrun =~ s/§NAME§/$calias/gx; - $tthlsrun = $ttips_en{"tthlsrun"}; $tthlsrun =~ s/§NAME§/$calias/gx; - $ttlrrun = $ttips_en{"ttlrrun"}; $ttlrrun =~ s/§NAME§/$calias/gx; - $tth264run = $ttips_en{"tth264run"}; $tth264run =~ s/§NAME§/$calias/gx; - $ttlmjpegrun= $ttips_en{"ttlmjpegrun"}; $ttlmjpegrun =~ s/§NAME§/$calias/gx; - $ttlsnaprun = $ttips_en{"ttlsnaprun"}; $ttlsnaprun =~ s/§NAME§/$calias/gx; - } else { - $ttrefresh = $ttips_de{"ttrefresh"}; $ttrefresh =~ s/§NAME§/$calias/gx; - $ttrecstart = $ttips_de{"ttrecstart"}; $ttrecstart =~ s/§NAME§/$calias/gx; - $ttrecstop = $ttips_de{"ttrecstop"}; $ttrecstop =~ s/§NAME§/$calias/gx; - $ttsnap = $ttips_de{"ttsnap"}; $ttsnap =~ s/§NAME§/$calias/gx; - $ttcmdstop = $ttips_de{"ttcmdstop"}; $ttcmdstop =~ s/§NAME§/$calias/gx; - $tthlsreact = $ttips_de{"tthlsreact"}; $tthlsreact =~ s/§NAME§/$calias/gx; - $ttmjpegrun = $ttips_de{"ttmjpegrun"}; $ttmjpegrun =~ s/§NAME§/$calias/gx; - $tthlsrun = $ttips_de{"tthlsrun"}; $tthlsrun =~ s/§NAME§/$calias/gx; - $ttlrrun = $ttips_de{"ttlrrun"}; $ttlrrun =~ s/§NAME§/$calias/gx; - $tth264run = $ttips_de{"tth264run"}; $tth264run =~ s/§NAME§/$calias/gx; - $ttlmjpegrun= $ttips_de{"ttlmjpegrun"}; $ttlmjpegrun =~ s/§NAME§/$calias/gx; - $ttlsnaprun = $ttips_de{"ttlsnaprun"}; $ttlsnaprun =~ s/§NAME§/$calias/gx; - } +my %params = ( + camname => $camname, + strmdev => $strmdev, + ftui => $ftui, + uuid => $uuid, + ha => $ha, + hb => $hb, + hau => $hau, + pws => $pws, + serveraddr => $serveraddr, + serverport => $serverport, + apivideostm => $apivideostm, + apivideostmpath => $apivideostmpath, + apivideostmmaxver => $apivideostmmaxver, + apiaudiostm => $apiaudiostm, + apiaudiostmpath => $apiaudiostmpath, + apiaudiostmmaxver => $apiaudiostmmaxver, + apivideostms => $apivideostms, + apivideostmspath => $apivideostmspath, + apivideostmsmaxver => $apivideostmsmaxver, + camid => $camid, + sid => $sid, + proto => $proto, + cmdstop => $cmdstop, + cmdhlsreact => $cmdhlsreact, + cmdmjpegrun => $cmdmjpegrun, + cmdhlsrun => $cmdhlsrun, + cmdlrirun => $cmdlrirun, + cmdlh264run => $cmdlh264run, + cmdlmjpegrun => $cmdlmjpegrun, + cmdlsnaprun => $cmdlsnaprun, + cmdrecendless => $cmdrecendless, + cmdrecstop => $cmdrecstop, + cmddosnap => $cmddosnap, + cmdrefresh => $cmdrefresh, + imgblank => $imgblank, + imgstop => $imgstop, + imghlsreact => $imghlsreact, + imgmjpegrun => $imgmjpegrun, + imghlsrun => $imghlsrun, + imglrirun => $imglrirun, + imglh264run => $imglh264run, + imglmjpegrun => $imglmjpegrun, + imglsnaprun => $imglsnaprun, + imgrecendless => $imgrecendless, + imgrecstop => $imgrecstop, + imgdosnap => $imgdosnap, + imgrefresh => $imgrefresh, + ttrefresh => $ttrefresh, + ttrecstart => $ttrecstart, + ttrecstop => $ttrecstop, + ttsnap => $ttsnap, + ttcmdstop => $ttcmdstop, + tthlsreact => $tthlsreact, + ttmjpegrun => $ttmjpegrun, + tthlsrun => $tthlsrun, + ttlrrun => $ttlrrun, + tth264run => $tth264run, + ttlmjpegrun => $ttlmjpegrun, + ttlsnaprun => $ttlsnaprun, +); $ret = ""; $ret .= ""; @@ -8137,362 +8205,601 @@ sub streamDev { return $ret; } - if ($fmt =~ /mjpeg/x) { - if(ReadingsVal($camname, "SVSversion", "8.2.3-5828") eq "8.2.3-5828" && ReadingsVal($camname, "CamVideoType", "") !~ /MJPEG/) { - $ret .= "
Because SVS version 8.2.3-5828 is running you cannot see the MJPEG-Stream. Please upgrade to a higher SVS version !

"; - } else { - if($apivideostmsmaxver) { - $link = "$proto://$serveraddr:$serverport/webapi/$apivideostmspath?api=$apivideostms&version=$apivideostmsmaxver&method=Stream&cameraId=$camid&format=mjpeg&_sid=$sid"; - } elsif ($hash->{HELPER}{STMKEYMJPEGHTTP}) { - $link = $hash->{HELPER}{STMKEYMJPEGHTTP}; - } - if($apiaudiostmmaxver) { - $audiolink = "$proto://$serveraddr:$serverport/webapi/$apiaudiostmpath?api=$apiaudiostm&version=$apiaudiostmmaxver&method=Stream&cameraId=$camid&_sid=$sid"; - } - if(!$ftui) { - $ret .= "')\">
"; - } else { - $ret .= "
"; - } - $streamHash->{HELPER}{STREAM} = ""; # Stream für "get popupStream" speichern - $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist - } - if(!$hb) { - if(ReadingsVal($camname, "Record", "Stop") eq "Stop") { - # Aufnahmebutton endlos Start - $ret .= "$imgrecendless "; - } else { - # Aufnahmebutton Stop - $ret .= "$imgrecstop "; - } - $ret .= "$imgdosnap "; - } - $ret .= ""; - if(AttrVal($camname,"ptzPanel_use",1)) { - my $ptz_ret = ptzPanel($camname,$strmdev,'',$ftui); - if($ptz_ret) { - $ret .= "$ptz_ret"; - } - } - if($audiolink && ReadingsVal($camname, "CamAudioType", "Unknown") !~ /Unknown/ && !$hau) { - $ret .= ''; - $ret .= ''; - $ret .= ""; - $ret .= ""; - $ret .= "" if(AttrVal($camname,"ptzPanel_use",0)); - } - - } elsif ($fmt =~ /lastsnap/x) { - # $link = $hash->{HELPER}{".LASTSNAP"}; - my $cache = cache($camname, "c_init"); # Cache initialisieren - Log3($camname, 1, "$camname - Fall back to internal Cache due to preceding failure.") if(!$cache); - if(!$cache || $cache eq "internal" ) { - $link = $data{SSCam}{$camname}{LASTSNAP}; - } else { - $link = cache($camname, "c_read", "{LASTSNAP}"); - } - - my $gattr = (AttrVal($camname,"snapGallerySize","Icon") eq "Full")?$ha:""; - if($link) { - if(!$ftui) { - $ret .= "')\">
"; - } else { - $ret .= "
"; - } - if(!$hb) { - $ret .= "$imgdosnap "; - } - $ret .= ""; - $streamHash->{HELPER}{STREAM} = ""; # Stream für "get popupStream" speichern - $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist - } else { - $cause = "no snapshot available to display"; - $cause = "kein Schnappschuss zur Anzeige vorhanden" if(AttrVal("global","language","EN") =~ /DE/ix); - $ret .= "
$cause

"; - } - - } elsif ($fmt =~ /generic/x) { - my $htag = AttrVal($strmdev,"genericStrmHtmlTag",AttrVal($camname,"genericStrmHtmlTag","")); - - if( $htag =~ m/^\s*(.*)\s*$/s ) { - $htag = $1; - $htag =~ s/\$NAME/$camname/xg; - $htag =~ s/\$HTMLATTR/$ha/g; - $htag =~ s/\$PWS/$pws/g; - } - - if(!$htag) { - $ret .= "
Set attribute \"genericStrmHtmlTag\" in device $camname or in device $strmdev

"; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - return $ret; - } - $ret .= ""; - $ret .= "$htag"; - if($htag) { - # Popup-Tag um den Popup-Teil bereinigen - my $ptag = $htag; - $ptag =~ m/^(\s+)?(?<)(\s+)?(?.*)(\s+)?(?onClick=.*)(\s+)?(?>)(\s+)?$/s; - $ptag = $+{heart}?$+{b}.$+{heart}.$+{e}:$ptag; - $streamHash->{HELPER}{STREAM} = "$ptag"; # Stream für "set popupStream" speichern - $streamHash->{HELPER}{STREAM} =~ s/["']//gx; - $streamHash->{HELPER}{STREAM} =~ s/\s+/ /gx; - $streamHash->{HELPER}{STREAMACTIVE} = 1; # Statusbit wenn ein Stream aktiviert ist - } - $ret .= "
"; - Log3($strmdev, 4, "$strmdev - generic Stream params:\n$htag"); - if(!$hb) { - $ret .= "$imgrefresh "; - $ret .= $imgblank; - if(ReadingsVal($camname, "Record", "Stop") eq "Stop") { - # Aufnahmebutton endlos Start - $ret .= "$imgrecendless "; - } else { - # Aufnahmebutton Stop - $ret .= "$imgrecstop "; - } - $ret .= "$imgdosnap "; - } - $ret .= ""; - if(AttrVal($camname,"ptzPanel_use",1)) { - my $ptz_ret = ptzPanel($camname,$strmdev,'',$ftui); - if($ptz_ret) { - $ret .= "$ptz_ret"; - } - } - - } elsif ($fmt =~ /hls/x) { - # es ist ein .m3u8-File bzw. ein Link dorthin zu übergeben - my $cam = AttrVal($camname, "alias", $camname); - my $m3u8 = AttrVal($camname, "hlsStrmObject", ""); - - if( $m3u8 =~ m/^\s*(.*)\s*$/s ) { - $m3u8 = $1; - $m3u8 =~ s/\$NAME/$camname/gx; - } - my $d = $camname; - $d =~ s/\./_/x; # Namensableitung zur javascript Codeanpassung - - if(!$m3u8) { - $cause = "You have to specify attribute \"hlsStrmObject\" in Camera $cam !"; - $ret .= "
$cause

"; - $ret .= ''; - $ret .= ''; - $ret .= ''; - $ret .= ''; - return $ret; - } - - $ret .= "
"; - $ret .= bindhlsjs ($camname, $strmdev, $m3u8, $d); - - $streamHash->{HELPER}{STREAM} = ""; # Stream für "set popupStream" speichern - $streamHash->{HELPER}{STREAMACTIVE} = 1; # Statusbit wenn ein Stream aktiviert ist - if(!$hb) { - $ret .= "$imgrefresh "; - $ret .= $imgblank; - if(ReadingsVal($camname, "Record", "Stop") eq "Stop") { - # Aufnahmebutton endlos Start - $ret .= "$imgrecendless "; - } else { - # Aufnahmebutton Stop - $ret .= "$imgrecstop "; - } - $ret .= "$imgdosnap "; - } - $ret .= ""; - if(AttrVal($camname,"ptzPanel_use",1)) { - my $ptz_ret = ptzPanel($camname,$strmdev,'',$ftui); - if($ptz_ret) { - $ret .= "$ptz_ret"; - } - } - - } elsif ($fmt =~ /switched/x) { - my $wltype = $hash->{HELPER}{WLTYPE}; - $link = $hash->{HELPER}{LINK}; - - if($link && $wltype =~ /image|iframe|video|base64img|embed|hls/x) { - if($wltype =~ /image/x) { - if(ReadingsVal($camname, "SVSversion", "8.2.3-5828") eq "8.2.3-5828" && ReadingsVal($camname, "CamVideoType", "") !~ /MJPEG/) { - $ret .= "
Because SVS version 8.2.3-5828 is running you cannot see the MJPEG-Stream. Please upgrade to a higher SVS version !

"; - } else { - if(!$ftui) { - $ret .= "')\">
" if($link); - } else { - $ret .= "
" if($link); - } - $streamHash->{HELPER}{STREAM} = ""; # Stream für "set popupStream" speichern - $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist - } - $ret .= "$imgstop "; - $ret .= $imgblank; - if($hash->{HELPER}{RUNVIEW} =~ /live_fw/x) { - if(ReadingsVal($camname, "Record", "Stop") eq "Stop") { - # Aufnahmebutton endlos Start - $ret .= "$imgrecendless "; - } else { - # Aufnahmebutton Stop - $ret .= "$imgrecstop "; - } - $ret .= "$imgdosnap "; - } - $ret .= ""; - if(AttrVal($camname,"ptzPanel_use",1) && $hash->{HELPER}{RUNVIEW} =~ /live_fw/x) { - my $ptz_ret = ptzPanel($camname,$strmdev,'',$ftui); - if($ptz_ret) { - $ret .= "$ptz_ret"; - } - } - if($hash->{HELPER}{AUDIOLINK} && ReadingsVal($camname, "CamAudioType", "Unknown") !~ /Unknown/ && !$hau) { - $ret .= ""; - $ret .= ''; - $ret .= ""; - $ret .= ""; - $ret .= "" if(AttrVal($camname,"ptzPanel_use",0)); - } - - } elsif ($wltype =~ /iframe/x) { - if(!$ftui) { - $ret .= "
" if($link); - } else { - $ret .= "
" if($link); - } - $streamHash->{HELPER}{STREAM} = ""; # Stream für "set popupStream" speichern - $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist - $ret .= "$imgstop "; - $ret .= "$imgrefresh "; - $ret .= ""; - if($hash->{HELPER}{AUDIOLINK} && ReadingsVal($camname, "CamAudioType", "Unknown") !~ /Unknown/ && !$hau) { - $ret .= ''; - $ret .= ''; - $ret .= ""; - $ret .= ""; - $ret .= "" if(AttrVal($camname,"ptzPanel_use",0)); - } - - } elsif ($wltype =~ /video/x) { - $ret .= "
"; - $streamHash->{HELPER}{STREAM} = ""; # Stream für "set popupStream" speichern - $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist - $ret .= "$imgstop "; - $ret .= ""; - if($hash->{HELPER}{AUDIOLINK} && ReadingsVal($camname, "CamAudioType", "Unknown") !~ /Unknown/ && !$hau) { - $ret .= ''; - $ret .= ''; - $ret .= ""; - $ret .= ""; - $ret .= "" if(AttrVal($camname,"ptzPanel_use",0)); - } - } elsif($wltype =~ /base64img/x) { - if(!$ftui) { - $ret .= "')\">
" if($link); - } else { - $ret .= "
" if($link); - } - $streamHash->{HELPER}{STREAM} = ""; # Stream für "get popupStream" speichern - $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist - $ret .= "$imgstop "; - $ret .= $imgblank; - $ret .= "$imgdosnap "; - $ret .= ""; - - } elsif($wltype =~ /embed/x) { - if(!$ftui) { - $ret .= "')\">" if($link); - } else { - $ret .= "" if($link); - } - $streamHash->{HELPER}{STREAM} = ""; # Stream für "set popupStream" speichern - $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist - - } elsif($wltype =~ /hls/x) { - $ret .= "
"; - $streamHash->{HELPER}{STREAM} = ""; # Stream für "set popupStream" speichern - $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist - $ret .= "$imgstop "; - $ret .= "$imgrefresh "; - $ret .= "$imghlsreact "; - $ret .= $imgblank; - if(ReadingsVal($camname, "Record", "Stop") eq "Stop") { - # Aufnahmebutton endlos Start - $ret .= "$imgrecendless "; - } else { - # Aufnahmebutton Stop - $ret .= "$imgrecstop "; - } - $ret .= "$imgdosnap "; - $ret .= ""; - if(AttrVal($camname,"ptzPanel_use",1)) { - my $ptz_ret = ptzPanel($camname,$strmdev,'',$ftui); - if($ptz_ret) { - $ret .= "$ptz_ret"; - } - } - - } - - } else { - my $cam = AttrVal($camname, "alias", $camname); - $cause = "Playback cam \"$cam\" switched off"; - $ret .= "
$cause

"; - $ret .= "$imgmjpegrun "; - $ret .= "$imghlsrun " if(IsCapHLS($hash)); - $ret .= "$imglrirun "; - $ret .= "$imglh264run "; - $ret .= "$imglmjpegrun "; - $ret .= "$imglsnaprun "; - $ret .= ""; - } + # Streaming ausführen + no strict "refs"; ## no critic 'NoStrict' + if(defined &{$sdfn{$fmt}{fn}}) { + $ret .= &{$sdfn{$fmt}{fn}} (\%params); } else { - $cause = "Videoformat not supported"; - $ret .= "
$cause

"; - } + $cause = qq{Streaming of format "$fmt" is not supported}; + $ret .= "
$cause

"; + } + use strict "refs"; $ret .= ''; $ret .= ''; $ret .= ''; - Log3($strmdev, 4, "$strmdev - Link called: $link") if($link); - - undef $link; return $ret; } +###################################################################################### +# Streaming Device Typ: mjpeg +sub _streamDevMJPEG { + my $params = shift; + + my $camname = $params->{camname}; + my $strmdev = $params->{strmdev}; + + my $hash = $defs{$camname}; + my $streamHash = $defs{$strmdev}; + my $ftui = $params->{ftui}; + my $camid = $params->{camid}; + my $proto = $params->{proto}; + my $sid = $params->{sid}; + my $pws = $params->{pws}; + my $ha = $params->{ha}; + my $hb = $params->{hb}; + my $hau = $params->{hau}; + + my $serveraddr = $params->{serveraddr}; + my $serverport = $params->{serverport}; + my $apivideostms = $params->{apivideostms}; + my $apivideostmspath = $params->{apivideostmspath}; + my $apivideostmsmaxver = $params->{apivideostmsmaxver}; + my $apiaudiostm = $params->{apiaudiostm}; + my $apiaudiostmpath = $params->{apiaudiostmpath}; + my $apiaudiostmmaxver = $params->{apiaudiostmmaxver}; + + my $cmdrecendless = $params->{cmdrecendless}; + my $ttrecstart = $params->{ttrecstart}; + my $imgrecendless = $params->{imgrecendless}; + my $cmdrecstop = $params->{cmdrecstop}; + my $ttrecstop = $params->{ttrecstop}; + my $imgrecstop = $params->{imgrecstop}; + my $cmddosnap = $params->{cmddosnap}; + my $ttsnap = $params->{ttsnap}; + my $imgdosnap = $params->{imgdosnap}; + + my ($link,$audiolink); + my $ret = ""; + + if(ReadingsVal($camname, "SVSversion", "8.2.3-5828") eq "8.2.3-5828" && ReadingsVal($camname, "CamVideoType", "") !~ /MJPEG/) { + $ret .= "
Because SVS version 8.2.3-5828 is running you cannot see the MJPEG-Stream. Please upgrade to a higher SVS version !

"; + + } else { + if($apivideostmsmaxver) { + $link = "$proto://$serveraddr:$serverport/webapi/$apivideostmspath?api=$apivideostms&version=$apivideostmsmaxver&method=Stream&cameraId=$camid&format=mjpeg&_sid=$sid"; + } elsif ($hash->{HELPER}{STMKEYMJPEGHTTP}) { + $link = $hash->{HELPER}{STMKEYMJPEGHTTP}; + } + if($apiaudiostmmaxver) { + $audiolink = "$proto://$serveraddr:$serverport/webapi/$apiaudiostmpath?api=$apiaudiostm&version=$apiaudiostmmaxver&method=Stream&cameraId=$camid&_sid=$sid"; + } + if(!$ftui) { + $ret .= "')\">
"; + } else { + $ret .= "
"; + } + $streamHash->{HELPER}{STREAM} = ""; # Stream für "get popupStream" speichern + $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist + } + if(!$hb) { + if(ReadingsVal($camname, "Record", "Stop") eq "Stop") { + # Aufnahmebutton endlos Start + $ret .= "$imgrecendless "; + } else { + # Aufnahmebutton Stop + $ret .= "$imgrecstop "; + } + $ret .= "$imgdosnap "; + } + $ret .= ""; + if(AttrVal($camname,"ptzPanel_use",1)) { + my $ptz_ret = ptzPanel($camname,$strmdev,'',$ftui); + if($ptz_ret) { + $ret .= "$ptz_ret"; + } + } + if($audiolink && ReadingsVal($camname, "CamAudioType", "Unknown") !~ /Unknown/ && !$hau) { + $ret .= ''; + $ret .= ''; + $ret .= ""; + $ret .= ""; + $ret .= "" if(AttrVal($camname,"ptzPanel_use",0)); + } + + Log3($strmdev, 4, "$strmdev - Link called: $link") if($link); + undef $link; + +return $ret; +} + +###################################################################################### +# Streaming Device Typ: lastsnap +sub _streamDevLASTSNAP { + my $params = shift; + + my $camname = $params->{camname}; + my $strmdev = $params->{strmdev}; + + my $hash = $defs{$camname}; + my $streamHash = $defs{$strmdev}; + my $ftui = $params->{ftui}; + my $pws = $params->{pws}; + my $ha = $params->{ha}; + my $hb = $params->{hb}; + + my $cmddosnap = $params->{cmddosnap}; + my $ttsnap = $params->{ttsnap}; + my $imgdosnap = $params->{imgdosnap}; + + my ($link,$cause,$ret) = ("","",""); + + my $cache = cache($camname, "c_init"); # Cache initialisieren + Log3($camname, 1, "$camname - Fall back to internal Cache due to preceding failure.") if(!$cache); + + if(!$cache || $cache eq "internal" ) { + $link = $data{SSCam}{$camname}{LASTSNAP}; + } else { + $link = cache($camname, "c_read", "{LASTSNAP}"); + } + + my $gattr = (AttrVal($camname,"snapGallerySize","Icon") eq "Full") ? $ha : ""; + + if($link) { + if(!$ftui) { + $ret .= "')\">
"; + } else { + $ret .= "
"; + } + + if(!$hb) { + $ret .= "$imgdosnap "; + } + + $ret .= ""; + + $streamHash->{HELPER}{STREAM} = ""; # Stream für "get popupStream" speichern + $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist + + } else { + $cause = "no snapshot available to display"; + $cause = "kein Schnappschuss zur Anzeige vorhanden" if(AttrVal("global","language","EN") =~ /DE/ix); + $ret .= "
$cause

"; + } + + Log3($strmdev, 4, "$strmdev - Link called: $link") if($link); + undef $link; + +return $ret; +} + +###################################################################################### +# Streaming Device Typ: generic +sub _streamDevGENERIC { + my $params = shift; + + my $camname = $params->{camname}; + my $strmdev = $params->{strmdev}; + + my $hash = $defs{$camname}; + my $streamHash = $defs{$strmdev}; + my $ftui = $params->{ftui}; + my $pws = $params->{pws}; + my $ha = $params->{ha}; + my $hb = $params->{hb}; + + my $cmdrefresh = $params->{cmdrefresh}; + my $cmdrecendless = $params->{cmdrecendless}; + my $cmdrecstop = $params->{cmdrecstop}; + my $cmddosnap = $params->{cmddosnap}; + + my $imgrecendless = $params->{imgrecendless}; + my $imgrecstop = $params->{imgrecstop}; + my $imgdosnap = $params->{imgdosnap}; + my $imgrefresh = $params->{imgrefresh}; + my $imgblank = $params->{imgblank}; + + my $ttrefresh = $params->{ttrefresh}; + my $ttsnap = $params->{ttsnap}; + my $ttrecstop = $params->{ttrecstop}; + my $ttrecstart = $params->{ttrecstart}; + + my $ret = ""; + my $htag = AttrVal( $strmdev, "genericStrmHtmlTag", AttrVal($camname, "genericStrmHtmlTag", "") ); + + if($htag =~ m/^\s*(.*)\s*$/s) { + $htag = $1; + $htag =~ s/\$NAME/$camname/xg; + $htag =~ s/\$HTMLATTR/$ha/g; + $htag =~ s/\$PWS/$pws/g; + } + + if(!$htag) { + $ret .= "
Set attribute \"genericStrmHtmlTag\" in device $camname or in device $strmdev

"; + $ret .= ''; + $ret .= ''; + $ret .= ''; + $ret .= ''; + return $ret; + } + + $ret .= ""; + $ret .= "$htag"; + + if($htag) { + # Popup-Tag um den Popup-Teil bereinigen + my $ptag = $htag; + $ptag =~ m/^(\s+)?(?<)(\s+)?(?.*)(\s+)?(?onClick=.*)(\s+)?(?>)(\s+)?$/s; + $ptag = $+{heart} ? $+{b}.$+{heart}.$+{e} : $ptag; + $streamHash->{HELPER}{STREAM} = "$ptag"; # Stream für "set popupStream" speichern + $streamHash->{HELPER}{STREAM} =~ s/["']//gx; + $streamHash->{HELPER}{STREAM} =~ s/\s+/ /gx; + $streamHash->{HELPER}{STREAMACTIVE} = 1; # Statusbit wenn ein Stream aktiviert ist + } + + $ret .= "
"; + + Log3($strmdev, 4, "$strmdev - generic Stream params:\n$htag"); + + if(!$hb) { + $ret .= "$imgrefresh "; + $ret .= $imgblank; + + if(ReadingsVal($camname, "Record", "Stop") eq "Stop") { # Aufnahmebutton endlos Start + $ret .= "$imgrecendless "; + } else { # Aufnahmebutton Stop + $ret .= "$imgrecstop "; + } + + $ret .= "$imgdosnap "; + } + $ret .= ""; + + if(AttrVal($camname,"ptzPanel_use",1)) { + my $ptz_ret = ptzPanel($camname,$strmdev,'',$ftui); + if($ptz_ret) { + $ret .= "$ptz_ret"; + } + } + +return $ret; +} + +###################################################################################### +# Streaming Device Typ: hls +sub _streamDevHLS { + my $params = shift; + + my $camname = $params->{camname}; + my $strmdev = $params->{strmdev}; + + my $hash = $defs{$camname}; + my $streamHash = $defs{$strmdev}; + my $ftui = $params->{ftui}; + my $pws = $params->{pws}; + my $ha = $params->{ha}; + my $hb = $params->{hb}; + + my $cmdrefresh = $params->{cmdrefresh}; + my $cmdrecendless = $params->{cmdrecendless}; + my $cmdrecstop = $params->{cmdrecstop}; + my $cmddosnap = $params->{cmddosnap}; + + my $imgrecendless = $params->{imgrecendless}; + my $imgrecstop = $params->{imgrecstop}; + my $imgdosnap = $params->{imgdosnap}; + my $imgrefresh = $params->{imgrefresh}; + my $imgblank = $params->{imgblank}; + + my $ttrefresh = $params->{ttrefresh}; + my $ttsnap = $params->{ttsnap}; + my $ttrecstop = $params->{ttrecstop}; + my $ttrecstart = $params->{ttrecstart}; + + my ($cause,$ret) = ("",""); + + # es ist ein .m3u8-File bzw. ein Link dorthin zu übergeben + my $cam = AttrVal($camname, "alias", $camname); + my $m3u8 = AttrVal($camname, "hlsStrmObject", ""); + + if( $m3u8 =~ m/^\s*(.*)\s*$/s ) { + $m3u8 = $1; + $m3u8 =~ s/\$NAME/$camname/gx; + } + + my $d = $camname; + $d =~ s/\./_/x; # Namensableitung zur javascript Codeanpassung + + if(!$m3u8) { + $cause = "You have to specify attribute \"hlsStrmObject\" in Camera $cam !"; + $ret .= "
$cause

"; + $ret .= ''; + $ret .= ''; + $ret .= ''; + $ret .= ''; + return $ret; + } + + $ret .= "
"; + $ret .= bindhlsjs ($camname, $strmdev, $m3u8, $d); + + $streamHash->{HELPER}{STREAM} = ""; # Stream für "set popupStream" speichern + $streamHash->{HELPER}{STREAMACTIVE} = 1; # Statusbit wenn ein Stream aktiviert ist + + if(!$hb) { + $ret .= "$imgrefresh "; + $ret .= $imgblank; + + if(ReadingsVal($camname, "Record", "Stop") eq "Stop") { # Aufnahmebutton endlos Start + $ret .= "$imgrecendless "; + } else { # Aufnahmebutton Stop + $ret .= "$imgrecstop "; + } + + $ret .= "$imgdosnap "; + } + + $ret .= ""; + + if(AttrVal($camname,"ptzPanel_use",1)) { + my $ptz_ret = ptzPanel($camname,$strmdev,'',$ftui); + if($ptz_ret) { + $ret .= "$ptz_ret"; + } + } + +return $ret; +} + +###################################################################################### +# Streaming Device Typ: switched +sub _streamDevSWITCHED { + my $params = shift; + + my $camname = $params->{camname}; + my $strmdev = $params->{strmdev}; + + my $hash = $defs{$camname}; + my $streamHash = $defs{$strmdev}; + my $ftui = $params->{ftui}; + my $pws = $params->{pws}; + my $ha = $params->{ha}; + my $hb = $params->{hb}; + my $hau = $params->{hau}; + + my $cmdrefresh = $params->{cmdrefresh}; + my $cmdrecendless = $params->{cmdrecendless}; + my $cmdrecstop = $params->{cmdrecstop}; + my $cmddosnap = $params->{cmddosnap}; + my $cmdstop = $params->{cmdstop}; + my $cmdmjpegrun = $params->{cmdmjpegrun}; + my $cmdhlsrun = $params->{cmdhlsrun}; + my $cmdlrirun = $params->{cmdlrirun}; + my $cmdlh264run = $params->{cmdlh264run}; + my $cmdlsnaprun = $params->{cmdlsnaprun}; + my $cmdhlsreact = $params->{cmdhlsreact}; + my $cmdlmjpegrun = $params->{cmdlmjpegrun}; + + my $imgrecendless = $params->{imgrecendless}; + my $imgrecstop = $params->{imgrecstop}; + my $imgdosnap = $params->{imgdosnap}; + my $imgrefresh = $params->{imgrefresh}; + my $imgblank = $params->{imgblank}; + my $imgstop = $params->{imgstop}; + my $imghlsreact = $params->{imghlsreact}; + my $imgmjpegrun = $params->{imgmjpegrun}; + my $imghlsrun = $params->{imghlsrun}; + my $imglh264run = $params->{imglh264run}; + my $imglmjpegrun = $params->{imglmjpegrun}; + my $imglsnaprun = $params->{imglsnaprun}; + + my $ttrefresh = $params->{ttrefresh}; + my $ttsnap = $params->{ttsnap}; + my $ttrecstop = $params->{ttrecstop}; + my $ttrecstart = $params->{ttrecstart}; + my $ttcmdstop = $params->{ttcmdstop}; + my $tthlsreact = $params->{tthlsreact}; + my $ttmjpegrun = $params->{ttmjpegrun}; + my $tthlsrun = $params->{tthlsrun}; + my $ttlrrun = $params->{ttlrrun}; + my $imglrirun = $params->{imglrirun}; + my $tth264run = $params->{tth264run}; + my $ttlmjpegrun = $params->{ttlmjpegrun}; + my $ttlsnaprun = $params->{ttlsnaprun}; + + my ($link,$cause,$ret) = ("","",""); + + my $wltype = $hash->{HELPER}{WLTYPE}; + $link = $hash->{HELPER}{LINK}; + + if($link && $wltype =~ /image|iframe|video|base64img|embed|hls/x) { + if($wltype =~ /image/x) { + if(ReadingsVal($camname, "SVSversion", "8.2.3-5828") eq "8.2.3-5828" && ReadingsVal($camname, "CamVideoType", "") !~ /MJPEG/) { + $ret .= "
Because SVS version 8.2.3-5828 is running you cannot see the MJPEG-Stream. Please upgrade to a higher SVS version !

"; + } else { + if(!$ftui) { + $ret .= "')\">
" if($link); + } else { + $ret .= "
" if($link); + } + + $streamHash->{HELPER}{STREAM} = ""; # Stream für "set popupStream" speichern + $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist + } + + $ret .= "$imgstop "; + $ret .= $imgblank; + + if($hash->{HELPER}{RUNVIEW} =~ /live_fw/x) { + if(ReadingsVal($camname, "Record", "Stop") eq "Stop") { # Aufnahmebutton endlos Start + $ret .= "$imgrecendless "; + } else { # Aufnahmebutton Stop + $ret .= "$imgrecstop "; + } + + $ret .= "$imgdosnap "; + } + + $ret .= ""; + + if(AttrVal($camname,"ptzPanel_use",1) && $hash->{HELPER}{RUNVIEW} =~ /live_fw/x) { + my $ptz_ret = ptzPanel($camname,$strmdev,'',$ftui); + if($ptz_ret) { + $ret .= "$ptz_ret"; + } + } + + if($hash->{HELPER}{AUDIOLINK} && ReadingsVal($camname, "CamAudioType", "Unknown") !~ /Unknown/ && !$hau) { + $ret .= ""; + $ret .= ''; + $ret .= ""; + $ret .= ""; + $ret .= "" if(AttrVal($camname,"ptzPanel_use",0)); + } + + } elsif ($wltype =~ /iframe/x) { + if(!$ftui) { + $ret .= "
" if($link); + } else { + $ret .= "
" if($link); + } + $streamHash->{HELPER}{STREAM} = ""; # Stream für "set popupStream" speichern + $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist + + $ret .= "$imgstop "; + $ret .= "$imgrefresh "; + $ret .= ""; + + if($hash->{HELPER}{AUDIOLINK} && ReadingsVal($camname, "CamAudioType", "Unknown") !~ /Unknown/ && !$hau) { + $ret .= ''; + $ret .= ''; + $ret .= ""; + $ret .= ""; + $ret .= "" if(AttrVal($camname,"ptzPanel_use",0)); + } + + } elsif ($wltype =~ /video/x) { + $ret .= "
"; + + $streamHash->{HELPER}{STREAM} = ""; # Stream für "set popupStream" speichern + + $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist + + $ret .= "$imgstop "; + $ret .= ""; + + if($hash->{HELPER}{AUDIOLINK} && ReadingsVal($camname, "CamAudioType", "Unknown") !~ /Unknown/ && !$hau) { + $ret .= ''; + $ret .= ''; + $ret .= ""; + $ret .= ""; + $ret .= "" if(AttrVal($camname,"ptzPanel_use",0)); + } + + } elsif($wltype =~ /base64img/x) { + if(!$ftui) { + $ret .= "')\">
" if($link); + } else { + $ret .= "
" if($link); + } + $streamHash->{HELPER}{STREAM} = ""; # Stream für "get popupStream" speichern + $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist + + $ret .= "$imgstop "; + $ret .= $imgblank; + $ret .= "$imgdosnap "; + $ret .= ""; + + } elsif($wltype =~ /embed/x) { + if(!$ftui) { + $ret .= "')\">" if($link); + } else { + $ret .= "" if($link); + } + $streamHash->{HELPER}{STREAM} = ""; # Stream für "set popupStream" speichern + $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist + + } elsif($wltype =~ /hls/x) { + $ret .= "
"; + + $streamHash->{HELPER}{STREAM} = ""; # Stream für "set popupStream" speichern + + $streamHash->{HELPER}{STREAMACTIVE} = 1 if($link); # Statusbit wenn ein Stream aktiviert ist + + $ret .= "$imgstop "; + $ret .= "$imgrefresh "; + $ret .= "$imghlsreact "; + $ret .= $imgblank; + + if(ReadingsVal($camname, "Record", "Stop") eq "Stop") { # Aufnahmebutton endlos Start + $ret .= "$imgrecendless "; + } else { # Aufnahmebutton Stop + $ret .= "$imgrecstop "; + } + + $ret .= "$imgdosnap "; + $ret .= ""; + + if(AttrVal($camname,"ptzPanel_use",1)) { + my $ptz_ret = ptzPanel($camname,$strmdev,'',$ftui); + if($ptz_ret) { + $ret .= "$ptz_ret"; + } + } + } + + } else { + my $cam = AttrVal($camname, "alias", $camname); + $cause = "Playback cam \"$cam\" switched off"; + $ret .= "
$cause

"; + $ret .= "$imgmjpegrun "; + $ret .= "$imghlsrun " if(IsCapHLS($hash)); + $ret .= "$imglrirun "; + $ret .= "$imglh264run "; + $ret .= "$imglmjpegrun "; + $ret .= "$imglsnaprun "; + $ret .= ""; + } + + Log3($strmdev, 4, "$strmdev - Link called: $link") if($link); + undef $link; + +return $ret; +} + ############################################################################################# # hls.js laden für Streamimgdevice Typen HLS, RTSP # $m3u8 - ein .m3u8-File oder ein entsprechender Link @@ -10881,12 +11188,12 @@ sub setVersionInfo { if($modules{$type}{META}{x_prereqs_src} && !$hash->{HELPER}{MODMETAABSENT}) { # META-Daten sind vorhanden $modules{$type}{META}{version} = "v".$v; # Version aus META.json überschreiben, Anzeige mit {Dumper $modules{SMAPortal}{META}} - if($modules{$type}{META}{x_version}) { # {x_version} ( nur gesetzt wenn $Id: 49_SSCam.pm 22363 2020-07-06 21:38:30Z DS_Starter $ im Kopf komplett! vorhanden ) + if($modules{$type}{META}{x_version}) { # {x_version} ( nur gesetzt wenn $Id: 49_SSCam.pm 22382 2020-07-10 20:25:50Z DS_Starter $ im Kopf komplett! vorhanden ) $modules{$type}{META}{x_version} =~ s/1.1.1/$v/g; } else { $modules{$type}{META}{x_version} = $v; } - return $@ unless (FHEM::Meta::SetInternals($hash)); # FVERSION wird gesetzt ( nur gesetzt wenn $Id: 49_SSCam.pm 22363 2020-07-06 21:38:30Z DS_Starter $ im Kopf komplett! vorhanden ) + return $@ unless (FHEM::Meta::SetInternals($hash)); # FVERSION wird gesetzt ( nur gesetzt wenn $Id: 49_SSCam.pm 22382 2020-07-10 20:25:50Z DS_Starter $ im Kopf komplett! vorhanden ) if(__PACKAGE__ eq "FHEM::$type" || __PACKAGE__ eq $type) { # es wird mit Packages gearbeitet -> Perl übliche Modulversion setzen # mit {->VERSION()} im FHEMWEB kann Modulversion abgefragt werden @@ -10948,6 +11255,7 @@ return;
  • automatized definition of all in SVS available cameras in FHEM (autocreateCams)
  • save the last recording of camera locally
  • Selection of several cache types for image data storage (attribute cacheType)
  • +
  • execute Zoom actions (only if PTZ camera supports Zoom)

  • @@ -10998,10 +11306,14 @@ return;
    - The PTZ panel (only PTZ cameras) in SSCam use its own icons. - Thereby the system find the icons, in FHEMWEB device the attribute "iconPath" has to be completed by "sscam" - (e.g. "attr WEB iconPath default:fhemSVG:openautomation:sscam"). -

    + SSCam uses its own icons. + In order for the system to find the icons, the attribute iconPath must be supplemented with sscam in the FHEMWEB device.

    + +
      + Example
      + attr WEB iconPath default:fhemSVG:openautomation:sscam +
    +

    @@ -12874,6 +13186,7 @@ attr <name> genericStrmHtmlTag <img $HTMLATTR
  • Automatisiertes Anlegen aller in der SVS vorhandenen Kameras in FHEM (autocreateCams)
  • lokales Abspeichern der letzten Kamera-Aufnahme
  • Auswahl unterschiedlicher Cache-Typen zur Bilddatenspeicherung (Attribut cacheType)
  • +
  • ausführen von Zoom-Aktionen (bei PTZ-Kameras die Zoom unterstützen)

  • @@ -12924,17 +13237,21 @@ attr <name> genericStrmHtmlTag <img $HTMLATTR Meta (FHEM-Modul) Net::SMTP (wenn Bilddaten-Versand verwendet) MIME::Lite (wenn Bilddaten-Versand verwendet) - CHI (wenn Cache verwendet) - CHI::Driver::Redis (wenn Cache verwendet) - Cache::Cache (wenn Cache verwendet) + CHI (wenn Cache verwendet wird) + CHI::Driver::Redis (wenn Cache verwendet wird) + Cache::Cache (wenn Cache verwendet wird)
    - Das PTZ-Paneel (nur PTZ Kameras) in SSCam benutzt einen eigenen Satz Icons. - Damit das System sie findet, ist im FHEMWEB Device das Attribut "iconPath" um "sscam" zu ergänzen - (z.B. "attr WEB iconPath default:fhemSVG:openautomation:sscam"). -

    + SSCam benutzt einen eigenen Satz Icons. + Damit das System sie findet, ist im FHEMWEB Device das Attribut iconPath um sscam zu ergänzen.

    + +
      + Beispiel
      + attr WEB iconPath default:fhemSVG:openautomation:sscam +
    +