diff --git a/copyparty/__main__.py b/copyparty/__main__.py index db5d63a0..a10b6170 100644 --- a/copyparty/__main__.py +++ b/copyparty/__main__.py @@ -416,6 +416,9 @@ def run_argparse(argv, formatter): ap2.add_argument("--th-maxage", metavar="SEC", type=int, default=604800, help="max folder age") ap2.add_argument("--th-covers", metavar="N,N", type=u, default="folder.png,folder.jpg,cover.png,cover.jpg", help="folder thumbnails to stat for") + ap2 = ap.add_argument_group('transcoding options') + ap2.add_argument("--no-acode", action="store_true", help="disable audio transcoding") + ap2 = ap.add_argument_group('general db options') ap2.add_argument("-e2d", action="store_true", help="enable up2k database") ap2.add_argument("-e2ds", action="store_true", help="enable up2k db-scanner, sets -e2d") diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index d0ce8dd1..477edd76 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -2072,6 +2072,7 @@ class HttpCli(object): "def_hcols": [], "have_up2k_idx": ("e2d" in vn.flags), "have_tags_idx": ("e2t" in vn.flags), + "have_acode": (not self.args.no_acode), "have_mv": (not self.args.no_mv), "have_del": (not self.args.no_del), "have_zip": (not self.args.no_zip), diff --git a/copyparty/th_cli.py b/copyparty/th_cli.py index 687cbbb3..c64f921f 100644 --- a/copyparty/th_cli.py +++ b/copyparty/th_cli.py @@ -26,8 +26,16 @@ class ThumbCli(object): if is_vid and self.args.no_vthumb: return None + want_opus = fmt == "opus" is_au = ext in FMT_FFA - if is_au and self.args.no_athumb: + if is_au: + if want_opus: + if self.args.no_acode: + return None + else: + if self.args.no_athumb: + return None + elif want_opus: return None if rem.startswith(".hist/th/") and rem.split(".")[-1] in ["webp", "jpg"]: diff --git a/copyparty/th_srv.py b/copyparty/th_srv.py index dacf1b4f..4358ceaf 100644 --- a/copyparty/th_srv.py +++ b/copyparty/th_srv.py @@ -51,7 +51,7 @@ except: # ffmpeg -formats FMT_PIL = "bmp dib gif icns ico jpg jpeg jp2 jpx pcx png pbm pgm ppm pnm sgi tga tif tiff webp xbm dds xpm" FMT_FFV = "av1 asf avi flv m4v mkv mjpeg mjpg mpg mpeg mpg2 mpeg2 h264 avc mts h265 hevc mov 3gp mp4 ts mpegts nut ogv ogm rm vob webm wmv" -FMT_FFA = "aac m4a ogg opus flac alac mp3 mp2 ac3 dts wma wav aif aiff au amr gsm ape tak tta wv" +FMT_FFA = "aac m4a ogg opus flac alac mp3 mp2 ac3 dts wma ra wav aif aiff au amr gsm ape tak tta wv" if HAVE_HEIF: FMT_PIL += " heif heifs heic heics" @@ -90,9 +90,10 @@ def thumb_path(histpath, rem, mtime, fmt): h = hashlib.sha512(fsenc(fn)).digest() fn = base64.urlsafe_b64encode(h).decode("ascii")[:24] - return "{}/th/{}/{}.{:x}.{}".format( - histpath, rd, fn, int(mtime), "webp" if fmt == "w" else "jpg" - ) + if fmt != "opus": + fmt = "webp" if fmt == "w" else "jpg" + + return "{}/th/{}/{}.{:x}.{}".format(histpath, rd, fn, int(mtime), fmt) class ThumbSrv(object): @@ -207,7 +208,10 @@ class ThumbSrv(object): elif ext in FMT_FFV: fun = self.conv_ffmpeg elif ext in FMT_FFA: - fun = self.conv_spec + if tpath.endswith(".opus"): + fun = self.conv_opus + else: + fun = self.conv_spec if fun: try: @@ -346,7 +350,6 @@ class ThumbSrv(object): def conv_spec(self, abspath, tpath): ret, _ = ffprobe(abspath) - if "ac" not in ret: raise Exception("not audio") @@ -381,6 +384,30 @@ class ThumbSrv(object): cmd += [fsenc(tpath)] self._run_ff(cmd) + def conv_opus(self, abspath, tpath): + if self.args.no_acode: + raise Exception("disabled in server config") + + ret, _ = ffprobe(abspath) + if "ac" not in ret: + raise Exception("not audio") + + # fmt: off + cmd = [ + b"ffmpeg", + b"-nostdin", + b"-v", b"error", + b"-hide_banner", + b"-i", fsenc(abspath), + b"-map", b"0:a:0", + b"-c:a", b"libopus", + b"-b:a", b"128k", + fsenc(tpath) + ] + # fmt: on + + self._run_ff(cmd) + def poke(self, tdir): if not self.poke_cd.poke(tdir): return diff --git a/copyparty/web/browser.html b/copyparty/web/browser.html index 4570f5ef..bf46ef8f 100644 --- a/copyparty/web/browser.html +++ b/copyparty/web/browser.html @@ -130,6 +130,7 @@ def_hcols = {{ def_hcols|tojson }}, have_up2k_idx = {{ have_up2k_idx|tojson }}, have_tags_idx = {{ have_tags_idx|tojson }}, + have_acode = {{ have_acode|tojson }}, have_mv = {{ have_mv|tojson }}, have_del = {{ have_del|tojson }}, have_unpost = {{ have_unpost|tojson }}, diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index e9ac30ae..c8f4f3b6 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -320,6 +320,14 @@ var mpl = (function () { '📂 next-folder' + '' + + (have_acode ? ( + '
' + ) : '') + + '