support macos ffmpeg

This commit is contained in:
ed 2021-06-11 03:05:42 +02:00
parent 972a56e738
commit a45a53fdce
7 changed files with 74 additions and 28 deletions

8
.vscode/launch.json vendored
View file

@ -43,5 +43,13 @@
"${file}"
]
},
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"justMyCode": false
},
]
}

View file

@ -122,6 +122,7 @@ summary: all planned features work! now please enjoy the bloatening
* Windows: python 3.7 and older cannot read tags with ffprobe, so use mutagen or upgrade
* Windows: python 2.7 cannot index non-ascii filenames with `-e2d`
* Windows: python 2.7 cannot handle filenames with mojibake
* MacOS: `--th-ff-jpg` may fix thumbnails using macports-FFmpeg
## general bugs

View file

@ -277,6 +277,7 @@ def run_argparse(argv, formatter):
ap2.add_argument("--th-poke", metavar="SEC", type=int, default=300, help="activity labeling cooldown")
ap2.add_argument("--th-clean", metavar="SEC", type=int, default=43200, help="cleanup interval")
ap2.add_argument("--th-maxage", metavar="SEC", type=int, default=604800, help="max folder age")
ap2.add_argument("--th-ff-jpg", action="store_true", help="force jpg for video thumbs")
ap2 = ap.add_argument_group('database options')
ap2.add_argument("-e2d", action="store_true", help="enable up2k database")

View file

@ -21,13 +21,15 @@ class ThumbCli(object):
if ext not in THUMBABLE:
return None
if self.args.no_vthumb and ext in FMT_FF:
is_vid = ext in FMT_FF
if is_vid and self.args.no_vthumb:
return None
if fmt == "j" and self.args.th_no_jpg:
fmt = "w"
if fmt == "w" and self.args.th_no_webp:
if fmt == "w":
if self.args.th_no_webp or (is_vid and self.args.th_ff_jpg):
fmt = "j"
hist = self.hist[ptop]

View file

@ -11,7 +11,7 @@ import threading
import subprocess as sp
from .__init__ import PY2
from .util import fsenc, mchkcmd, Queue, Cooldown, BytesIO
from .util import fsenc, runcmd, Queue, Cooldown, BytesIO, min_ex
from .mtag import HAVE_FFMPEG, HAVE_FFPROBE, ffprobe
@ -213,9 +213,9 @@ class ThumbSrv(object):
if fun:
try:
fun(abspath, tpath)
except Exception as ex:
msg = "{} failed on {}\n {!r}"
self.log(msg.format(fun.__name__, abspath, ex), 3)
except:
msg = "{} failed on {}\n{}"
self.log(msg.format(fun.__name__, abspath, min_ex()), 3)
with open(tpath, "wb") as _:
pass
@ -263,8 +263,13 @@ class ThumbSrv(object):
def conv_ffmpeg(self, abspath, tpath):
ret, _ = ffprobe(abspath)
ext = abspath.rsplit(".")[-1]
if ext in ["h264", "h265"]:
seek = []
else:
dur = ret[".dur"][1] if ".dur" in ret else 4
seek = "{:.0f}".format(dur / 3)
seek = [b"-ss", seek.encode("utf-8")]
scale = "scale={0}:{1}:force_original_aspect_ratio="
if self.args.th_no_crop:
@ -273,19 +278,20 @@ class ThumbSrv(object):
scale += "increase,crop={0}:{1},setsar=1:1"
scale = scale.format(*list(self.res)).encode("utf-8")
# fmt: off
cmd = [
b"ffmpeg",
b"-nostdin",
b"-hide_banner",
b"-ss",
seek,
b"-i",
fsenc(abspath),
b"-vf",
scale,
b"-vframes",
b"1",
b"-v", b"error",
b"-hide_banner"
]
cmd += seek
cmd += [
b"-i", fsenc(abspath),
b"-vf", scale,
b"-vframes", b"1",
]
# fmt: on
if tpath.endswith(".jpg"):
cmd += [
@ -302,7 +308,11 @@ class ThumbSrv(object):
cmd += [fsenc(tpath)]
mchkcmd(cmd)
ret, sout, serr = runcmd(*cmd)
if ret != 0:
msg = ["ff: {}".format(x) for x in serr.split("\n")]
self.log("FFmpeg failed:\n" + "\n".join(msg), c="1;30")
raise sp.CalledProcessError(ret, (cmd[0], b"...", cmd[-1]))
def poke(self, tdir):
if not self.poke_cd.poke(tdir):

View file

@ -998,8 +998,8 @@ def guess_mime(url, fallback="application/octet-stream"):
def runcmd(*argv):
p = sp.Popen(argv, stdout=sp.PIPE, stderr=sp.PIPE)
stdout, stderr = p.communicate()
stdout = stdout.decode("utf-8")
stderr = stderr.decode("utf-8")
stdout = stdout.decode("utf-8", "replace")
stderr = stderr.decode("utf-8", "replace")
return [p.returncode, stdout, stderr]

View file

@ -46,20 +46,22 @@ def main():
with open(vidp, "rb") as f:
ovid = f.read()
args = ["-p", "4321"]
args = ["-p", "4321", "-e2dsa", "-e2tsr"]
pdirs = []
for d1 in ["r", "w", "a"]:
pdirs.append("{}/{}".format(td, d1))
pdirs.append("{}/{}/j".format(td, d1))
for d2 in ["r", "w", "a"]:
d = os.path.join(td, d1, "j", d2)
pdirs.append(d.replace("\\", "/"))
os.makedirs(d)
udirs = [x.split("/", 2)[2] for x in pdirs]
for pd, ud in zip(pdirs, udirs):
perms = [x.rstrip("j/")[-1] for x in pdirs]
for pd, ud, p in zip(pdirs, udirs, perms):
# args += ["-v", "{}:{}:{}".format(d.split("/", 1)[1], d, d[-1])]
args += ["-v", "{}:{}:{}".format(pd, ud, ud[-1])]
args += ["-v", "{}:{}:{}".format(pd, ud, p)]
cpp = Cpp(args)
@ -74,14 +76,36 @@ def main():
pass
assert up
# for d in dirs:
# rd, fn = d.rsplit("/", 1)
# requests.post(ub + rd, files={"act": "mkdir", "name": fn})
for d in udirs:
vid = ovid + "\n{}".format(d).encode("utf-8")
requests.post(ub + d, data={"act": "bput"}, files={"f": ("a.h264", vid)})
time.sleep(3)
for d, p in zip(udirs, perms):
u = "{}{}/a.h264".format(ub, d)
r = requests.get(u)
ok = bool(r)
if ok != (p in ["a"]):
raise Exception("get {} with perm {} at {}".format(ok, p, u))
for d, p in zip(pdirs, perms):
u = "{}/a.h264".format(d)
ok = os.path.exists(u)
if ok != (p in ["a", "w"]):
raise Exception("stat {} with perm {} at {}".format(ok, p, u))
for d, p in zip(udirs, perms):
u = "{}{}/a.h264?th=j".format(ub, d)
r = requests.get(u)
ok = False
if r:
r.raw.decode_content = True
buf = r.raw.read(256)
if buf[:3] == b"\xff\xd8\xff":
ok = True
if ok != (p in ["a"]):
raise Exception("thumb {} with perm {} at {}".format(ok, p, u))
cpp.stop(True)