diff --git a/bundles/org.openhab.binding.ipcamera/README.md b/bundles/org.openhab.binding.ipcamera/README.md index 44ad00c7383..9be185f4c7f 100644 --- a/bundles/org.openhab.binding.ipcamera/README.md +++ b/bundles/org.openhab.binding.ipcamera/README.md @@ -115,7 +115,7 @@ Thing ipcamera:hikvision:West "West Camera" port=80, nvrChannel=4, serverPort=54324, - ffmpegOutput="/etc/openhab2/html/cameras/camera-west/", + ffmpegOutput="/var/lib/openhab/ipcamera/West/", ffmpegInput="rtsp://192.168.0.XX:554/ISAPI/Streaming/channels/401" ] ``` @@ -192,7 +192,7 @@ If you do not specify any of these, the binding will use the default which shoul | `ffmpegInput`| Best if this stream is in H.264 format and can be RTSP or HTTP URLs. Leave this blank to use the auto detected RTSP address for ONVIF cameras. | | `ffmpegInputOptions` | Allows you to specify any options before the -i on the commands for FFmpeg. If you have a ESP32 camera that only has a mjpeg stream then make this equal `-f mjpeg`. | | `ffmpegLocation`| The full path including the filename for where you have installed FFmpeg. The default should work for most Linux installs but if using windows use this format: `c:\ffmpeg\bin\ffmpeg.exe` | -| `ffmpegOutput`| The full path where FFmpeg has the ability to write files to ending with a slash. For windows use this format: `c:\openhabconf\html\ipcamera\`. If you would like to expose the GIF files to your static server, you can set it to `/etc/openhab2/html/cameras/camera-name/` | +| `ffmpegOutput`| The full path to a unique folder (different for each camera) where FFmpeg has the ability to write files to ending with a slash. If you leave this blank, the binding will automatically use `$OPENHAB_USERDATA/ipcamera/UID`. See here for where this is located on your installation, | | `hlsOutOptions`| This gives you direct access to specify your own FFmpeg options to be used. Default: `-strict -2 -f lavfi -i aevalsrc=0 -acodec aac -vcodec copy -hls_flags delete_segments -hls_time 2 -hls_list_size 4` | | `gifOutOptions`| This gives you direct access to specify your own FFmpeg options to be used for animated GIF files. Default: `-r 2 -filter_complex scale=-2:360:flags=lanczos,setpts=0.5*PTS,split[o1][o2];[o1]palettegen[p];[o2]fifo[o3];[o3][p]paletteuse` | | `mjpegOptions` | Allows you to change the settings for creating a MJPEG stream from RTSP using FFmpeg. Possible reasons to change this would be to rotate or re-scale the picture from the camera, change the JPG compression for better quality or the FPS rate. | @@ -485,8 +485,7 @@ To use the HLS feature, you need to: + Ensure FFmpeg is installed. + For `generic` cameras, you will need to use the config `ffmpegInput` to provide a HTTP or RTSP URL. -+ Supply a folder that the openhab user has write permissions for to the config `ffmpegOutput`. -+ Set a valid `serverPort` as the default value of -1 will turn this feature off. ++ Set a valid `serverPort` as the value of -1 will turn this feature off. + Consider using a SSD/HDD, zram location, or a tmpfs (ram drive) can be used if you only have micro SD/flash based storage. ### Ram Drive Setup diff --git a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/CameraConfig.java b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/CameraConfig.java index 2f7f96afd83..df2e5725d76 100644 --- a/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/CameraConfig.java +++ b/bundles/org.openhab.binding.ipcamera/src/main/java/org/openhab/binding/ipcamera/internal/CameraConfig.java @@ -94,6 +94,10 @@ public class CameraConfig { return ffmpegOutput; } + public void setFfmpegOutput(String path) { + ffmpegOutput = path; + } + public boolean getPtzContinuous() { return ptzContinuous; } 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 ddc7a5d5929..5dd9481ecdc 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 @@ -57,6 +57,7 @@ import org.openhab.binding.ipcamera.internal.IpCameraDynamicStateDescriptionProv import org.openhab.binding.ipcamera.internal.MyNettyAuthHandler; import org.openhab.binding.ipcamera.internal.StreamServerHandler; import org.openhab.binding.ipcamera.internal.onvif.OnvifConnection; +import org.openhab.core.OpenHAB; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.IncreaseDecreaseType; import org.openhab.core.library.types.OnOffType; @@ -467,7 +468,7 @@ public class IpCameraHandler extends BaseThingHandler { String temp = longUrl; URL url; - if (longUrl.isEmpty() || longUrl.equals("ffmpeg")) { + if (longUrl.isEmpty() || "ffmpeg".equals(longUrl)) { return longUrl; } @@ -772,7 +773,7 @@ public class IpCameraHandler extends BaseThingHandler { if (start) { if (mjpegChannelGroup.isEmpty()) {// first stream being requested. mjpegChannelGroup.add(ctx.channel()); - if (mjpegUri.isEmpty() || mjpegUri.equals("ffmpeg")) { + if (mjpegUri.isEmpty() || "ffmpeg".equals(mjpegUri)) { sendMjpegFirstPacket(ctx); setupFfmpegFormat(FFmpegFormat.MJPEG); } else { @@ -794,7 +795,7 @@ public class IpCameraHandler extends BaseThingHandler { mjpegChannelGroup.remove(ctx.channel()); if (mjpegChannelGroup.isEmpty()) { logger.debug("All ipcamera.mjpeg streams have stopped."); - if (mjpegUri.equals("ffmpeg") || mjpegUri.isEmpty()) { + if ("ffmpeg".equals(mjpegUri) || mjpegUri.isEmpty()) { Ffmpeg localMjpeg = ffmpegMjpeg; if (localMjpeg != null) { localMjpeg.stopConverting(); @@ -979,7 +980,7 @@ public class IpCameraHandler extends BaseThingHandler { localGIF.startConverting(); if (gifHistory.isEmpty()) { gifHistory = gifFilename; - } else if (!gifFilename.equals("ipcamera")) { + } else if (!"ipcamera".equals(gifFilename)) { gifHistory = gifFilename + "," + gifHistory; if (gifHistoryLength > 49) { int endIndex = gifHistory.lastIndexOf(","); @@ -1003,7 +1004,7 @@ public class IpCameraHandler extends BaseThingHandler { localRecord.startConverting(); if (mp4History.isEmpty()) { mp4History = mp4Filename; - } else if (!mp4Filename.equals("ipcamera")) { + } else if (!"ipcamera".equals(mp4Filename)) { mp4History = mp4Filename + "," + mp4History; if (mp4HistoryLength > 49) { int endIndex = mp4History.lastIndexOf(","); @@ -1193,6 +1194,26 @@ public class IpCameraHandler extends BaseThingHandler { onvifCamera.sendPTZRequest(OnvifConnection.RequestType.AbsoluteMove); } + @Override + public void channelLinked(ChannelUID channelUID) { + if (cameraConfig.getServerPort() > 0) { + switch (channelUID.getId()) { + case CHANNEL_MJPEG_URL: + updateState(CHANNEL_MJPEG_URL, new StringType( + "http://" + hostIp + ":" + cameraConfig.getServerPort() + "/ipcamera.mjpeg")); + break; + case CHANNEL_HLS_URL: + updateState(CHANNEL_HLS_URL, + new StringType("http://" + hostIp + ":" + cameraConfig.getServerPort() + "/ipcamera.m3u8")); + break; + case CHANNEL_IMAGE_URL: + updateState(CHANNEL_IMAGE_URL, + new StringType("http://" + hostIp + ":" + cameraConfig.getServerPort() + "/ipcamera.jpg")); + break; + } + } + } + @Override public void handleCommand(ChannelUID channelUID, Command command) { if (command instanceof RefreshType) { @@ -1488,7 +1509,7 @@ public class IpCameraHandler extends BaseThingHandler { if (rtspUri.isEmpty()) { logger.warn("Binding has not been supplied with a FFmpeg Input URL, so some features will not work."); } - if (snapshotUri.isEmpty() || snapshotUri.equals("ffmpeg")) { + if (snapshotUri.isEmpty() || "ffmpeg".equals(snapshotUri)) { snapshotIsFfmpeg(); } else { sendHttpRequest("GET", snapshotUri, null); @@ -1500,7 +1521,7 @@ public class IpCameraHandler extends BaseThingHandler { cameraConfig.getOnvifPort()); onvifCamera.connect(thing.getThingTypeUID().getId().equals(ONVIF_THING)); } - if (snapshotUri.equals("ffmpeg")) { + if ("ffmpeg".equals(snapshotUri)) { snapshotIsFfmpeg(); } else if (!snapshotUri.isEmpty()) { sendHttpRequest("GET", snapshotUri, null); @@ -1664,6 +1685,10 @@ public class IpCameraHandler extends BaseThingHandler { snapshotUri = getCorrectUrlFormat(cameraConfig.getSnapshotUrl()); mjpegUri = getCorrectUrlFormat(cameraConfig.getMjpegUrl()); rtspUri = cameraConfig.getFfmpegInput(); + if (cameraConfig.getFfmpegOutput().isEmpty()) { + cameraConfig + .setFfmpegOutput(OpenHAB.getUserDataFolder() + "/ipcamera/" + this.thing.getUID().getId() + "/"); + } if (cameraConfig.getServerPort() < 1) { logger.warn( 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 12624ebc1f1..576eeda0787 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 @@ -76,10 +76,10 @@ - The full path where FFmpeg has the ability to write files to ending with a slash. For windows use this - format, c:\openhabconf\html\ipcamera\ + Leave this blank and the binding will use the openHAB userdata folder. Alternatively, a unique path for + each camera that ends with a slash and has write permissions can be entered. - /etc/openhab/html/camera1/ + true @@ -218,10 +218,10 @@ - The full path where FFmpeg has the ability to write files to ending with a slash. For windows use this - format, c:\openhabconf\html\ipcamera\ + Leave this blank and the binding will use the openHAB userdata folder. Alternatively, a unique path for + each camera that ends with a slash and has write permissions can be entered. - /etc/openhab/html/camera1/ + true @@ -447,10 +447,10 @@ - The full path where FFmpeg has the ability to write files to ending with a slash. For windows use this - format, c:\openhabconf\html\ipcamera\ + Leave this blank and the binding will use the openHAB userdata folder. Alternatively, a unique path for + each camera that ends with a slash and has write permissions can be entered. - /etc/openhab/html/camera1/ + true @@ -699,10 +699,10 @@ - The full path where FFmpeg has the ability to write files to ending with a slash. For windows use this - format, c:\openhabconf\html\ipcamera\ + Leave this blank and the binding will use the openHAB userdata folder. Alternatively, a unique path for + each camera that ends with a slash and has write permissions can be entered. - /etc/openhab/html/camera1/ + true @@ -997,10 +997,10 @@ - The full path where FFmpeg has the ability to write files to ending with a slash. For windows use this - format, c:\openhabconf\html\ipcamera\ + Leave this blank and the binding will use the openHAB userdata folder. Alternatively, a unique path for + each camera that ends with a slash and has write permissions can be entered. - /etc/openhab/html/camera1/ + true @@ -1271,10 +1271,10 @@ - The full path where FFmpeg has the ability to write files to ending with a slash. For windows use this - format, c:\openhabconf\html\ipcamera\ + Leave this blank and the binding will use the openHAB userdata folder. Alternatively, a unique path for + each camera that ends with a slash and has write permissions can be entered. - /etc/openhab/html/camera1/ + true @@ -1542,10 +1542,10 @@ - The full path where FFmpeg has the ability to write files to ending with a slash. For windows use this - format, c:\openhabconf\html\ipcamera\ + Leave this blank and the binding will use the openHAB userdata folder. Alternatively, a unique path for + each camera that ends with a slash and has write permissions can be entered. - /etc/openhab/html/camera1/ + true @@ -1838,10 +1838,10 @@ - The full path where FFmpeg has the ability to write files to ending with a slash. For windows use this - format, c:\openhabconf\html\ipcamera\ + Leave this blank and the binding will use the openHAB userdata folder. Alternatively, a unique path for + each camera that ends with a slash and has write permissions can be entered. - /etc/openhab/html/camera1/ + true @@ -2121,10 +2121,10 @@ - The full path where FFmpeg has the ability to write files to ending with a slash. For windows use this - format, c:\openhabconf\html\ipcamera\ + Leave this blank and the binding will use the openHAB userdata folder. Alternatively, a unique path for + each camera that ends with a slash and has write permissions can be entered. - /etc/openhab/html/camera1/ + true