diff --git a/copyparty/__main__.py b/copyparty/__main__.py index 6ff0439a..cec09537 100644 --- a/copyparty/__main__.py +++ b/copyparty/__main__.py @@ -437,6 +437,7 @@ def run_argparse(argv, formatter): ap2.add_argument("--no-vthumb", action="store_true", help="disable video thumbnails") ap2.add_argument("--th-size", metavar="WxH", default="320x256", help="thumbnail res") ap2.add_argument("--th-mt", metavar="CORES", type=int, default=cores, help="num cpu cores to use for generating thumbnails") + ap2.add_argument("--th-convt", metavar="SEC", type=int, default=60, help="conversion timeout in seconds") ap2.add_argument("--th-no-crop", action="store_true", help="dynamic height; show full image") ap2.add_argument("--th-no-jpg", action="store_true", help="disable jpg output") ap2.add_argument("--th-no-webp", action="store_true", help="disable webp output") diff --git a/copyparty/mtag.py b/copyparty/mtag.py index 9d86b14f..a4099197 100644 --- a/copyparty/mtag.py +++ b/copyparty/mtag.py @@ -8,7 +8,7 @@ import shutil import subprocess as sp from .__init__ import PY2, WINDOWS, unicode -from .util import fsenc, fsdec, uncyg, REKOBO_LKEY +from .util import fsenc, fsdec, uncyg, runcmd, REKOBO_LKEY from .bos import bos @@ -73,7 +73,7 @@ class MParser(object): raise Exception() -def ffprobe(abspath): +def ffprobe(abspath, timeout=10): cmd = [ b"ffprobe", b"-hide_banner", @@ -82,10 +82,8 @@ def ffprobe(abspath): b"--", fsenc(abspath), ] - p = sp.Popen(cmd, stdout=sp.PIPE, stderr=sp.PIPE) - r = p.communicate() - txt = r[0].decode("utf-8", "replace") - return parse_ffprobe(txt) + rc = runcmd(cmd, timeout=timeout) + return parse_ffprobe(rc[1]) def parse_ffprobe(txt): diff --git a/copyparty/th_srv.py b/copyparty/th_srv.py index af926ef2..4b5a34f2 100644 --- a/copyparty/th_srv.py +++ b/copyparty/th_srv.py @@ -349,7 +349,7 @@ class ThumbSrv(object): def _run_ff(self, cmd): # self.log((b" ".join(cmd)).decode("utf-8")) - ret, sout, serr = runcmd(cmd) + ret, sout, serr = runcmd(cmd, timeout=self.args.th_convt) if ret != 0: m = "FFmpeg failed (probably a corrupt video file):\n" m += "\n".join(["ff: {}".format(x) for x in serr.split("\n")]) diff --git a/copyparty/util.py b/copyparty/util.py index ceec44cb..8d9a2951 100644 --- a/copyparty/util.py +++ b/copyparty/util.py @@ -1324,9 +1324,17 @@ def guess_mime(url, fallback="application/octet-stream"): return ret -def runcmd(argv): +def runcmd(argv, timeout=None): p = sp.Popen(argv, stdout=sp.PIPE, stderr=sp.PIPE) - stdout, stderr = p.communicate() + if not timeout or PY2: + stdout, stderr = p.communicate() + else: + try: + stdout, stderr = p.communicate(timeout=timeout) + except sp.TimeoutExpired: + p.kill() + stdout, stderr = p.communicate() + stdout = stdout.decode("utf-8", "replace") stderr = stderr.decode("utf-8", "replace") return [p.returncode, stdout, stderr]