aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-webui/octoprint/octoprint/0001-timelapse-add-setting-for-videocodec.patch
blob: d5102d4539a1ff170023544a9e94c116f9b35237 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
From 2fb4b4d9e4f95db8bcdad5c8a52006de8811c1e8 Mon Sep 17 00:00:00 2001
From: Koen Kooi <koen@dominion.thruhere.net>
Date: Sat, 27 Jan 2018 12:09:28 +0100
Subject: [PATCH 1/3] timelapse: add setting for videocodec

---
 docs/api/settings.rst                                     |  2 ++
 docs/configuration/config_yaml.rst                        |  3 +++
 src/octoprint/server/api/settings.py                      |  3 +++
 src/octoprint/settings.py                                 |  1 +
 src/octoprint/static/js/app/viewmodels/settings.js        |  1 +
 src/octoprint/templates/dialogs/settings/webcam.jinja2    |  1 +
 .../snippets/settings/webcam/ffmpegVideoCodec.jinja2      |  6 ++++++
 src/octoprint/timelapse.py                                | 15 ++++++++++-----
 8 files changed, 27 insertions(+), 5 deletions(-)
 create mode 100644 src/octoprint/templates/snippets/settings/webcam/ffmpegVideoCodec.jinja2

diff --git a/docs/api/settings.rst b/docs/api/settings.rst
index b26b2d2..7be1b1e 100644
--- a/docs/api/settings.rst
+++ b/docs/api/settings.rst
@@ -254,6 +254,8 @@ mapped from the same fields in ``config.yaml`` unless otherwise noted:
      -
    * - ``webcam.ffmpegThreads``
      -
+   * - ``webcam.ffmpegVideoCodec``
+     -
    * - ``webcam.watermark``
      -
    * - ``webcam.flipH``
diff --git a/docs/configuration/config_yaml.rst b/docs/configuration/config_yaml.rst
index 7205ee1..6ccf9b9 100644
--- a/docs/configuration/config_yaml.rst
+++ b/docs/configuration/config_yaml.rst
@@ -1181,6 +1181,9 @@ Use the following settings to configure webcam support:
      # Should be left at 1 for RPi1.
      ffmpegThreads: 1
 
+     # Videocodec to be used for encoding. Defaults to mpeg2video.
+     ffmpegVideoCodec: mpeg2video
+
      # The bitrate to use for rendering the timelapse video. This gets directly passed to ffmpeg.
      bitrate: 5000k
 
diff --git a/src/octoprint/server/api/settings.py b/src/octoprint/server/api/settings.py
index 9ccb461..13ab076 100644
--- a/src/octoprint/server/api/settings.py
+++ b/src/octoprint/server/api/settings.py
@@ -106,6 +106,7 @@ def getSettings():
 			"ffmpegPath": s.get(["webcam", "ffmpeg"]),
 			"bitrate": s.get(["webcam", "bitrate"]),
 			"ffmpegThreads": s.get(["webcam", "ffmpegThreads"]),
+			"ffmpegVideoCodec": s.get(["webcam", "ffmpegVideoCodec"]),
 			"watermark": s.getBoolean(["webcam", "watermark"]),
 			"flipH": s.getBoolean(["webcam", "flipH"]),
 			"flipV": s.getBoolean(["webcam", "flipV"]),
@@ -341,6 +342,8 @@ def _saveSettings(data):
 		if "ffmpegPath" in data["webcam"]: s.set(["webcam", "ffmpeg"], data["webcam"]["ffmpegPath"])
 		if "bitrate" in data["webcam"]: s.set(["webcam", "bitrate"], data["webcam"]["bitrate"])
 		if "ffmpegThreads" in data["webcam"]: s.setInt(["webcam", "ffmpegThreads"], data["webcam"]["ffmpegThreads"])
