summaryrefslogtreecommitdiffhomepage
path: root/applications/luci-app-mjpg-streamer
diff options
context:
space:
mode:
Diffstat (limited to 'applications/luci-app-mjpg-streamer')
-rw-r--r--applications/luci-app-mjpg-streamer/Makefile2
-rw-r--r--applications/luci-app-mjpg-streamer/htdocs/luci-static/resources/view/mjpg-streamer/mjpg-streamer.js264
-rw-r--r--applications/luci-app-mjpg-streamer/luasrc/model/cbi/mjpg-streamer.lua224
-rw-r--r--applications/luci-app-mjpg-streamer/root/usr/share/luci/menu.d/luci-app-mjpg-streamer.json13
-rw-r--r--applications/luci-app-mjpg-streamer/root/usr/share/rpcd/acl.d/luci-app-mjpg-streamer.json10
5 files changed, 280 insertions, 233 deletions
diff --git a/applications/luci-app-mjpg-streamer/Makefile b/applications/luci-app-mjpg-streamer/Makefile
index 876e99dd41..b4f1f14127 100644
--- a/applications/luci-app-mjpg-streamer/Makefile
+++ b/applications/luci-app-mjpg-streamer/Makefile
@@ -7,7 +7,7 @@
include $(TOPDIR)/rules.mk
LUCI_TITLE:=MJPG-Streamer service configuration module
-LUCI_DEPENDS:=+luci-compat +mjpg-streamer
+LUCI_DEPENDS:= +mjpg-streamer
include ../../luci.mk
diff --git a/applications/luci-app-mjpg-streamer/htdocs/luci-static/resources/view/mjpg-streamer/mjpg-streamer.js b/applications/luci-app-mjpg-streamer/htdocs/luci-static/resources/view/mjpg-streamer/mjpg-streamer.js
new file mode 100644
index 0000000000..6fb6f3c27b
--- /dev/null
+++ b/applications/luci-app-mjpg-streamer/htdocs/luci-static/resources/view/mjpg-streamer/mjpg-streamer.js
@@ -0,0 +1,264 @@
+'use strict';
+'require view';
+'require form';
+'require uci';
+'require ui';
+'require poll';
+
+/* Copyright 2014 Roger D < rogerdammit@gmail.com>
+Licensed to the public under the Apache License 2.0. */
+
+return view.extend({
+ load: function () {
+ var self = this;
+ poll.add(function () {
+ self.render();
+ }, 5);
+
+ document
+ .querySelector('head')
+ .appendChild(
+ E('style', { type: 'text/css' }, [
+ '.img-preview {display: inline-block !important;height: auto;width: 640px;padding: 4px;line-height: 1.428571429;background-color: #fff;border: 1px solid #ddd;border-radius: 4px;-webkit-transition: all .2s ease-in-out;transition: all .2s ease-in-out;margin-bottom: 5px;display: none;}',
+ ]),
+ );
+
+ return Promise.all([uci.load('mjpg-streamer')]);
+ },
+ render: function () {
+ var m, s, o;
+
+ m = new form.Map('mjpg-streamer', 'MJPG-streamer', _('mjpg streamer is a streaming application for Linux-UVC compatible webcams'));
+
+ //General settings
+
+ var section_gen = m.section(form.TypedSection, 'mjpg-streamer', _('General'));
+ section_gen.addremove = false;
+ section_gen.anonymous = true;
+
+ var enabled = section_gen.option(form.Flag, 'enabled', _('Enabled'), _('Enable MJPG-streamer'));
+
+ var input = section_gen.option(form.ListValue, 'input', _('Input plugin'));
+ input.depends('enabled', '1');
+ input.value('uvc', 'UVC');
+ // input: value("file", "File")
+ input.optional = false;
+
+ var output = section_gen.option(form.ListValue, 'output', _('Output plugin'));
+ output.depends('enabled', '1');
+ output.value('http', 'HTTP');
+ output.value('file', 'File');
+ output.optional = false;
+
+ //Plugin settings
+
+ s = m.section(form.TypedSection, 'mjpg-streamer', _('Plugin settings'));
+ s.addremove = false;
+ s.anonymous = true;
+
+ s.tab('output_http', _('HTTP output'));
+ s.tab('output_file', _('File output'));
+ s.tab('input_uvc', _('UVC input'));
+ // s: tab("input_file", _("File input"))
+
+ // Input UVC settings
+
+ var this_tab = 'input_uvc';
+
+ var device = s.taboption(this_tab, form.Value, 'device', _('Device'));
+ device.default = '/dev/video0';
+ //device.datatype = "device"
+ device.value('/dev/video0', '/dev/video0');
+ device.value('/dev/video1', '/dev/video1');
+ device.value('/dev/video2', '/dev/video2');
+ device.optional = false;
+
+ var resolution = s.taboption(this_tab, form.Value, 'resolution', _('Resolution'));
+ resolution.default = '640x480';
+ resolution.value('320x240', '320x240');
+ resolution.value('640x480', '640x480');
+ resolution.value('800x600', '800x600');
+ resolution.value('864x480', '864x480');
+ resolution.value('960x544', '960x544');
+ resolution.value('960x720', '960x720');
+ resolution.value('1280x720', '1280x720');
+ resolution.value('1280x960', '1280x960');
+ resolution.value('1920x1080', '1920x1080');
+ resolution.optional = true;
+
+ var fps = s.taboption(this_tab, form.Value, 'fps', _('Frames per second'));
+ fps.datatype = 'and(uinteger, min(1))';
+ fps.placeholder = '5';
+ fps.optional = true;
+
+ var yuv = s.taboption(this_tab, form.Flag, 'yuv', _('Enable YUYV format'), _('Automatic disabling of MJPEG mode'));
+
+ var quality = s.taboption(
+ this_tab,
+ form.Value,
+ 'quality',
+ _('JPEG compression quality'),
+ _('Set the quality in percent. This setting activates YUYV format, disables MJPEG'),
+ );
+ quality.datatype = 'range(0, 100)';
+
+ var minimum_size = s.taboption(
+ this_tab,
+ form.Value,
+ 'minimum_size',
+ _('Drop frames smaller than this limit'),
+ _('Set the minimum size if the webcam produces small-sized garbage frames. May happen under low light conditions'),
+ );
+ minimum_size.datatype = 'uinteger';
+
+ var no_dynctrl = s.taboption(this_tab, form.Flag, 'no_dynctrl', _("Don't initialize dynctrls"), _('Do not initialize dynctrls of Linux-UVC driver'));
+
+ var led = s.taboption(this_tab, form.ListValue, 'led', _('Led control'));
+ led.value('on', _('On'));
+ led.value('off', _('Off'));
+ led.value('blink', _('Blink'));
+ led.value('auto', _('Auto'));
+ led.optional = true;
+
+ // Output HTTP settings
+
+ this_tab = 'output_http';
+
+ var port = s.taboption(this_tab, form.Value, 'port', _('Port'), _('TCP port for this HTTP server'));
+ port.datatype = 'port';
+ port.placeholder = '8080';
+
+ var enable_auth = s.taboption(this_tab, form.Flag, 'enable_auth', _('Authentication required'), _('Ask for username and password on connect'));
+ enable_auth.default = false;
+
+ var username = s.taboption(this_tab, form.Value, 'username', _('Username'));
+ username.depends('enable_auth', '1');
+ username.optional = false;
+
+ var password = s.taboption(this_tab, form.Value, 'password', _('Password'));
+ password.depends('enable_auth', '1');
+ password.password = true;
+ password.optional = false;
+ password.default = false;
+
+ var www = s.taboption(this_tab, form.Value, 'www', _('WWW folder'), _('Folder that contains webpages'));
+ www.datatype = 'directory';
+ www.default = '/www/webcam/';
+ www.optional = false;
+
+
+ function init_stream() {
+ console.log('init_stream');
+ start_stream();
+ }
+
+ function _start_stream() {
+ console.log('_start_stream');
+
+ var port = uci.get('mjpg-streamer', 'core', 'port');
+
+ if (uci.get('mjpg-streamer', 'core', 'enable_auth') == '1') {
+ var user = uci.get('mjpg-streamer', 'core', 'username');
+ var pass = uci.get('mjpg-streamer', 'core', 'password');
+ var login = user + ':' + pass + '@';
+ } else {
+ var login = '';
+ }
+
+ var img = document.getElementById('video_preview') || video_preview;
+ img.src = 'http://' + login + location.hostname + ':' + port + '/?action=snapshot' + '&t=' + new Date().getTime();
+ }
+
+ function start_stream() {
+ console.log('start_stream');
+
+ setTimeout(function () {
+ _start_stream();
+ }, 500);
+ }
+
+ function on_error() {
+ console.log('on_error');
+
+ var img = video_preview;
+ img.style.display = 'none';
+
+ var stream_stat = document.getElementById('stream_status') || stream_status;
+ stream_stat.style.display = 'block';
+
+ start_stream();
+ }
+
+ function on_load() {
+ console.log('on_load');
+
+ var img = video_preview;
+ img.style.display = 'block';
+
+ var stream_stat = stream_status;
+ stream_stat.style.display = 'none';
+ }
+
+ //HTTP preview
+ var video_preview = E('img', {
+ 'id': 'video_preview',
+ 'class': 'img-preview',
+ 'error': on_error,
+ 'load': on_load,
+ });
+
+ var stream_status = E(
+ 'p',
+ {
+ 'id': 'stream_status',
+ 'style': 'text-align: center; color: orange; font-weight: bold;',
+ },
+ _('Stream unavailable'),
+ );
+
+
+ init_stream();
+
+ var preview = s.taboption(this_tab, form.DummyValue, '_dummy');
+ preview.render = L.bind(function (view, section_id) {
+ return E([], [
+ video_preview,
+ stream_status
+ ]);
+ }, preview, this);
+ preview.depends('output', 'http');
+
+ //Output file settings
+
+ this_tab = 'output_file';
+
+ var folder = s.taboption(this_tab, form.Value, 'folder', _('Folder'), _('Set folder to save pictures'));
+ folder.placeholder = '/tmp/images';
+ folder.datatype = 'directory';
+
+ //mjpeg=s.taboption(this_tab, Value, "mjpeg", _("Mjpeg output"), _("Check to save the stream to an mjpeg file"))
+
+ var delay = s.taboption(this_tab, form.Value, 'delay', _('Interval between saving pictures'), _('Set the interval in millisecond'));
+ delay.placeholder = '5000';
+ delay.datatype = 'uinteger';
+
+ var ringbuffer = s.taboption(this_tab, form.Value, 'ringbuffer', _('Ring buffer size'), _('Max. number of pictures to hold'));
+ ringbuffer.placeholder = '10';
+ ringbuffer.datatype = 'uinteger';
+
+ var exceed = s.taboption(this_tab, form.Value, 'exceed', _('Exceed'), _('Allow ringbuffer to exceed limit by this amount'));
+ exceed.datatype = 'uinteger';
+
+ var command = s.taboption(
+ this_tab,
+ form.Value,
+ 'command',
+ _('Command to run'),
+ _('Execute command after saving picture. Mjpg-streamer parses the filename as first parameter to your script.'),
+ );
+
+ var link = s.taboption(this_tab, form.Value, 'link', _('Link newest picture to fixed file name'), _('Link the last picture in ringbuffer to fixed named file provided.'));
+
+ return m.render();
+ },
+});
diff --git a/applications/luci-app-mjpg-streamer/luasrc/model/cbi/mjpg-streamer.lua b/applications/luci-app-mjpg-streamer/luasrc/model/cbi/mjpg-streamer.lua
deleted file mode 100644
index 86ea302c2f..0000000000
--- a/applications/luci-app-mjpg-streamer/luasrc/model/cbi/mjpg-streamer.lua
+++ /dev/null
@@ -1,224 +0,0 @@
--- Copyright 2014 Roger D <rogerdammit@gmail.com>
--- Licensed to the public under the Apache License 2.0.
-
-m = Map("mjpg-streamer", "MJPG-streamer", translate("mjpg streamer is a streaming application for Linux-UVC compatible webcams"))
-
---- General settings ---
-
-section_gen = m:section(TypedSection, "mjpg-streamer", translate("General"))
- section_gen.addremove=false
- section_gen.anonymous=true
-
-enabled = section_gen:option(Flag, "enabled", translate("Enabled"), translate("Enable MJPG-streamer"))
-
-input = section_gen:option(ListValue, "input", translate("Input plugin"))
- input:depends("enabled", "1")
- input:value("uvc", "UVC")
- ---input:value("file", "File")
- input.optional = false
-
-output = section_gen:option(ListValue, "output", translate("Output plugin"))
- output:depends("enabled", "1")
- output:value("http", "HTTP")
- output:value("file", "File")
- output.optional = false
-
-
---- Plugin settings ---
-
-s = m:section(TypedSection, "mjpg-streamer", translate("Plugin settings"))
- s.addremove=false
- s.anonymous=true
-
- s:tab("output_http", translate("HTTP output"))
- s:tab("output_file", translate("File output"))
- s:tab("input_uvc", translate("UVC input"))
- ---s:tab("input_file", translate("File input"))
-
-
---- Input UVC settings ---
-
-this_tab = "input_uvc"
-
-device = s:taboption(this_tab, Value, "device", translate("Device"))
- device.default="/dev/video0"
- --device.datatype = "device"
- device:value("/dev/video0", "/dev/video0")
- device:value("/dev/video1", "/dev/video1")
- device:value("/dev/video2", "/dev/video2")
- device.optional = false
-
-resolution = s:taboption(this_tab, Value, "resolution", translate("Resolution"))
- resolution.default = "640x480"
- resolution:value("320x240", "320x240")
- resolution:value("640x480", "640x480")
- resolution:value("800x600", "800x600")
- resolution:value("864x480", "864x480")
- resolution:value("960x544", "960x544")
- resolution:value("960x720", "960x720")
- resolution:value("1280x720", "1280x720")
- resolution:value("1280x960", "1280x960")
- resolution:value("1920x1080", "1920x1080")
- resolution.optional = true
-
-fps = s:taboption(this_tab, Value, "fps", translate("Frames per second"))
- fps.datatype = "and(uinteger, min(1))"
- fps.placeholder = "5"
- fps.optional = true
-
-yuv = s:taboption(this_tab, Flag, "yuv", translate("Enable YUYV format"), translate("Automatic disabling of MJPEG mode"))
-
-quality = s:taboption(this_tab, Value, "quality", translate("JPEG compression quality"), translate("Set the quality in percent. This setting activates YUYV format, disables MJPEG"))
- quality.datatype = "range(0, 100)"
-
-minimum_size = s:taboption(this_tab, Value, "minimum_size", translate("Drop frames smaller than this limit"),translate("Set the minimum size if the webcam produces small-sized garbage frames. May happen under low light conditions"))
- minimum_size.datatype = "uinteger"
-
-no_dynctrl = s:taboption(this_tab, Flag, "no_dynctrl", translate("Don't initialize dynctrls"), translate("Do not initialize dynctrls of Linux-UVC driver"))
-
-led = s:taboption(this_tab, ListValue, "led", translate("Led control"))
- led:value("on", translate("On"))
- led:value("off", translate("Off"))
- led:value("blink", translate("Blink"))
- led:value("auto", translate("Auto"))
- led.optional = true
-
-
---- Output HTTP settings ---
-
-this_tab = "output_http"
-
-port=s:taboption(this_tab, Value, "port", translate("Port"), translate("TCP port for this HTTP server"))
- port.datatype = "port"
- port.placeholder = "8080"
-
-enable_auth = s:taboption(this_tab, Flag, "enable_auth", translate("Authentication required"), translate("Ask for username and password on connect"))
- enable_auth.default = false
-
-username = s:taboption(this_tab, Value, "username", translate("Username"))
- username:depends("enable_auth", "1")
- username.optional = false
-
-password = s:taboption(this_tab, Value, "password", translate("Password"))
- password:depends("enable_auth", "1")
- password.password = true
- password.optional = false
- password.default = false
-
-www = s:taboption(this_tab, Value, "www", translate("WWW folder"), translate("Folder that contains webpages"))
- www.datatype = "directory"
- www.default = "/www/webcam/"
- www.optional = false
-
-
---- HTTP preview ---
-
-html = [[
-<style media="screen" type="text/css">
- .img-preview {
- display: inline-block;
- height: auto;
- width: 640px;
- padding: 4px;
- line-height: 1.428571429;
- background-color: #fff;
- border: 1px solid #ddd;
- border-radius: 4px;
- -webkit-transition: all .2s ease-in-out;
- transition: all .2s ease-in-out;
- margin-bottom: 5px;
- display: none;
- }
-</style>
-
-<div id="videodiv">
- <img id="video_preview" class="img-preview" onerror="on_error()" onload="on_load()"/>
- <p id="stream_status" style="text-align: center; color: orange; font-weight:bold;">Stream unavailable</p>
-</div>
-
-<script type="text/javascript">
-
-function init_stream() {
- console.log('init_stream');
- start_stream()
-}
-
-function _start_stream() {
- console.log('_start_stream');
-
- port = document.getElementById('cbid.mjpg-streamer.core.port').value
-
- if (document.getElementById('cbid.mjpg-streamer.core.enable_auth').checked) {
- user = document.getElementById('cbid.mjpg-streamer.core.username').value
- pass = document.getElementById('cbid.mjpg-streamer.core.password').value
- login = user + ":" + pass + "@"
- } else {
- login = ""
- }
-
- img = document.getElementById('video_preview');
- img.src = 'http://' + login + location.hostname + ':' + port + '/?action=snapshot';
-}
-
-function start_stream() {
- console.log('start_stream');
-
- setTimeout(function() { _start_stream(); }, 500);
-}
-
-function on_error() {
- console.log('on_error');
-
- img = document.getElementById('video_preview');
- img.style.display = 'none';
-
- stream_stat = document.getElementById('stream_status');
- stream_stat.style.display = 'block';
-
- start_stream();
-}
-
-function on_load() {
- console.log('on_load');
-
- img = document.getElementById('video_preview');
- img.style.display = 'block';
-
- stream_stat = document.getElementById('stream_status');
- stream_stat.style.display = 'none';
-}
-
-init_stream()
-
-</script>
-]]
-
-preview = s:taboption(this_tab, DummyValue, "_dummy", html)
- preview:depends("output", "http")
-
---- Output file settings ---
-
-this_tab = "output_file"
-
-folder=s:taboption(this_tab, Value, "folder", translate("Folder"), translate("Set folder to save pictures"))
- folder.placeholder="/tmp/images"
- folder.datatype = "directory"
-
---mjpeg=s:taboption(this_tab, Value, "mjpeg", translate("Mjpeg output"), translate("Check to save the stream to an mjpeg file"))
-
-delay=s:taboption(this_tab, Value, "delay", translate("Interval between saving pictures"), translate("Set the interval in millisecond"))
- delay.placeholder="5000"
- delay.datatype = "uinteger"
-
-ringbuffer=s:taboption(this_tab, Value, "ringbuffer", translate("Ring buffer size"), translate("Max. number of pictures to hold"))
- ringbuffer.placeholder="10"
- ringbuffer.datatype = "uinteger"
-
-exceed=s:taboption(this_tab, Value, "exceed", translate("Exceed"), translate("Allow ringbuffer to exceed limit by this amount"))
- exceed.datatype = "uinteger"
-
-command=s:taboption(this_tab, Value, "command", translate("Command to run"), translate("Execute command after saving picture. Mjpg-streamer parses the filename as first parameter to your script."))
-
-link=s:taboption(this_tab, Value, "link", translate("Link newest picture to fixed file name"), translate("Link the last picture in ringbuffer to fixed named file provided."))
-
-return m
diff --git a/applications/luci-app-mjpg-streamer/root/usr/share/luci/menu.d/luci-app-mjpg-streamer.json b/applications/luci-app-mjpg-streamer/root/usr/share/luci/menu.d/luci-app-mjpg-streamer.json
index 6f79358e49..9a5a8bd9eb 100644
--- a/applications/luci-app-mjpg-streamer/root/usr/share/luci/menu.d/luci-app-mjpg-streamer.json
+++ b/applications/luci-app-mjpg-streamer/root/usr/share/luci/menu.d/luci-app-mjpg-streamer.json
@@ -2,13 +2,16 @@
"admin/services/mjpg-streamer": {
"title": "MJPG-streamer",
"action": {
- "type": "cbi",
- "path": "mjpg-streamer",
- "post": { "cbi.submit": true }
+ "type": "view",
+ "path": "mjpg-streamer/mjpg-streamer"
},
"depends": {
- "acl": [ "luci-app-mjpg-streamer" ],
- "uci": { "mjpg-streamer": true }
+ "acl": [
+ "luci-app-mjpg-streamer"
+ ],
+ "uci": {
+ "mjpg-streamer": true
+ }
}
}
}
diff --git a/applications/luci-app-mjpg-streamer/root/usr/share/rpcd/acl.d/luci-app-mjpg-streamer.json b/applications/luci-app-mjpg-streamer/root/usr/share/rpcd/acl.d/luci-app-mjpg-streamer.json
index ab68a6e1c2..4a2f1df55a 100644
--- a/applications/luci-app-mjpg-streamer/root/usr/share/rpcd/acl.d/luci-app-mjpg-streamer.json
+++ b/applications/luci-app-mjpg-streamer/root/usr/share/rpcd/acl.d/luci-app-mjpg-streamer.json
@@ -2,10 +2,14 @@
"luci-app-mjpg-streamer": {
"description": "Grant UCI access for luci-app-mjpg-streamer",
"read": {
- "uci": [ "mjpg-streamer" ]
+ "uci": [
+ "mjpg-streamer"
+ ]
},
"write": {
- "uci": [ "mjpg-streamer" ]
+ "uci": [
+ "mjpg-streamer"
+ ]
}
}
-}
+} \ No newline at end of file