aboutsummaryrefslogtreecommitdiffstats
path: root/gallery_dl/postprocessor
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@unit193.net>2021-06-05 20:55:36 -0400
committerLibravatarUnit 193 <unit193@unit193.net>2021-06-05 20:55:36 -0400
commit8a644b7a06c504263a478d3681eed10b4161b5be (patch)
treeb3d668588e5c0be8c75467e50499f73ff9ec7c05 /gallery_dl/postprocessor
parente7eb1f9779f2e223575ab23a6bc1abf2222e7d27 (diff)
New upstream version 1.17.5.upstream/1.17.5
Diffstat (limited to 'gallery_dl/postprocessor')
-rw-r--r--gallery_dl/postprocessor/ugoira.py87
1 files changed, 59 insertions, 28 deletions
diff --git a/gallery_dl/postprocessor/ugoira.py b/gallery_dl/postprocessor/ugoira.py
index 14eaa8d..ac094b7 100644
--- a/gallery_dl/postprocessor/ugoira.py
+++ b/gallery_dl/postprocessor/ugoira.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright 2018-2020 Mike Fährmann
+# Copyright 2018-2021 Mike Fährmann
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
@@ -26,6 +26,7 @@ class UgoiraPP(PostProcessor):
self.twopass = options.get("ffmpeg-twopass", False)
self.output = options.get("ffmpeg-output", True)
self.delete = not options.get("keep-files", False)
+ self.repeat = options.get("repeat-last-frame", True)
ffmpeg = options.get("ffmpeg-location")
self.ffmpeg = util.expand_path(ffmpeg) if ffmpeg else "ffmpeg"
@@ -34,6 +35,11 @@ class UgoiraPP(PostProcessor):
if rate != "auto":
self.calculate_framerate = lambda _: (None, rate)
+ if options.get("ffmpeg-demuxer") == "image2":
+ self._process = self._image2
+ else:
+ self._process = self._concat
+
if options.get("libx264-prevent-odd", True):
# get last video-codec argument
vcodec = None
@@ -72,34 +78,17 @@ class UgoiraPP(PostProcessor):
if not self._frames:
return
- rate_in, rate_out = self.calculate_framerate(self._frames)
-
with tempfile.TemporaryDirectory() as tempdir:
# extract frames
- with zipfile.ZipFile(pathfmt.temppath) as zfile:
- zfile.extractall(tempdir)
-
- # write ffconcat file
- ffconcat = tempdir + "/ffconcat.txt"
- with open(ffconcat, "w") as file:
- file.write("ffconcat version 1.0\n")
- for frame in self._frames:
- file.write("file '{}'\n".format(frame["file"]))
- file.write("duration {}\n".format(frame["delay"] / 1000))
- if self.extension != "gif":
- # repeat the last frame to prevent it from only being
- # displayed for a very short amount of time
- file.write("file '{}'\n".format(self._frames[-1]["file"]))
-
- # collect command-line arguments
- args = [self.ffmpeg]
- if rate_in:
- args += ("-r", str(rate_in))
- args += ("-i", ffconcat)
- if rate_out:
- args += ("-r", str(rate_out))
- if self.prevent_odd:
- args += ("-vf", "crop=iw-mod(iw\\,2):ih-mod(ih\\,2)")
+ try:
+ with zipfile.ZipFile(pathfmt.temppath) as zfile:
+ zfile.extractall(tempdir)
+ except FileNotFoundError:
+ pathfmt.realpath = pathfmt.temppath
+ return
+
+ # process frames and collect command-line arguments
+ args = self._process(tempdir)
if self.args:
args += self.args
self.log.debug("ffmpeg args: %s", args)
@@ -108,7 +97,7 @@ class UgoiraPP(PostProcessor):
pathfmt.set_extension(self.extension)
try:
if self.twopass:
- if "-f" not in args:
+ if "-f" not in self.args:
args += ("-f", self.extension)
args += ("-passlogfile", tempdir + "/ffmpeg2pass", "-pass")
self._exec(args + ["1", "-y", os.devnull])
@@ -127,6 +116,48 @@ class UgoiraPP(PostProcessor):
else:
pathfmt.set_extension("zip")
+ def _concat(self, path):
+ ffconcat = path + "/ffconcat.txt"
+
+ content = ["ffconcat version 1.0"]
+ append = content.append
+ for frame in self._frames:
+ append("file '{}'\nduration {}".format(
+ frame["file"], frame["delay"] / 1000))
+ if self.repeat:
+ append("file '{}'".format(frame["file"]))
+ append("")
+
+ with open(ffconcat, "w") as file:
+ file.write("\n".join(content))
+
+ rate_in, rate_out = self.calculate_framerate(self._frames)
+ args = [self.ffmpeg, "-f", "concat"]
+ if rate_in:
+ args += ("-r", str(rate_in))
+ args += ("-i", ffconcat)
+ if rate_out:
+ args += ("-r", str(rate_out))
+ return args
+
+ def _image2(self, path):
+ path += "/"
+
+ # adjust frame mtime values
+ ts = 0
+ for frame in self._frames:
+ os.utime(path + frame["file"], ns=(ts, ts))
+ ts += frame["delay"] * 1000000
+
+ return [
+ self.ffmpeg,
+ "-f", "image2",
+ "-ts_from_file", "2",
+ "-pattern_type", "sequence",
+ "-i", "{}%06d.{}".format(
+ path.replace("%", "%%"), frame["file"].rpartition(".")[2]),
+ ]
+
def _exec(self, args):
out = None if self.output else subprocess.DEVNULL
return subprocess.Popen(args, stdout=out, stderr=out).wait()