luci-app-mjpg-streamer: migrate to js
authorAyushman Tripathi <ayushmantripathi7724@gmail.com>
Fri, 11 Aug 2023 18:28:47 +0000 (23:58 +0530)
committerJo-Philipp Wich <jo@mein.io>
Thu, 31 Aug 2023 13:45:49 +0000 (15:45 +0200)
Signed-off-by: Ayushman Tripathi <ayushmantripathi7724@gmail.com>
[fix commit message]
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
applications/luci-app-mjpg-streamer/Makefile
applications/luci-app-mjpg-streamer/htdocs/luci-static/resources/view/mjpg-streamer/mjpg-streamer.js [new file with mode: 0644]
applications/luci-app-mjpg-streamer/luasrc/model/cbi/mjpg-streamer.lua [deleted file]
applications/luci-app-mjpg-streamer/root/usr/share/luci/menu.d/luci-app-mjpg-streamer.json
applications/luci-app-mjpg-streamer/root/usr/share/rpcd/acl.d/luci-app-mjpg-streamer.json

index 876e99dd41cc72f9201692e48ef10b30881ff71e..b4f1f1412741f462eec9beb39669f1015d8e93c5 100644 (file)
@@ -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 (file)
index 0000000..6fb6f3c
--- /dev/null
@@ -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 (file)
index 86ea302..0000000
+++ /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
index 6f79358e498d0d6bb37867c9b2b56f02ab18a0a5..9a5a8bd9ebb9267ab2151a39acd1d40948c29c84 100644 (file)
@@ -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
+                       }
                }
        }
 }
index ab68a6e1c2c84d4c508e5881b5c8a9f13c3f7c1a..4a2f1df55a9447332cdcac87d6531dc5b2106be9 100644 (file)
@@ -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