Merge pull request #278 from nmav/ocserv
[project/luci.git] / applications / luci-mjpg-streamer / luasrc / model / cbi / mjpg-streamer.lua
1 --[[
2
3 LuCI MJPEG Streamer
4
5 (c) 2014 Roger D <rogerdammit@gmail.com>
6 Based on work by: vargabab and OpenWrt Dreambox
7
8 Licensed under the Apache License, Version 2.0 (the "License");
9 you may not use this file except in compliance with the License.
10 You may obtain a copy of the License at
11
12         http://www.apache.org/licenses/LICENSE-2.0
13
14 ]]--
15
16 m = Map("mjpg-streamer", "MJPG-streamer", translate("mjpg streamer is a streaming application for Linux-UVC compatible webcams"))
17
18 --- General settings ---
19
20 section_gen = m:section(TypedSection, "mjpg-streamer", "General")
21     section_gen.addremove=false
22     section_gen.anonymous=true
23
24 enabled = section_gen:option(Flag, "enabled", "Enabled", "Enable MJPG-streamer")
25
26 input = section_gen:option(ListValue, "input",  "Input plugin")
27    input:depends("enabled", "1")
28    input:value("uvc", "UVC")
29    ---input:value("file", "File")
30    input.optional = false
31
32 output = section_gen:option(ListValue, "output",  "Output plugin")
33    output:depends("enabled", "1")
34    output:value("http", "HTTP")
35    output:value("file", "File")
36    output.optional = false
37
38
39 --- Plugin settings ---
40
41 s = m:section(TypedSection, "mjpg-streamer", "Plugin settings")
42     s.addremove=false
43     s.anonymous=true
44
45     s:tab("output_http", translate("HTTP output"))
46     s:tab("output_file", translate("File output"))
47     s:tab("input_uvc", translate("UVC input"))
48     ---s:tab("input_file", translate("File input"))
49
50
51 --- Input UVC settings ---
52
53 this_tab = "input_uvc"
54
55 device = s:taboption(this_tab, Value, "device", translate("Device"))
56     device.default="/dev/video0"
57     --device.datatype = "device"
58     device:value("/dev/video0", "/dev/video0")
59     device:value("/dev/video1", "/dev/video1")
60     device:value("/dev/video2", "/dev/video2")
61     device.optional = false
62
63 resolution = s:taboption(this_tab, Value, "resolution", translate("Resolution"))
64     resolution.default = "640x480"
65     resolution:value("320x240", "320x240")
66     resolution:value("640x480", "640x480")
67     resolution:value("800x600", "800x600")
68     resolution:value("864x480", "864x480")
69     resolution:value("960x544", "960x544")
70     resolution:value("960x720", "960x720")
71     resolution:value("1280x720", "1280x720")
72     resolution:value("1280x960", "1280x960")
73     resolution:value("1920x1080", "1920x1080")
74     resolution.optional = true
75
76 fps = s:taboption(this_tab, Value, "fps", translate("Frames per second"))
77     fps.datatype = "and(uinteger, min(1))"
78     fps.placeholder = "5"
79     fps.optional = true
80
81 yuv = s:taboption(this_tab, Flag, "yuv", translate("Enable YUYV format"), translate("Automatic disabling of MJPEG mode"))
82
83 quality = s:taboption(this_tab, Value, "quality", translate("JPEG compression quality"), translate("Set the quality in percent. This setting activates YUYV format, disables MJPEG"))
84     quality.datatype = "range(0, 100)"
85
86 minimum_size = s:taboption(this_tab, Value, "minimum_size", translate("Drop frames smaller then this limit"),translate("Set the minimum size if the webcam produces small-sized garbage frames. May happen under low light conditions"))
87     minimum_size.datatype = "uinteger"
88
89 no_dynctrl = s:taboption(this_tab, Flag, "no_dynctrl", translate("Don't initalize dynctrls"), translate("Do not initalize dynctrls of Linux-UVC driver"))
90
91 led = s:taboption(this_tab, ListValue, "led", translate("Led control"))
92     led:value("on", translate("On"))
93     led:value("off", translate("Off"))
94     led:value("blink", translate("Blink"))
95     led:value("auto", translate("Auto"))
96     led.optional = true
97
98
99 --- Output HTTP settings ---
100
101 this_tab = "output_http"
102
103 port=s:taboption(this_tab, Value, "port", translate("Port"), translate("TCP port for this HTTP server"))
104     port.datatype = "port"
105     port.placeholder = "8080"
106
107 enable_auth = s:taboption(this_tab, Flag, "enable_auth", translate("Authentication required"), translate("Ask for username and password on connect"))
108     enable_auth.default = false
109
110 username = s:taboption(this_tab, Value, "username", translate("Username"))
111     username:depends("enable_auth", "1")
112     username.optional = false
113
114 password = s:taboption(this_tab, Value, "password", translate("Password"))
115     password:depends("enable_auth", "1")
116     password.password = true
117     password.optional = false
118     password.default = false
119
120 www = s:taboption(this_tab, Value, "www", translate("WWW folder"), translate("Folder that contains webpages"))
121     www.datatype = "directory"
122     www.default = "/www/webcam/"
123     www.optional = false
124
125
126 --- HTTP preview  ---
127
128 html = [[
129 <style media="screen" type="text/css">
130     .img-preview {
131         display: inline-block;
132         height: auto;
133         width: 640px;
134         padding: 4px;
135         line-height: 1.428571429;
136         background-color: #fff;
137         border: 1px solid #ddd;
138         border-radius: 4px;
139         -webkit-transition: all .2s ease-in-out;
140         transition: all .2s ease-in-out;
141         margin-bottom: 5px;
142         display: none;
143     }
144 </style>
145
146 <div id="videodiv">
147         <img id="video_preview" class="img-preview" onerror="on_error()" onload="on_load()"/>
148         <p id="stream_status" style="text-align: center; color: orange; font-weight:bold;">Stream unavailable</p>
149 </div>
150
151 <script type="text/javascript">
152
153 function init_stream() {
154     console.log('init_stream');
155     start_stream()
156 }
157
158 function _start_stream() {
159         console.log('_start_stream');
160
161         port = document.getElementById('cbid.mjpg-streamer.core.port').value
162
163         if (document.getElementById('cbid.mjpg-streamer.core.enable_auth').checked) {
164             user = document.getElementById('cbid.mjpg-streamer.core.username').value
165             pass = document.getElementById('cbid.mjpg-streamer.core.password').value
166             login = user + ":" + pass + "@"
167         } else {
168             login = ""
169         }
170
171         img = document.getElementById('video_preview');
172         img.src = 'http://' + login + location.hostname + ':' + port + '/?action=snapshot';
173 }
174
175 function start_stream() {
176         console.log('start_stream');
177
178         setTimeout(function() { _start_stream(); }, 500);
179 }
180
181 function on_error() {
182     console.log('on_error');
183
184     img = document.getElementById('video_preview');
185     img.style.display = 'none';
186
187     stream_stat = document.getElementById('stream_status');
188     stream_stat.style.display = 'block';
189
190     start_stream();
191 }
192
193 function on_load() {
194     console.log('on_load');
195
196     img = document.getElementById('video_preview');
197     img.style.display = 'block';
198
199     stream_stat = document.getElementById('stream_status');
200     stream_stat.style.display = 'none';
201 }
202
203 init_stream()
204
205 </script>
206 ]]
207
208 preview = s:taboption(this_tab, DummyValue, "_dummy", html)
209     preview:depends("output", "http")
210
211 --- Output file settings ---
212
213 this_tab = "output_file"
214
215 folder=s:taboption(this_tab, Value, "folder", translate("Folder"), translate("Set folder to save pictures"))
216     folder.placeholder="/tmp/images"
217     folder.datatype = "directory"
218
219 --mjpeg=s:taboption(this_tab, Value, "mjpeg", translate("Mjpeg output"), translate("Check to save the stream to an mjpeg file"))
220
221 delay=s:taboption(this_tab, Value, "delay", translate("Interval between saving pictures"), translate("Set the inteval in millisecond"))
222     delay.placeholder="5000"
223     delay.datatype = "uinteger"
224
225 ringbuffer=s:taboption(this_tab, Value, "ringbuffer", translate("Ring buffer size"), translate("Max. number of pictures to hold"))
226     ringbuffer.placeholder="10"
227     ringbuffer.datatype = "uinteger"
228
229 exceed=s:taboption(this_tab, Value, "exceed", translate("Exceed"), translate("Allow ringbuffer to exceed limit by this amount"))
230     exceed.datatype = "uinteger"
231
232 command=s:taboption(this_tab, Value, "command", translate("Command to run"), translate("Execute command after saving picture. Mjpg-streamer parse the filename as first parameter to your script."))
233
234
235 return m