aboutsummaryrefslogtreecommitdiffstats
path: root/gallery_dl/postprocessor/ugoira.py
diff options
context:
space:
mode:
Diffstat (limited to 'gallery_dl/postprocessor/ugoira.py')
-rw-r--r--gallery_dl/postprocessor/ugoira.py169
1 files changed, 110 insertions, 59 deletions
diff --git a/gallery_dl/postprocessor/ugoira.py b/gallery_dl/postprocessor/ugoira.py
index 9e60ce2..f053afa 100644
--- a/gallery_dl/postprocessor/ugoira.py
+++ b/gallery_dl/postprocessor/ugoira.py
@@ -36,7 +36,8 @@ class UgoiraPP(PostProcessor):
self.delete = not options.get("keep-files", False)
self.repeat = options.get("repeat-last-frame", True)
self.mtime = options.get("mtime", True)
- self.uniform = False
+ self.skip = options.get("skip", True)
+ self.uniform = self._convert_zip = self._convert_files = False
ffmpeg = options.get("ffmpeg-location")
self.ffmpeg = util.expand_path(ffmpeg) if ffmpeg else "ffmpeg"
@@ -90,33 +91,44 @@ class UgoiraPP(PostProcessor):
if self.prevent_odd:
args += ("-vf", "crop=iw-mod(iw\\,2):ih-mod(ih\\,2)")
- job.register_hooks(
- {"prepare": self.prepare, "file": self.convert}, options)
+ job.register_hooks({
+ "prepare": self.prepare,
+ "file" : self.convert_zip,
+ "after" : self.convert_files,
+ }, options)
def prepare(self, pathfmt):
- self._frames = None
-
- if pathfmt.extension != "zip":
+ if "frames" not in pathfmt.kwdict:
+ self._frames = None
return
- kwdict = pathfmt.kwdict
- if "frames" in kwdict:
- self._frames = kwdict["frames"]
- elif "pixiv_ugoira_frame_data" in kwdict:
- self._frames = kwdict["pixiv_ugoira_frame_data"]["data"]
+ self._frames = pathfmt.kwdict["frames"]
+ if pathfmt.extension == "zip":
+ self._convert_zip = True
+ if self.delete:
+ pathfmt.set_extension(self.extension)
+ pathfmt.build_path()
else:
- return
-
- if self.delete:
- pathfmt.set_extension(self.extension)
pathfmt.build_path()
+ index = pathfmt.kwdict["_ugoira_frame_index"]
+ frame = self._frames[index].copy()
+ frame["index"] = index
+ frame["path"] = pathfmt.realpath
+ frame["ext"] = pathfmt.kwdict["extension"]
+
+ if not index:
+ self._files = [frame]
+ else:
+ self._files.append(frame)
+ if len(self._files) >= len(self._frames):
+ self._convert_files = True
- def convert(self, pathfmt):
- if not self._frames:
+ def convert_zip(self, pathfmt):
+ if not self._convert_zip:
return
+ self._convert_zip = False
with tempfile.TemporaryDirectory() as tempdir:
- # extract frames
try:
with zipfile.ZipFile(pathfmt.temppath) as zfile:
zfile.extractall(tempdir)
@@ -124,53 +136,89 @@ class UgoiraPP(PostProcessor):
pathfmt.realpath = pathfmt.temppath
return
- # process frames and collect command-line arguments
- pathfmt.set_extension(self.extension)
- pathfmt.build_path()
-
- args = self._process(pathfmt, tempdir)
- if self.args_pp:
- args += self.args_pp
- if self.args:
- args += self.args
-
- # ensure target directory exists
- os.makedirs(pathfmt.realdirectory, exist_ok=True)
-
- # invoke ffmpeg
- try:
- if self.twopass:
- if "-f" not in self.args:
- args += ("-f", self.extension)
- args += ("-passlogfile", tempdir + "/ffmpeg2pass", "-pass")
- self._exec(args + ["1", "-y", os.devnull])
- self._exec(args + ["2", pathfmt.realpath])
- else:
- args.append(pathfmt.realpath)
- self._exec(args)
- if self._finalize:
- self._finalize(pathfmt, tempdir)
- except OSError as exc:
- print()
- self.log.error("Unable to invoke FFmpeg (%s: %s)",
- exc.__class__.__name__, exc)
- pathfmt.realpath = pathfmt.temppath
- except Exception as exc:
- print()
- self.log.error("%s: %s", exc.__class__.__name__, exc)
- self.log.debug("", exc_info=True)
- pathfmt.realpath = pathfmt.temppath
- else:
- if self.mtime:
- mtime = pathfmt.kwdict.get("_mtime")
- if mtime:
- util.set_mtime(pathfmt.realpath, mtime)
+ if self.convert(pathfmt, tempdir):
if self.delete:
pathfmt.delete = True
else:
+ self.log.info(pathfmt.filename)
pathfmt.set_extension("zip")
pathfmt.build_path()
+ def convert_files(self, pathfmt):
+ if not self._convert_files:
+ return
+ self._convert_files = False
+
+ with tempfile.TemporaryDirectory() as tempdir:
+ for frame in self._files:
+
+ # update frame filename extension
+ frame["file"] = name = "{}.{}".format(
+ frame["file"].partition(".")[0], frame["ext"])
+
+ # move frame into tempdir
+ try:
+ self._copy_file(frame["path"], tempdir + "/" + name)
+ except OSError as exc:
+ self.log.debug("Unable to copy frame %s (%s: %s)",
+ name, exc.__class__.__name__, exc)
+ return
+
+ pathfmt.kwdict["num"] = 0
+ self._frames = self._files
+ if self.convert(pathfmt, tempdir):
+ self.log.info(pathfmt.filename)
+ if self.delete:
+ self.log.debug("Deleting frames")
+ for frame in self._files:
+ util.remove_file(frame["path"])
+
+ def convert(self, pathfmt, tempdir):
+ pathfmt.set_extension(self.extension)
+ pathfmt.build_path()
+ if self.skip and pathfmt.exists():
+ return True
+
+ # process frames and collect command-line arguments
+ args = self._process(pathfmt, tempdir)
+ if self.args_pp:
+ args += self.args_pp
+ if self.args:
+ args += self.args
+
+ # ensure target directory exists
+ os.makedirs(pathfmt.realdirectory, exist_ok=True)
+
+ # invoke ffmpeg
+ try:
+ if self.twopass:
+ if "-f" not in self.args:
+ args += ("-f", self.extension)
+ args += ("-passlogfile", tempdir + "/ffmpeg2pass", "-pass")
+ self._exec(args + ["1", "-y", os.devnull])
+ self._exec(args + ["2", pathfmt.realpath])
+ else:
+ args.append(pathfmt.realpath)
+ self._exec(args)
+ if self._finalize:
+ self._finalize(pathfmt, tempdir)
+ except OSError as exc:
+ print()
+ self.log.error("Unable to invoke FFmpeg (%s: %s)",
+ exc.__class__.__name__, exc)
+ pathfmt.realpath = pathfmt.temppath
+ except Exception as exc:
+ print()
+ self.log.error("%s: %s", exc.__class__.__name__, exc)
+ self.log.debug("", exc_info=True)
+ pathfmt.realpath = pathfmt.temppath
+ else:
+ if self.mtime:
+ mtime = pathfmt.kwdict.get("_mtime")
+ if mtime:
+ util.set_mtime(pathfmt.realpath, mtime)
+ return True
+
def _exec(self, args):
self.log.debug(args)
out = None if self.output else subprocess.DEVNULL
@@ -182,6 +230,9 @@ class UgoiraPP(PostProcessor):
raise ValueError()
return retcode
+ def _copy_file(self, src, dst):
+ shutil.copyfile(src, dst)
+
def _process_concat(self, pathfmt, tempdir):
rate_in, rate_out = self.calculate_framerate(self._frames)
args = [self.ffmpeg, "-f", "concat"]