Tuesday, 21 August 2012

OpenWRT Mjpg_streamer saving to file

By default when you use the file output plugin with mjpg_streamer you can not set the file name just the folder. So what will happen is that folder will quickly fill with time stamped for name picture files. This could be what you want but this is not what I wanted. I wanted a single file in the web server root so I could include it in the web interface.

There are 2 main steps to achieve this. 

  1. Create a shell script that move the snapshot to the web server root(/www/video0.jpg)  
  2. Change the mjpg-streamer service to output snapshot to file and execute shell script to move snapshot

Step 1. The shell script.
This just moves the snapshot to "/www/video0.jpg". The -f is to force overwrite. I called the script "mjpg_save" and saved it to "/usr/bin/

mv -f "$1" '/www/video0.jpg'

don't forget to chmod +x the script

Step 2. Update the service.
You need to edit "/etc/init.d/mjpg-streameradding "\ --output "output_file.so -c /usr/bin/mjpg_save -d 1500" as per below. 
The "-d 1500" is the delay between saving in ms so 1500 = 1.5 seconds. If you have this set too low mjpg-streamer will not get a chance to finish saving this before starting to save the next picture over it leading to corrupt images.  

root@OpenWrt:/etc/init.d# vi mjpg-streamer

#!/bin/sh /etc/rc.common

# Copyright (C) 2009-2011 OpenWrt.org




error() {
        echo "${initscript}:" "$@" 1>&2

section_enabled() {
        config_get_bool enabled "$1" 'enabled' 0
        [ $enabled -gt 0 ]

start_instance() {
        local s="$1"

        section_enabled "$s" || return 1

        config_get device "$s" 'device'
        config_get resolution "$s" 'resolution'
        config_get fps "$s" 'fps'
        config_get port "$s" 'port'

        [ -c "$device" ] || {
                error "device '$device' does not exist"
                return 1

        service_start /usr/bin/mjpg_streamer --input "input_uvc.so \
                --device $device --fps $fps --resolution $resolution" \
                --output "output_http.so --port $port" \
                --output "output_file.so -c /usr/bin/mjpg_save -d 1500"

stop_instance() {
        local s="$1"

        section_enabled "$s" || return 1

        service_stop /usr/bin/mjpg_streamer

start() {
        config_load 'mjpg-streamer'
        config_foreach start_instance 'mjpg-streamer'

stop() {
        config_load 'mjpg-streamer'
        config_foreach stop_instance 'mjpg-streamer'

If all when well you should be able to access the screenshot from a remote computer using http://routerip/video0.jpg

1 comment:

  1. I ended up rolling back this change. I found the USB drive I was using didn't handle having a file save to it every second for a few weeks running. I found that the mount would change from RW to RO and the router would need a reboot. After removing this it became rock solid again. I might change to a wget script from server side or saving to a FTP server.