[ipcamera] FFmpeg based alarms will now auto restart if stopped (#13446)
* FFmpeg alarms now auto restart Signed-off-by: Matthew Skinner <matt@pcmus.com>
This commit is contained in:
parent
a646fe34e0
commit
cc50497f31
@ -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,11 +132,12 @@ public class Ffmpeg {
|
||||
String line = null;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
logger.debug("{}", line);
|
||||
if (format.equals(FFmpegFormat.RTSP_ALARMS)) {
|
||||
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 will take too long to go OFF.
|
||||
if (countOfMotions < 10) {// Stop increasing otherwise it takes too long to go OFF
|
||||
countOfMotions++;
|
||||
}
|
||||
if (countOfMotions > 9) {
|
||||
@ -170,6 +172,9 @@ public class Ffmpeg {
|
||||
} 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;
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -1177,6 +1177,8 @@
|
||||
<channel id="ffmpegMotionAlarm" typeId="ffmpegMotionAlarm"/>
|
||||
<channel id="externalMotion" typeId="externalMotion"/>
|
||||
<channel id="motionAlarm" typeId="motionAlarm"/>
|
||||
<channel id="thresholdAudioAlarm" typeId="thresholdAudioAlarm"/>
|
||||
<channel id="audioAlarm" typeId="audioAlarm"/>
|
||||
<channel id="activateAlarmOutput" typeId="activateAlarmOutput"/>
|
||||
<channel id="activateAlarmOutput2" typeId="activateAlarmOutput2"/>
|
||||
<channel id="doorBell" typeId="doorBell"/>
|
||||
@ -1727,6 +1729,7 @@
|
||||
<channel id="enableFieldDetectionAlarm" typeId="enableFieldDetectionAlarm"/>
|
||||
<channel id="fieldDetectionAlarm" typeId="fieldDetectionAlarm"/>
|
||||
<channel id="enableAudioAlarm" typeId="enableAudioAlarm"/>
|
||||
<channel id="thresholdAudioAlarm" typeId="thresholdAudioAlarm"/>
|
||||
<channel id="audioAlarm" typeId="audioAlarm"/>
|
||||
<channel id="activateAlarmOutput" typeId="activateAlarmOutput"/>
|
||||
<channel id="enableExternalAlarmInput" typeId="enableExternalAlarmInput"/>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user