This widget allows you to view your live camera with the more compatible MJPEG format for the live stream, and when a MP4 recording is made via the ipCamera binding, it will allow the folder icon to be clicked to show the recordings to be reviewed. Useful to show the number of people that have rung your doorbell, or driven up your driveway allowing a quick review of the recordings.
MJPEG has low latency and good compatibility with browsers.
There is a HLS version of this widget that will give higher resolution at the expense of latency and less compatible.
Once you have seen all the recordings, you can click on the “X” button to clear the counter which will NOT delete the recordings. The X just resets the number of how many recordings that have been made since you last reviewed and cleared the counter. The video camera icon returns you to the live view. You can enter full screen mode if the recording contains something of interest.
Setup
To get this widget working you MUST name your items with the default naming that occurs when you use the OH3 feature “Add equipment to model” from the things channel page (found at very bottom of page). If you manually create items, then the following items will need to be named as follows and linked to the channels of the same name:
EquipmentName (this is the item you select in the widget’s setup)
EquipmentName_MP4History
EquipmentName_MP4HistoryLength
The Base Url
config needs to be set to use your openHAB IP address and also be updated to include the cameras unique ID. This will look like this and will end with a /
http://192.168.1.2:8080/ipcamera/doorbell/
Resources
uid: CameraMjpegHistory
tags: []
props:
parameters:
- context: item
label: Select the Camera (Equipment)
name: camera
required: true
type: TEXT
- description: "example: http://192.168.1.2:8080/ipcamera/CameraUniqueID/"
label: Base URL
name: cameraBaseURL
required: true
type: TEXT
- description: ON will use the lower bandwidth autofps.mjpeg stream otherwise ipcamera.mjpeg
label: Use Lower Bandwidth Stream
name: lowerBandwidth
required: true
type: BOOLEAN
timestamp: Jun 2, 2023, 6:27:27 PM
component: f7-card
config:
key: "=(vars.selected === undefined) ? Math.random() : Math.random() + vars.selected"
style:
--f7-card-margin-horizontal: 0px
--f7-card-margin-vertical: 0px
border-radius: 6px
height: 9.4rem
width: 15.2rem
slots:
default:
- component: oh-video-card
config:
hideControls: false
startManually: false
url: =props.cameraBaseURL + items[props.camera + '_MP4History'].state.split(",")[vars.selected] +".mp4"
visible: =vars.archive == 2
- component: oh-image-card
config:
style:
border-radius: 6px
height: auto
margin: 0px
width: 100%
url: "=props.lowerBandwidth === true ? (props.cameraBaseURL + 'autofps.mjpeg') : (props.cameraBaseURL + 'ipcamera.mjpeg')"
visible: =vars.archive != 2
- component: f7-row
config:
class: no-gap
style:
position: absolute
top: 0px
width: 99%
z-index: 2
slots:
default:
- component: oh-button
config:
action: variable
actionVariable: archive
actionVariableValue: 2
iconColor: white
iconF7: folder
iconSize: 28
style:
margin: -2px
visible: "=(items[props.camera + '_MP4History'].state !== NULL ? vars.archive !== 2 : false)"
z-index: 2
- component: Label
config:
style:
color: white
font-size: 9px
left: 18px
position: absolute
top: 12px
z-index: -1
text: =items[props.camera+'_MP4HistoryLength'].state
visible: =vars.archive != 2 && items[props.camera+'_MP4HistoryLength'].state > 0
- component: Label
config:
style:
color: white
font-size: 9px
left: 12px
position: absolute
top: 9px
z-index: -1
text: =(vars.selected+1)
visible: =vars.archive == 2
- component: oh-button
config:
action: variable
actionVariable: archive
actionVariableValue: 1
iconColor: white
iconF7: videocam
iconSize: 28
style:
margin: -2px
visible: =(vars.archive == 2)
- component: oh-button
config:
action: variable
actionVariable: selected
actionVariableValue: =(items[props.camera +'_MP4HistoryLength'].state-1)
iconColor: white
iconF7: backward_end
iconSize: 28
style:
margin: -2px
visible: =vars.archive == 2 && items[props.camera+'_MP4HistoryLength'].state > 0
- component: oh-button
config:
action: variable
actionVariable: selected
actionVariableValue: =(vars.selected+1 < items[props.camera +'_MP4HistoryLength'].state)?(vars.selected+1):(items[props.camera +'_MP4HistoryLength'].state-1)
iconColor: white
iconF7: arrowtriangle_left
iconSize: 28
style:
margin: -2px
visible: =vars.archive == 2 && items[props.camera+'_MP4HistoryLength'].state > 0
- component: oh-button
config:
action: variable
actionVariable: selected
actionVariableValue: =(vars.selected != 0)?(vars.selected-1):(0)
iconColor: white
iconF7: arrowtriangle_right
iconSize: 28
style:
margin: -2px
visible: =vars.archive == 2 && items[props.camera+'_MP4HistoryLength'].state > 0
- component: oh-button
config:
action: variable
actionVariable: selected
actionVariableValue: 0
iconColor: white
iconF7: forward_end
iconSize: 28
style:
margin: -2px
visible: =vars.archive == 2 && items[props.camera+'_MP4HistoryLength'].state > 0
- component: oh-button
config:
action: toggle
actionCommand: "0"
actionItem: =props.camera+'_MP4HistoryLength'
iconColor: white
iconF7: clear
iconSize: 28
style:
margin: -2px
tooltip: Clear cameras mp4 history
visible: =vars.archive == 2 && items[props.camera+'_MP4HistoryLength'].state > 0