diff --git a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/Ffmpeg.java b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/Ffmpeg.java index 2c4098273..3b3cbacdc 100644 --- a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/Ffmpeg.java +++ b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/Ffmpeg.java @@ -54,6 +54,7 @@ public class Ffmpeg { private IpCameraFfmpegThread ipCameraFfmpegThread = new IpCameraFfmpegThread(); private int keepAlive = 8; private String password; + private Boolean notFrozen = true; public Ffmpeg(IpCameraHandler handle, FFmpegFormat format, String ffmpegLocation, String inputArguments, String input, String outArguments, String output, String username, String password) { @@ -131,45 +132,49 @@ public class Ffmpeg { String line = null; while ((line = bufferedReader.readLine()) != null) { logger.debug("{}", line); - if (format.equals(FFmpegFormat.RTSP_ALARMS)) { - if (line.contains("lavfi.")) { - // When the number of pixels that change are below the noise floor we need to look - // across frames to confirm it is motion and not noise. - if (countOfMotions < 10) {// Stop increasing otherwise it will take too long to go OFF. - countOfMotions++; - } - if (countOfMotions > 9) { - ipCameraHandler.motionDetected(CHANNEL_FFMPEG_MOTION_ALARM); - } else if (countOfMotions > 4 && ipCameraHandler.motionThreshold.intValue() > 10) { - ipCameraHandler.motionDetected(CHANNEL_FFMPEG_MOTION_ALARM); - } else if (countOfMotions > 3 && ipCameraHandler.motionThreshold.intValue() > 15) { - ipCameraHandler.motionDetected(CHANNEL_FFMPEG_MOTION_ALARM); - } else if (countOfMotions > 2 && ipCameraHandler.motionThreshold.intValue() > 30) { - ipCameraHandler.motionDetected(CHANNEL_FFMPEG_MOTION_ALARM); - } else if (countOfMotions > 0 && ipCameraHandler.motionThreshold.intValue() > 89) { - ipCameraHandler.motionDetected(CHANNEL_FFMPEG_MOTION_ALARM); - countOfMotions = 4;// Used to debounce the Alarm. - } - } else if (line.contains("speed=")) { - if (countOfMotions > 0) { - if (ipCameraHandler.motionThreshold.intValue() > 89) { - countOfMotions--; + switch (format) { + case RTSP_ALARMS: + if (line.contains("lavfi.")) { + // When the number of pixels that change are below the noise floor we need to look + // across frames to confirm it is motion and not noise. + if (countOfMotions < 10) {// Stop increasing otherwise it takes too long to go OFF + countOfMotions++; } - if (ipCameraHandler.motionThreshold.intValue() > 10) { - countOfMotions -= 2; - } else { - countOfMotions -= 4; + if (countOfMotions > 9) { + ipCameraHandler.motionDetected(CHANNEL_FFMPEG_MOTION_ALARM); + } else if (countOfMotions > 4 && ipCameraHandler.motionThreshold.intValue() > 10) { + ipCameraHandler.motionDetected(CHANNEL_FFMPEG_MOTION_ALARM); + } else if (countOfMotions > 3 && ipCameraHandler.motionThreshold.intValue() > 15) { + ipCameraHandler.motionDetected(CHANNEL_FFMPEG_MOTION_ALARM); + } else if (countOfMotions > 2 && ipCameraHandler.motionThreshold.intValue() > 30) { + ipCameraHandler.motionDetected(CHANNEL_FFMPEG_MOTION_ALARM); + } else if (countOfMotions > 0 && ipCameraHandler.motionThreshold.intValue() > 89) { + ipCameraHandler.motionDetected(CHANNEL_FFMPEG_MOTION_ALARM); + countOfMotions = 4;// Used to debounce the Alarm. } - if (countOfMotions <= 0) { - ipCameraHandler.noMotionDetected(CHANNEL_FFMPEG_MOTION_ALARM); - countOfMotions = 0; + } else if (line.contains("speed=")) { + if (countOfMotions > 0) { + if (ipCameraHandler.motionThreshold.intValue() > 89) { + countOfMotions--; + } + if (ipCameraHandler.motionThreshold.intValue() > 10) { + countOfMotions -= 2; + } else { + countOfMotions -= 4; + } + if (countOfMotions <= 0) { + ipCameraHandler.noMotionDetected(CHANNEL_FFMPEG_MOTION_ALARM); + countOfMotions = 0; + } } + } else if (line.contains("silence_start")) { + ipCameraHandler.noAudioDetected(); + } else if (line.contains("silence_end")) { + ipCameraHandler.audioDetected(); } - } else if (line.contains("silence_start")) { - ipCameraHandler.noAudioDetected(); - } else if (line.contains("silence_end")) { - ipCameraHandler.audioDetected(); - } + case SNAPSHOT: + notFrozen = true;// RTSP_ALARMS and SNAPSHOT both set this to true as there is no break. + break; } } } @@ -212,7 +217,10 @@ public class Ffmpeg { public boolean getIsAlive() { Process localProcess = process; if (localProcess != null) { - return localProcess.isAlive(); + if (localProcess.isAlive() && notFrozen) { + notFrozen = false; // Any process output will set this back to true before next check. + return true; + } } return false; } diff --git a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/HttpOnlyHandler.java b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/HttpOnlyHandler.java index ac7bc83d9..6dadb556e 100644 --- a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/HttpOnlyHandler.java +++ b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/HttpOnlyHandler.java @@ -62,11 +62,11 @@ public class HttpOnlyHandler extends ChannelDuplexHandler { switch (channelUID.getId()) { case CHANNEL_THRESHOLD_AUDIO_ALARM: if (OnOffType.ON.equals(command)) { - ipCameraHandler.audioAlarmEnabled = true; + ipCameraHandler.ffmpegAudioAlarmEnabled = true; } else if (OnOffType.OFF.equals(command) || DecimalType.ZERO.equals(command)) { - ipCameraHandler.audioAlarmEnabled = false; + ipCameraHandler.ffmpegAudioAlarmEnabled = false; } else { - ipCameraHandler.audioAlarmEnabled = true; + ipCameraHandler.ffmpegAudioAlarmEnabled = true; try { ipCameraHandler.audioThreshold = Integer.valueOf(command.toString()); } catch (NumberFormatException e) { diff --git a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/handler/IpCameraHandler.java b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/handler/IpCameraHandler.java index 500f6e188..08fd53083 100644 --- a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/handler/IpCameraHandler.java +++ b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/handler/IpCameraHandler.java @@ -183,8 +183,8 @@ public class IpCameraHandler extends BaseThingHandler { public BigDecimal motionThreshold = BigDecimal.ZERO; public int audioThreshold = 35; public boolean streamingSnapshotMjpeg = false; - public boolean motionAlarmEnabled = false; - public boolean audioAlarmEnabled = false; + public boolean ffmpegMotionAlarmEnabled = false; + public boolean ffmpegAudioAlarmEnabled = false; public boolean ffmpegSnapshotGeneration = false; public boolean snapshotPolling = false; public OnvifConnection onvifCamera = new OnvifConnection(this, "", "", ""); @@ -868,20 +868,20 @@ public class IpCameraHandler extends BaseThingHandler { Ffmpeg localAlarms = ffmpegRtspHelper; if (localAlarms != null) { localAlarms.stopConverting(); - if (!audioAlarmEnabled && !motionAlarmEnabled) { + if (!ffmpegAudioAlarmEnabled && !ffmpegMotionAlarmEnabled) { return; } } String input = (cameraConfig.getAlarmInputUrl().isEmpty()) ? rtspUri : cameraConfig.getAlarmInputUrl(); String filterOptions = ""; - if (!audioAlarmEnabled) { + if (!ffmpegAudioAlarmEnabled) { filterOptions = "-an"; } else { filterOptions = "-af silencedetect=n=-" + audioThreshold + "dB:d=2"; } - if (!motionAlarmEnabled && !ffmpegSnapshotGeneration) { + if (!ffmpegMotionAlarmEnabled && !ffmpegSnapshotGeneration) { filterOptions = filterOptions.concat(" -vn"); - } else if (motionAlarmEnabled && !cameraConfig.getMotionOptions().isEmpty()) { + } else if (ffmpegMotionAlarmEnabled && !cameraConfig.getMotionOptions().isEmpty()) { String usersMotionOptions = cameraConfig.getMotionOptions(); if (usersMotionOptions.startsWith("-")) { // Need to put the users custom options first in the chain before the motion is detected @@ -891,7 +891,7 @@ public class IpCameraHandler extends BaseThingHandler { filterOptions = filterOptions + " " + usersMotionOptions + " -vf select='gte(scene," + motionThreshold.divide(BIG_DECIMAL_SCALE_MOTION) + ")',metadata=print"; } - } else if (motionAlarmEnabled) { + } else if (ffmpegMotionAlarmEnabled) { filterOptions = filterOptions.concat(" -vf select='gte(scene," + motionThreshold.divide(BIG_DECIMAL_SCALE_MOTION) + ")',metadata=print"); } @@ -924,9 +924,9 @@ public class IpCameraHandler extends BaseThingHandler { if (ffmpegSnapshot == null) { if (inputOptions.isEmpty()) { // iFrames only - inputOptions = "-threads 1 -skip_frame nokey -hide_banner -loglevel warning"; + inputOptions = "-threads 1 -skip_frame nokey -hide_banner"; } else { - inputOptions += " -threads 1 -skip_frame nokey -hide_banner -loglevel warning"; + inputOptions += " -threads 1 -skip_frame nokey -hide_banner"; } ffmpegSnapshot = new Ffmpeg(this, format, cameraConfig.getFfmpegLocation(), inputOptions, rtspUri, cameraConfig.getSnapshotOptions(), "http://127.0.0.1:" + SERVLET_PORT + "/ipcamera/" @@ -1106,12 +1106,12 @@ public class IpCameraHandler extends BaseThingHandler { return; case CHANNEL_FFMPEG_MOTION_CONTROL: if (OnOffType.ON.equals(command)) { - motionAlarmEnabled = true; + ffmpegMotionAlarmEnabled = true; } else if (OnOffType.OFF.equals(command) || DecimalType.ZERO.equals(command)) { - motionAlarmEnabled = false; + ffmpegMotionAlarmEnabled = false; noMotionDetected(CHANNEL_FFMPEG_MOTION_ALARM); } else if (command instanceof PercentType) { - motionAlarmEnabled = true; + ffmpegMotionAlarmEnabled = true; motionThreshold = ((PercentType) command).toBigDecimal(); } setupFfmpegFormat(FFmpegFormat.RTSP_ALARMS); @@ -1564,9 +1564,15 @@ public class IpCameraHandler extends BaseThingHandler { + cameraConfig.getPassword()); break; } - Ffmpeg localHLS = ffmpegHLS; - if (localHLS != null) { - localHLS.checkKeepAlive(); + Ffmpeg localFfmpeg = ffmpegHLS; + if (localFfmpeg != null) { + localFfmpeg.checkKeepAlive(); + } + if (ffmpegMotionAlarmEnabled || ffmpegAudioAlarmEnabled) { + localFfmpeg = ffmpegRtspHelper; + if (localFfmpeg == null || !localFfmpeg.getIsAlive()) { + setupFfmpegFormat(FFmpegFormat.RTSP_ALARMS); + } } if (openChannels.size() > 10) { logger.debug("There are {} open Channels being tracked.", openChannels.size()); diff --git a/bundles/org.openhab.binding.ipcamera/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.ipcamera/src/main/resources/OH-INF/thing/thing-types.xml index 06ef7a3d8..62090a3ff 100644 --- a/bundles/org.openhab.binding.ipcamera/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.ipcamera/src/main/resources/OH-INF/thing/thing-types.xml @@ -1177,6 +1177,8 @@ + + @@ -1727,6 +1729,7 @@ +