luci-app-mjpg-streamer: migrate to js
[project/luci.git] / applications / luci-app-mjpg-streamer / htdocs / luci-static / resources / view / mjpg-streamer / mjpg-streamer.js
1 'use strict';
2 'require view';
3 'require form';
4 'require uci';
5 'require ui';
6 'require poll';
7
8 /* Copyright 2014 Roger D < rogerdammit@gmail.com>
9 Licensed to the public under the Apache License 2.0. */
10
11 return view.extend({
12 load: function () {
13 var self = this;
14 poll.add(function () {
15 self.render();
16 }, 5);
17
18 document
19 .querySelector('head')
20 .appendChild(
21 E('style', { type: 'text/css' }, [
22 '.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;}',
23 ]),
24 );
25
26 return Promise.all([uci.load('mjpg-streamer')]);
27 },
28 render: function () {
29 var m, s, o;
30
31 m = new form.Map('mjpg-streamer', 'MJPG-streamer', _('mjpg streamer is a streaming application for Linux-UVC compatible webcams'));
32
33 //General settings
34
35 var section_gen = m.section(form.TypedSection, 'mjpg-streamer', _('General'));
36 section_gen.addremove = false;
37 section_gen.anonymous = true;
38
39 var enabled = section_gen.option(form.Flag, 'enabled', _('Enabled'), _('Enable MJPG-streamer'));
40
41 var input = section_gen.option(form.ListValue, 'input', _('Input plugin'));
42 input.depends('enabled', '1');
43 input.value('uvc', 'UVC');
44 // input: value("file", "File")
45 input.optional = false;
46
47 var output = section_gen.option(form.ListValue, 'output', _('Output plugin'));
48 output.depends('enabled', '1');
49 output.value('http', 'HTTP');
50 output.value('file', 'File');
51 output.optional = false;
52
53 //Plugin settings
54
55 s = m.section(form.TypedSection, 'mjpg-streamer', _('Plugin settings'));
56 s.addremove = false;
57 s.anonymous = true;
58
59 s.tab('output_http', _('HTTP output'));
60 s.tab('output_file', _('File output'));
61 s.tab('input_uvc', _('UVC input'));
62 // s: tab("input_file", _("File input"))
63
64 // Input UVC settings
65
66 var this_tab = 'input_uvc';
67
68 var device = s.taboption(this_tab, form.Value, 'device', _('Device'));
69 device.default = '/dev/video0';
70 //device.datatype = "device"
71 device.value('/dev/video0', '/dev/video0');
72 device.value('/dev/video1', '/dev/video1');
73 device.value('/dev/video2', '/dev/video2');
74 device.optional = false;
75
76 var resolution = s.taboption(this_tab, form.Value, 'resolution', _('Resolution'));
77 resolution.default = '640x480';
78 resolution.value('320x240', '320x240');
79 resolution.value('640x480', '640x480');
80 resolution.value('800x600', '800x600');
81 resolution.value('864x480', '864x480');
82 resolution.value('960x544', '960x544');
83 resolution.value('960x720', '960x720');
84 resolution.value('1280x720', '1280x720');
85 resolution.value('1280x960', '1280x960');
86 resolution.value('1920x1080', '1920x1080');
87 resolution.optional = true;
88
89 var fps = s.taboption(this_tab, form.Value, 'fps', _('Frames per second'));
90 fps.datatype = 'and(uinteger, min(1))';
91 fps.placeholder = '5';
92 fps.optional = true;
93
94 var yuv = s.taboption(this_tab, form.Flag, 'yuv', _('Enable YUYV format'), _('Automatic disabling of MJPEG mode'));
95
96 var quality = s.taboption(
97 this_tab,
98 form.Value,
99 'quality',
100 _('JPEG compression quality'),
101 _('Set the quality in percent. This setting activates YUYV format, disables MJPEG'),
102 );
103 quality.datatype = 'range(0, 100)';
104
105 var minimum_size = s.taboption(
106 this_tab,
107 form.Value,
108 'minimum_size',
109 _('Drop frames smaller than this limit'),
110 _('Set the minimum size if the webcam produces small-sized garbage frames. May happen under low light conditions'),
111 );
112 minimum_size.datatype = 'uinteger';
113
114 var no_dynctrl = s.taboption(this_tab, form.Flag, 'no_dynctrl', _("Don't initialize dynctrls"), _('Do not initialize dynctrls of Linux-UVC driver'));
115
116 var led = s.taboption(this_tab, form.ListValue, 'led', _('Led control'));
117 led.value('on', _('On'));
118 led.value('off', _('Off'));
119 led.value('blink', _('Blink'));
120 led.value('auto', _('Auto'));
121 led.optional = true;
122
123 // Output HTTP settings
124
125 this_tab = 'output_http';
126
127 var port = s.taboption(this_tab, form.Value, 'port', _('Port'), _('TCP port for this HTTP server'));
128 port.datatype = 'port';
129 port.placeholder = '8080';
130
131 var enable_auth = s.taboption(this_tab, form.Flag, 'enable_auth', _('Authentication required'), _('Ask for username and password on connect'));
132 enable_auth.default = false;
133
134 var username = s.taboption(this_tab, form.Value, 'username', _('Username'));
135 username.depends('enable_auth', '1');
136 username.optional = false;
137
138 var password = s.taboption(this_tab, form.Value, 'password', _('Password'));
139 password.depends('enable_auth', '1');
140 password.password = true;
141 password.optional = false;
142 password.default = false;
143
144 var www = s.taboption(this_tab, form.Value, 'www', _('WWW folder'), _('Folder that contains webpages'));
145 www.datatype = 'directory';
146 www.default = '/www/webcam/';
147 www.optional = false;
148
149
150 function init_stream() {
151 console.log('init_stream');
152 start_stream();
153 }
154
155 function _start_stream() {
156 console.log('_start_stream');
157
158 var port = uci.get('mjpg-streamer', 'core', 'port');
159
160 if (uci.get('mjpg-streamer', 'core', 'enable_auth') == '1') {
161 var user = uci.get('mjpg-streamer', 'core', 'username');
162 var pass = uci.get('mjpg-streamer', 'core', 'password');
163 var login = user + ':' + pass + '@';
164 } else {
165 var login = '';
166 }
167
168 var img = document.getElementById('video_preview') || video_preview;
169 img.src = 'http://' + login + location.hostname + ':' + port + '/?action=snapshot' + '&t=' + new Date().getTime();
170 }
171
172 function start_stream() {
173 console.log('start_stream');
174
175 setTimeout(function () {
176 _start_stream();
177 }, 500);
178 }
179
180 function on_error() {
181 console.log('on_error');
182
183 var img = video_preview;
184 img.style.display = 'none';
185
186 var stream_stat = document.getElementById('stream_status') || stream_status;
187 stream_stat.style.display = 'block';
188
189 start_stream();
190 }
191
192 function on_load() {
193 console.log('on_load');
194
195 var img = video_preview;
196 img.style.display = 'block';
197
198 var stream_stat = stream_status;
199 stream_stat.style.display = 'none';
200 }
201
202 //HTTP preview
203 var video_preview = E('img', {
204 'id': 'video_preview',
205 'class': 'img-preview',
206 'error': on_error,
207 'load': on_load,
208 });
209
210 var stream_status = E(
211 'p',
212 {
213 'id': 'stream_status',
214 'style': 'text-align: center; color: orange; font-weight: bold;',
215 },
216 _('Stream unavailable'),
217 );
218
219
220 init_stream();
221
222 var preview = s.taboption(this_tab, form.DummyValue, '_dummy');
223 preview.render = L.bind(function (view, section_id) {
224 return E([], [
225 video_preview,
226 stream_status
227 ]);
228 }, preview, this);
229 preview.depends('output', 'http');
230
231 //Output file settings
232
233 this_tab = 'output_file';
234
235 var folder = s.taboption(this_tab, form.Value, 'folder', _('Folder'), _('Set folder to save pictures'));
236 folder.placeholder = '/tmp/images';
237 folder.datatype = 'directory';
238
239 //mjpeg=s.taboption(this_tab, Value, "mjpeg", _("Mjpeg output"), _("Check to save the stream to an mjpeg file"))
240
241 var delay = s.taboption(this_tab, form.Value, 'delay', _('Interval between saving pictures'), _('Set the interval in millisecond'));
242 delay.placeholder = '5000';
243 delay.datatype = 'uinteger';
244
245 var ringbuffer = s.taboption(this_tab, form.Value, 'ringbuffer', _('Ring buffer size'), _('Max. number of pictures to hold'));
246 ringbuffer.placeholder = '10';
247 ringbuffer.datatype = 'uinteger';
248
249 var exceed = s.taboption(this_tab, form.Value, 'exceed', _('Exceed'), _('Allow ringbuffer to exceed limit by this amount'));
250 exceed.datatype = 'uinteger';
251
252 var command = s.taboption(
253 this_tab,
254 form.Value,
255 'command',
256 _('Command to run'),
257 _('Execute command after saving picture. Mjpg-streamer parses the filename as first parameter to your script.'),
258 );
259
260 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.'));
261
262 return m.render();
263 },
264 });