+                # Add a whitelist for vcodecs like aspect ration has?
+                if "ffmpegVideoCodec" in data["webcam"]: s.set(["webcam", "ffmpegVideoCodec"], data["webcam"]["ffmpegVideoCodec"])
 		if "watermark" in data["webcam"]: s.setBoolean(["webcam", "watermark"], data["webcam"]["watermark"])
 		if "flipH" in data["webcam"]: s.setBoolean(["webcam", "flipH"], data["webcam"]["flipH"])
 		if "flipV" in data["webcam"]: s.setBoolean(["webcam", "flipV"], data["webcam"]["flipV"])
diff --git a/src/octoprint/settings.py b/src/octoprint/settings.py
index e360077..72823ec 100644
--- a/src/octoprint/settings.py
+++ b/src/octoprint/settings.py
@@ -205,6 +205,7 @@ default_settings = {
 		"snapshotSslValidation": True,
 		"ffmpeg": None,
 		"ffmpegThreads": 1,
+		"ffmpegVideoCodec": "mpeg2video",
 		"bitrate": "5000k",
 		"watermark": True,
 		"flipH": False,
diff --git a/src/octoprint/static/js/app/viewmodels/settings.js b/src/octoprint/static/js/app/viewmodels/settings.js
index c2ee03f..bb95a88 100644
--- a/src/octoprint/static/js/app/viewmodels/settings.js
+++ b/src/octoprint/static/js/app/viewmodels/settings.js
@@ -125,6 +125,7 @@ $(function() {
         self.webcam_ffmpegPath = ko.observable(undefined);
         self.webcam_bitrate = ko.observable(undefined);
         self.webcam_ffmpegThreads = ko.observable(undefined);
+        self.webcam_ffmpegVideoCodec = ko.observable(undefined);
         self.webcam_watermark = ko.observable(undefined);
         self.webcam_flipH = ko.observable(undefined);
         self.webcam_flipV = ko.observable(undefined);
diff --git a/src/octoprint/templates/dialogs/settings/webcam.jinja2 b/src/octoprint/templates/dialogs/settings/webcam.jinja2
index 7a1330e..f9b72b0 100644
--- a/src/octoprint/templates/dialogs/settings/webcam.jinja2
+++ b/src/octoprint/templates/dialogs/settings/webcam.jinja2
@@ -26,6 +26,7 @@
             {% include "snippets/settings/webcam/ffmpegThreads.jinja2" %}
             {% include "snippets/settings/webcam/webcamSnapshotTimeout.jinja2" %}
             {% include "snippets/settings/webcam/webcamSnapshotSslValidation.jinja2" %}
+            {% include "snippets/settings/webcam/ffmpegVideoCodec.jinja2" %}
         </div>
     </div>
 </form>
diff --git a/src/octoprint/templates/snippets/settings/webcam/ffmpegVideoCodec.jinja2 b/src/octoprint/templates/snippets/settings/webcam/ffmpegVideoCodec.jinja2
new file mode 100644
index 0000000..920a534
--- /dev/null
+++ b/src/octoprint/templates/snippets/settings/webcam/ffmpegVideoCodec.jinja2
@@ -0,0 +1,6 @@
+<div class="control-group" title="{{ _('Videocodec uses for encoding') }}">
+    <label class="control-label" for="settings-webcam_ffmpegVideoCodec">{{ _('Videocodec') }}</label>
+    <div class="controls">
+        <input class="input-mini" data-bind="value: webcam_ffmpegVIdeoCodec" id="settings-webcamFfmpegVideoCodec" type="text">
+    </div>
+</div>
diff --git a/src/octoprint/timelapse.py b/src/octoprint/timelapse.py
index d18fb2d..0e01972 100644
--- a/src/octoprint/timelapse.py
+++ b/src/octoprint/timelapse.py
@@ -158,6 +158,7 @@ def render_unrendered_timelapse(name, gcode=None, postfix=None, fps=25):
 	capture_dir = settings().getBaseFolder("timelapse_tmp")
 	output_dir = settings().getBaseFolder("timelapse")
 	threads = settings().get(["webcam", "ffmpegThreads"])
+	videocodec = settings().get(["webcam", "ffmpegVideoCodec"])
 
 	job = TimelapseRenderJob(capture_dir, output_dir, name,
 	                         postfix=postfix,
@@ -165,6 +166,7 @@ def render_unrendered_timelapse(name, gcode=None, postfix=None, fps=25):
 	                         output_format=_output_format,
 	                         fps=fps,
 	                         threads=threads,
+                                 videocodec=videocodec,
 	                         on_start=_create_render_start_handler(name, gcode=gcode),
 	                         on_success=_create_render_success_handler(name, gcode=gcode),
 	                         on_fail=_create_render_fail_handler(name, gcode=gcode),
@@ -740,7 +742,7 @@ class TimelapseRenderJob(object):
 
 	def __init__(self, capture_dir, output_dir, prefix, postfix=None, capture_glob="{prefix}-*.jpg",
 	             capture_format="{prefix}-%d.jpg", output_format="{prefix}{postfix}.mpg", fps=25, threads=1,
-	             on_start=None, on_success=None, on_fail=None, on_always=None):
+	             videocodec="mpeg2video", on_start=None, on_success=None, on_fail=None, on_always=None):
 		self._capture_dir = capture_dir
 		self._output_dir = output_dir
 		self._prefix = prefix
@@ -750,6 +752,7 @@ class TimelapseRenderJob(object):
 		self._output_format = output_format
 		self._fps = fps
 		self._threads = threads
+		self._videocodec = videocodec
 		self._on_start = on_start
 		self._on_success = on_success
 		self._on_fail = on_fail
@@ -805,7 +808,8 @@ class TimelapseRenderJob(object):
 
 		# prepare ffmpeg command
 		command_str = self._create_ffmpeg_command_string(ffmpeg, self._fps, bitrate, self._threads, input, output,
-		                                                 hflip=hflip, vflip=vflip, rotate=rotate, watermark=watermark)
+		                                                 self._videocodec, hflip=hflip, vflip=vflip, rotate=rotate,
+                                                                 watermark=watermark)
 		self._logger.debug("Executing command: {}".format(command_str))
 
 		with self.render_job_lock:
@@ -827,7 +831,7 @@ class TimelapseRenderJob(object):
 				self._notify_callback("always", output)
 
 	@classmethod
-	def _create_ffmpeg_command_string(cls, ffmpeg, fps, bitrate, threads, input, output, hflip=False, vflip=False,
+	def _create_ffmpeg_command_string(cls, ffmpeg, fps, bitrate, threads, input, output, videocodec, hflip=False, vflip=False,
 	                                  rotate=False, watermark=None, pixfmt="yuv420p"):
 		"""
 		Create ffmpeg command string based on input parameters.
@@ -837,7 +841,8 @@ class TimelapseRenderJob(object):
 		    fps (int): Frames per second for output
 		    bitrate (str): Bitrate of output
 		    threads (int): Number of threads to use for rendering
-		    input (str): Absolute path to input files including file mask
+		    videocodec (str): Videocodec to be used for encoding
+                    input (str): Absolute path to input files including file mask
 		    output (str): Absolute path to output file
 		    hflip (bool): Perform horizontal flip on input material.
 		    vflip (bool): Perform vertical flip on input material.
@@ -854,7 +859,7 @@ class TimelapseRenderJob(object):
 		logger = logging.getLogger(__name__)
 
 		command = [
-			ffmpeg, '-framerate', str(fps), '-loglevel', 'error', '-i', '"{}"'.format(input), '-vcodec', 'mpeg2video',
+			ffmpeg, '-framerate', str(fps), '-loglevel', 'error', '-i', '"{}"'.format(input), '-vcodec', videocodec,
 			'-threads', str(threads), '-r', "25", '-y', '-b', str(bitrate),
 			'-f', 'vob']
 
-- 
2.0.1