Added (optional!) watermark addition to generated timelapse movies.
parent
3b50fdcf3f
commit
07d4a8fd4f
|
@ -349,7 +349,8 @@ def getSettings():
|
||||||
"streamUrl": s.get(["webcam", "stream"]),
|
"streamUrl": s.get(["webcam", "stream"]),
|
||||||
"snapshotUrl": s.get(["webcam", "snapshot"]),
|
"snapshotUrl": s.get(["webcam", "snapshot"]),
|
||||||
"ffmpegPath": s.get(["webcam", "ffmpeg"]),
|
"ffmpegPath": s.get(["webcam", "ffmpeg"]),
|
||||||
"bitrate": s.get(["webcam", "bitrate"])
|
"bitrate": s.get(["webcam", "bitrate"]),
|
||||||
|
"watermark": s.getBoolean(["webcam", "watermark"])
|
||||||
},
|
},
|
||||||
"feature": {
|
"feature": {
|
||||||
"gcodeViewer": s.getBoolean(["feature", "gCodeVisualizer"]),
|
"gcodeViewer": s.getBoolean(["feature", "gCodeVisualizer"]),
|
||||||
|
@ -387,6 +388,7 @@ def setSettings():
|
||||||
if "snapshotUrl" in data["webcam"].keys(): s.set(["webcam", "snapshot"], data["webcam"]["snapshotUrl"])
|
if "snapshotUrl" in data["webcam"].keys(): s.set(["webcam", "snapshot"], data["webcam"]["snapshotUrl"])
|
||||||
if "ffmpeg" in data["webcam"].keys(): s.set(["webcam", "ffmpeg"], data["webcam"]["ffmpeg"])
|
if "ffmpeg" in data["webcam"].keys(): s.set(["webcam", "ffmpeg"], data["webcam"]["ffmpeg"])
|
||||||
if "bitrate" in data["webcam"].keys(): s.set(["webcam", "bitrate"], data["webcam"]["bitrate"])
|
if "bitrate" in data["webcam"].keys(): s.set(["webcam", "bitrate"], data["webcam"]["bitrate"])
|
||||||
|
if "watermark" in data["webcam"].keys(): s.setBoolean(["webcam", "watermark"], data["webcam"]["watermark"])
|
||||||
|
|
||||||
if "feature" in data.keys():
|
if "feature" in data.keys():
|
||||||
if "gcodeViewer" in data["feature"].keys(): s.setBoolean(["feature", "gCodeVisualizer"], data["feature"]["gcodeViewer"])
|
if "gcodeViewer" in data["feature"].keys(): s.setBoolean(["feature", "gCodeVisualizer"], data["feature"]["gcodeViewer"])
|
||||||
|
|
|
@ -32,7 +32,8 @@ old_default_settings = {
|
||||||
"stream": None,
|
"stream": None,
|
||||||
"snapshot": None,
|
"snapshot": None,
|
||||||
"ffmpeg": None,
|
"ffmpeg": None,
|
||||||
"bitrate": "5000k"
|
"bitrate": "5000k",
|
||||||
|
"watermark": True
|
||||||
},
|
},
|
||||||
"folder": {
|
"folder": {
|
||||||
"uploads": None,
|
"uploads": None,
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 6.7 KiB |
|
@ -977,6 +977,7 @@ function SettingsViewModel() {
|
||||||
self.webcam_snapshotUrl = ko.observable(undefined);
|
self.webcam_snapshotUrl = ko.observable(undefined);
|
||||||
self.webcam_ffmpegPath = ko.observable(undefined);
|
self.webcam_ffmpegPath = ko.observable(undefined);
|
||||||
self.webcam_bitrate = ko.observable(undefined);
|
self.webcam_bitrate = ko.observable(undefined);
|
||||||
|
self.webcam_watermark = ko.observable(undefined);
|
||||||
|
|
||||||
self.feature_gcodeViewer = ko.observable(undefined);
|
self.feature_gcodeViewer = ko.observable(undefined);
|
||||||
self.feature_waitForStart = ko.observable(undefined);
|
self.feature_waitForStart = ko.observable(undefined);
|
||||||
|
@ -1018,6 +1019,7 @@ function SettingsViewModel() {
|
||||||
self.webcam_snapshotUrl(response.webcam.snapshotUrl);
|
self.webcam_snapshotUrl(response.webcam.snapshotUrl);
|
||||||
self.webcam_ffmpegPath(response.webcam.ffmpegPath);
|
self.webcam_ffmpegPath(response.webcam.ffmpegPath);
|
||||||
self.webcam_bitrate(response.webcam.bitrate);
|
self.webcam_bitrate(response.webcam.bitrate);
|
||||||
|
self.webcam_watermark(response.webcam.watermark);
|
||||||
|
|
||||||
self.feature_gcodeViewer(response.feature.gcodeViewer);
|
self.feature_gcodeViewer(response.feature.gcodeViewer);
|
||||||
self.feature_waitForStart(response.feature.waitForStart);
|
self.feature_waitForStart(response.feature.waitForStart);
|
||||||
|
@ -1046,7 +1048,8 @@ function SettingsViewModel() {
|
||||||
"streamUrl": self.webcam_streamUrl(),
|
"streamUrl": self.webcam_streamUrl(),
|
||||||
"snapshotUrl": self.webcam_snapshotUrl(),
|
"snapshotUrl": self.webcam_snapshotUrl(),
|
||||||
"ffmpegPath": self.webcam_ffmpegPath(),
|
"ffmpegPath": self.webcam_ffmpegPath(),
|
||||||
"bitrate": self.webcam_bitrate()
|
"bitrate": self.webcam_bitrate(),
|
||||||
|
"watermark": self.webcam_watermark()
|
||||||
},
|
},
|
||||||
"feature": {
|
"feature": {
|
||||||
"gcodeViewer": self.feature_gcodeViewer(),
|
"gcodeViewer": self.feature_gcodeViewer(),
|
||||||
|
|
|
@ -81,6 +81,13 @@
|
||||||
<input type="text" class="input-block-level" data-bind="value: webcam_bitrate" id="settings-webcamBitrate">
|
<input type="text" class="input-block-level" data-bind="value: webcam_bitrate" id="settings-webcamBitrate">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<div class="controls">
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" data-bind="checked: webcam_watermark" id="settings-webcamWatermark"> Enable OctoPrint watermark in timelapse movies
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="tab-pane" id="settings_features">
|
<div class="tab-pane" id="settings_features">
|
||||||
|
|
|
@ -13,6 +13,8 @@ import subprocess
|
||||||
import fnmatch
|
import fnmatch
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
def getFinishedTimelapses():
|
def getFinishedTimelapses():
|
||||||
files = []
|
files = []
|
||||||
basedir = settings().getBaseFolder("timelapse")
|
basedir = settings().getBaseFolder("timelapse")
|
||||||
|
@ -91,10 +93,24 @@ class Timelapse(object):
|
||||||
|
|
||||||
input = os.path.join(self._captureDir, "tmp_%05d.jpg")
|
input = os.path.join(self._captureDir, "tmp_%05d.jpg")
|
||||||
output = os.path.join(self._movieDir, "%s_%s.mpg" % (os.path.splitext(self._gcodeFile)[0], time.strftime("%Y%m%d%H%M%S")))
|
output = os.path.join(self._movieDir, "%s_%s.mpg" % (os.path.splitext(self._gcodeFile)[0], time.strftime("%Y%m%d%H%M%S")))
|
||||||
subprocess.call([
|
|
||||||
ffmpeg, '-i', input, '-vcodec', 'mpeg2video', '-pix_fmt', 'yuv420p', '-r', '25', '-y',
|
# prepare ffmpeg command
|
||||||
'-b:v', bitrate, '-f', 'vob', output
|
command = [
|
||||||
])
|
ffmpeg, '-i', input, '-vcodec', 'mpeg2video', '-pix_fmt', 'yuv420p', '-r', '25', '-y', '-b:v', bitrate,
|
||||||
|
'-f', 'vob']
|
||||||
|
|
||||||
|
# add watermark if configured
|
||||||
|
if settings().getBoolean(["webcam", "watermark"]):
|
||||||
|
watermark = os.path.join(os.path.dirname(__file__), "static", "img", "watermark.png")
|
||||||
|
if sys.platform == "win32":
|
||||||
|
# Because ffmpeg hiccups on windows' drive letters and backslashes we have to give the watermark
|
||||||
|
# path a special treatment. Yeah, I couldn't believe it either...
|
||||||
|
watermark = watermark.replace("\\", "/").replace(":", "\\\\:")
|
||||||
|
command.extend(['-vf', 'movie=%s [wm]; [in][wm] overlay=10:main_h-overlay_h-10 [out]' % (watermark)])
|
||||||
|
|
||||||
|
# finalize command with output file
|
||||||
|
command.append(output)
|
||||||
|
subprocess.call(command)
|
||||||
|
|
||||||
def cleanCaptureDir(self):
|
def cleanCaptureDir(self):
|
||||||
if not os.path.isdir(self._captureDir):
|
if not os.path.isdir(self._captureDir):
|
||||||
|
|
Loading…
Reference in New Issue