This is a module for the MagicMirror².
This module will show a live RTSP video stream and/or periodic snapshots on the Magic Mirror from any IP Security Camera which supports the RTSP protocol and/or can serve a snapshot periodically.
- Supports single or multiple camera streams/snapshots
- For multiple streams: supports rotating through streams in a single window or displaying multiple windows (with customizeable layout)
- Supports fetching snapshots from a file or url when not actively streaming
- Flexible configurations to limit resource use on Raspberry Pi --
- Stops all streams when module is hidden
- Option for AutoPlay or manual starting of stream
- Plays one or all streams (when displaying multiple)
ffmpeg
process only started when active stream window is shown and customizeable delay for shutdown after stopping.- Note: 3 simultaneous streams on a RaspberryPi 3 is about the limit for usability.
- Support for MMM-KeyBindings module for Play/Pause Remote Control and navigation of multiple streams
- New: Hardware-Accelerated Playback on the main screen, with option to use software playback on a remote browser window.
- New: When using
omxplayer
, double-clicking the play button (or longpressing PlayPause key if using MMM-KeyBindings) will play the video fullscreen. Click anywhere once (or Pause with MMM-KeyBindings) to exit.
- For hardware-accelerated streaming,
omxplayer
is required. Install using the system package manager (e.g.apt-get
). Should be installed by default for Raspberry Pi users. Note:omxplayer
will only work on the local display since the video is overlaid directly onto the display. - For software-decoded streaming and/or remote browser viewing:
- Requires
jsmpeg
for front-end display of stream. - Requires
node-rtsp-stream-es6
Node.js module andffmpeg
for backend. - Video flow using
'ffmpeg'
: Camera RTSP Stream →ffmpeg
pre-processor → MM module'snode_helper.js
(vianode-rtsp-stream-es6
) → Web Socket (ws
) → MagicMirror² (viajsmpeg
)
- Requires
First, ensure omxplayer
is installed; if not, install using your system's package manager. For Raspberry Pi:
# Test for installation:
which omxplayer
# Should show "/usr/bin/omxplayer"
# If nothing appears:
apt-get install omxplayer
Second, if the MM² server is on a different machine than the screen you are using to view it: ffmpeg
should be installed.
For Raspberry Pi running Raspbian Jessie a precompiled package can be installed from the following location: (source)
wget https://github.com/ccrisan/motioneye/wiki/precompiled/ffmpeg_3.1.1-1_armhf.deb
dpkg -i ffmpeg_3.1.1-1_armhf.deb
Finally, run the following commands to install the module:
cd ~/MagicMirror/modules
git clone https://github.com/shbatm/MMM-RTSPStream.git
cd MMM-RTSPStream
npm install
Note: Running npm install
will attempt to install the "Graceful Shutdown" patch on the MagicMirror installation. This patch allows the module to properly close all streams when the mirror is shutdown or restarted.
cd ~/MagicMirror/modules/MMM-RTSPStream
git pull
npm install
To use this module, use the configuration builder tool included.
- Install the module (see above).
- From a command-line:
cd ~/MagicMirror/modules/MMM-RTSPStream
http-server -p 9999
- Open a web-browser and navigate to: http://your-mirror-ip:9999/config.html
- Use the tool to generate your config details.
- Copy the section you your MagicMirror
config.js
file. - Stop the http-server with
Ctrl+C
.
It is highly recommended you use the tool included. Several sample configurations are available on this wiki page, detailed options are listed below.
Option | Description |
---|---|
autoStart |
Start the stream(s) automatically Default: true |
rotateStreams |
true : Rotate through all streams in a single windowfalse : Display an individual window for each streamDefault: true |
rotateStreamTimeout |
Time (in sec) to show each stream when rotateStreams is true .Default: 10 |
localPlayer |
Optional: Which player to use for local playback: ffmpeg or omxplayer .Default: omxplayer for hardware acceleration. |
remotePlayer |
Optional: Which player to use for remote browser playback: ffmpeg or none .Default: ffmpeg . Set to none to disable remote playback. |
remoteSnaps |
Optional: If true , module will continue to show snapshots for any remote browser windows while playing the stream locally. Using false will stop updating snapshots when playing locally. Use this option if you only use the local screen to save resources.Default: true . |
showSnapWhenPaused |
Whether or not to show snapshots when the stream(s) is paused. Default: true |
moduleWidth |
Width in px of the module.Note: When rotateStreams is false and multiple streams are used, adjust this value to adjust the number of streams shown side by side. E.G. to show 2 streams side by side, this value should be = 2*(Stream Width + 2*1px (border) + 2*15px (margin)) Default: 354px |
moduleHeight |
Similar (but less critical) to moduleWidth . Adjust to the number of streams high to ensure other modules clear.Default: 240px |
moduleOffset |
Only applies when using OMXPlayer. On some displays, the video does not properly line up with the box on the screen because of differences between JavaScript's reporting and the native display. Entering a pixel value will shift the video over by that amount. Default: 0 Values: Any number (no units) by itself will adjust both top/left the same amount, or you can specify left & top adjustments separately (e.g. moduleOffset: { left: 10, top: -10 } |
streamX |
The individual stream configuration options. See table below for more details. |
Each stream you would like to show should be added to the the configuration by adding a streamX
section, where X
is the number of the stream (e.g. stream1
, stream2
, stream3
, etc.)
config: {
... <other config options; see above> ...,
stream1: {
name: 'BigBuckBunny Test Stream',
url: 'rtsp://184.72.239.149/vod/mp4:BigBuckBunny_115k.mov',
... <additional stream options; see below> ...
},
stream2: {
...
},
...
}
Option | Description |
---|---|
name |
Required The name of the individual stream. Will be displayed when paused if snapshots are turned off. |
url |
The url of the RTSP stream. See this list for paths for some common security cameras. Also see below for how to test for a valid url Username and password should be passed in the url if required: rtsp://<username>:<password>@<hostname>:<port>/<path> Default: A test stream at 'rtsp://184.72.239.149/vod/mp4:BigBuckBunny_115k.mov' , |
hdUrl |
Optional: The url for the "High-Def" stream to use when playing a full screen stream with OMXPlayer. If blank, regular url will be used. |
protocol |
Protocol to use for receiving RTSP stream Default: "tcp" , valid options: "tcp" or "udp" . |
snapshotUrl |
A string with the path to the camera snapshot. This can either be a url to camera itself (if supported) or a file path to where the snapshot is stored every X seconds by the camera. Leave blank to show just the stream title when paused. Username and password should be passed in the url if required: http://<username>:<password>@<hostname>:<port>/<path> |
snapshotType |
The type of snapshot path given Values: url or file Default: url |
snapshotRefresh |
How often to refresh the snapshot image (in sec). Default: 10 (seconds) |
frameRate |
Framerate to use for the RTSP stream. Must be a string. Default: "30" |
width |
The width in px of the stream. |
height |
The height in px of the stream. |
absPosition |
Only required for OMXPlayer Provide an absolute potiion to show the stream. This overrides the automatic window and moduleOffset settings. Format: { top: XX, right: XX, bottom: XX, left: XX } where XX is the pixel position on the screen. |
ffmpegPort |
Only required for ffmpeg Any available port to use for the ffmpeg websocket.Notes: THIS IS NOT THE PORT FOR YOUR CAMERA Camera stream's port must be included in the URL above. This port must be unqiue for each stream added and cannot be used by another service on the server. This is a separate WebSocket from the the Socket.IO connection between the module's script and it's node_helper.js .Default: 9999 |
shutdownDelay |
The time delay (in ms) between when the last client disconnects and the ffmpeg stream actually stops. Once created, the websocket continues to run in the background; however, the ffmpeg process will only process the camera's stream while there are active connections on the socket (e.g. someone is watching the video on the frontend). When rotating through multiple streams this prevents ffmpeg from closing its connection to a stream only to re-open a few seconds later when it comes back through the loop (which reduces the time delay when restarting a stream). To conserve resources on a slow device, you can set this to 0Default: 10000 (ms) |
hideFfmpegOutput |
Whether or not so hide the detailed output from ffmpeg on the console (or logs if using pm2 ).Default: true (output hidden). |
omxRestart |
Automatically restart the OMX Stream every X hours. Default: 24 (hours). |
To test to make sure you have a working url for a camera feed: create a text file with the URL as the first and only line in the file. Save the file as <somename>.strm
and open the file with a video player like VLC.
This module has been tested exclusively with streams for Hikvision (Swann) cameras. You may find that you need to adjust the ffmpeg
settings that are used beyond just frame rate and size. The command line arguements for ffmpeg
can be changed by editing Line 14 of the following file after install. The ffmpeg
arguement list is passed as an array.
~/MagicMirror/modules/MMM-RTSPStream/node_modules/node-rtsp-stream-es6/src/mpeg1muxer.js
The streams can be controlled on the main screen by sending a module notification. Examples:
this.sendNotification("RTSP-PLAY", "all"); // Play all streams (or current stream if rotating)
this.sendNotification("RTSP-PLAY", "streamX"); // Play a particular stream (when not rotating)
this.sendNotification("RTSP-PLAY-FULLSCREEN", "streamX"); // Play a particular stream fullscreen (when using OMXPLAYER)
this.sendNotification("RTSP-PLAY-WINDOW", { name:"streamX", box: { top: XX, right: XX, bottom: XX, left: XX } }); // Play a particular stream in a custom window (when using OMXPLAYER)
this.sendNotification("RTSP-STOP", "all"); // Stop the streams
this.sendNotification("RTSP-STOP", "streamX"); // Stop a particular stream
When using the MMM-KeyBindings Module with the relay server enabled, you can also control the streams via URL calls (replace RTSP-PLAY
with the desired command from above and {{all or streamX}}
with all
or the stream number; without the curly brackets):
http://mirror_ip:8080/MMM-KeyBindings/notify?notification=RTSP-PLAY&payload=%7B+%22stream%22%3A+%22{{all or streamX}}%22+%7D
KeyBindings Configuration (Requires MMM-KeyBindings)
To change from the defaults, add changes to the end of the module's configuration section
Option | Description |
---|---|
keyBindingsMode |
Default: "DEFAULT" - Will respond to a key press if no other module has the focus.Note: - To enable this module to take focus, change this value and add a Focus key name below. |
keyBindings |
The map between this module's key functions and the Keyboard / MMM-KeyBinding's key name that is sent (i.e. when the "MediaPlayPause" key is pressed, it will send a Play action to this module).Previous /Next actions will cycle through the streams when rotateStreams is enabled, and will change which stream is selected when multiple streams are shown (red border will appear around selected stream). |
keyBindings: {
Play: "MediaPlayPause",
Previous: "MediaPreviousTrack",
Next: "MediaNextTrack",
Focus: ""
}
- Add better touchscreen support (use an OnTouch method to play/pause instead of OnClick).
- KNOWN ISSUE: snapshots can be stopped by another "instance" of the mirror running in a different window. Expected behavior: should only affect the local window.
- KNOWN ISSUE:
omxplayer
will only play a certain maximum number of streams at a time. On a RPi3, this appears to be a max of 3. It won't error, it just won't play another stream. To fix: adjust the memory split of the GPU/CPU using theraspi-config
command.
This section includes some untested options and configurations that may be useful in the future.
// Grab a frame every x seconds and save as thumb.png:
ffmpeg -i {RTSP_SOURCE} -f image2 -vf fps=fps=1/{x} -update 1 thumb.png
// Grab the first frame from a stream and save as thumb.jpg
ffmpeg -i {RTSP_SOURCE} -ss 00:00:01.500 -f image2 -vframes 1 thumb.png
(source)