mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 09:02:15 -06:00
Add flac transcoding option
This commit is contained in:
parent
b469db3c62
commit
b2d48c646f
|
@ -1449,6 +1449,8 @@ def add_transcoding(ap):
|
||||||
ap2.add_argument("--q-mp3", metavar="QUALITY", type=u, default="q2", help="target quality for transcoding to mp3, for example [\033[32m192k\033[0m] (CBR) or [\033[32mq0\033[0m] (CQ/CRF, q0=maxquality, q9=smallest); set 0 to disable")
|
ap2.add_argument("--q-mp3", metavar="QUALITY", type=u, default="q2", help="target quality for transcoding to mp3, for example [\033[32m192k\033[0m] (CBR) or [\033[32mq0\033[0m] (CQ/CRF, q0=maxquality, q9=smallest); set 0 to disable")
|
||||||
ap2.add_argument("--no-caf", action="store_true", help="disable transcoding to caf-opus (affects iOS v12~v17), will use mp3 instead")
|
ap2.add_argument("--no-caf", action="store_true", help="disable transcoding to caf-opus (affects iOS v12~v17), will use mp3 instead")
|
||||||
ap2.add_argument("--no-owa", action="store_true", help="disable transcoding to webm-opus (iOS v18 and later), will use mp3 instead")
|
ap2.add_argument("--no-owa", action="store_true", help="disable transcoding to webm-opus (iOS v18 and later), will use mp3 instead")
|
||||||
|
ap2.add_argument("--no-wav", action="store_true", help="disable transcoding to wav (lossless, uncompressed)")
|
||||||
|
ap2.add_argument("--no-flac", action="store_true", help="disable transcoding to flac (lossless, compressed)")
|
||||||
ap2.add_argument("--no-acode", action="store_true", help="disable audio transcoding")
|
ap2.add_argument("--no-acode", action="store_true", help="disable audio transcoding")
|
||||||
ap2.add_argument("--no-bacode", action="store_true", help="disable batch audio transcoding by folder download (zip/tar)")
|
ap2.add_argument("--no-bacode", action="store_true", help="disable batch audio transcoding by folder download (zip/tar)")
|
||||||
ap2.add_argument("--ac-maxage", metavar="SEC", type=int, default=86400, help="delete cached transcode output after \033[33mSEC\033[0m seconds")
|
ap2.add_argument("--ac-maxage", metavar="SEC", type=int, default=86400, help="delete cached transcode output after \033[33mSEC\033[0m seconds")
|
||||||
|
|
|
@ -4684,7 +4684,7 @@ class HttpCli(object):
|
||||||
# for f in fgen: print(repr({k: f[k] for k in ["vp", "ap"]}))
|
# for f in fgen: print(repr({k: f[k] for k in ["vp", "ap"]}))
|
||||||
cfmt = ""
|
cfmt = ""
|
||||||
if self.thumbcli and not self.args.no_bacode:
|
if self.thumbcli and not self.args.no_bacode:
|
||||||
for zs in ("opus", "mp3", "wav", "w", "j", "p"):
|
for zs in ("opus", "mp3", "flac", "wav", "w", "j", "p"):
|
||||||
if zs in self.ouparam or uarg == zs:
|
if zs in self.ouparam or uarg == zs:
|
||||||
cfmt = zs
|
cfmt = zs
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ HAVE_AVIF = False
|
||||||
HAVE_WEBP = False
|
HAVE_WEBP = False
|
||||||
|
|
||||||
EXTS_TH = set(["jpg", "webp", "png"])
|
EXTS_TH = set(["jpg", "webp", "png"])
|
||||||
EXTS_AC = set(["opus", "owa", "caf", "mp3", "wav"])
|
EXTS_AC = set(["opus", "owa", "caf", "mp3", "flac", "wav"])
|
||||||
EXTS_SPEC_SAFE = set("aif aiff flac mp3 opus wav".split())
|
EXTS_SPEC_SAFE = set("aif aiff flac mp3 opus wav".split())
|
||||||
|
|
||||||
PTN_TS = re.compile("^-?[0-9a-f]{8,10}$")
|
PTN_TS = re.compile("^-?[0-9a-f]{8,10}$")
|
||||||
|
@ -355,9 +355,10 @@ class ThumbSrv(object):
|
||||||
tex = tpath.rsplit(".", 1)[-1]
|
tex = tpath.rsplit(".", 1)[-1]
|
||||||
want_mp3 = tex == "mp3"
|
want_mp3 = tex == "mp3"
|
||||||
want_opus = tex in ("opus", "owa", "caf")
|
want_opus = tex in ("opus", "owa", "caf")
|
||||||
|
want_flac = tex == "flac"
|
||||||
want_wav = tex == "wav"
|
want_wav = tex == "wav"
|
||||||
want_png = tex == "png"
|
want_png = tex == "png"
|
||||||
want_au = want_mp3 or want_opus or want_wav
|
want_au = want_mp3 or want_opus or want_flac or want_wav
|
||||||
for lib in self.args.th_dec:
|
for lib in self.args.th_dec:
|
||||||
can_au = lib == "ff" and (
|
can_au = lib == "ff" and (
|
||||||
ext in self.fmt_ffa or ext in self.fmt_ffv
|
ext in self.fmt_ffa or ext in self.fmt_ffv
|
||||||
|
@ -372,6 +373,8 @@ class ThumbSrv(object):
|
||||||
funs.append(self.conv_opus)
|
funs.append(self.conv_opus)
|
||||||
elif want_mp3:
|
elif want_mp3:
|
||||||
funs.append(self.conv_mp3)
|
funs.append(self.conv_mp3)
|
||||||
|
elif want_flac:
|
||||||
|
funs.append(self.conv_flac)
|
||||||
elif want_wav:
|
elif want_wav:
|
||||||
funs.append(self.conv_wav)
|
funs.append(self.conv_wav)
|
||||||
elif want_png:
|
elif want_png:
|
||||||
|
@ -583,7 +586,7 @@ class ThumbSrv(object):
|
||||||
self._run_ff(cmd, vn)
|
self._run_ff(cmd, vn)
|
||||||
|
|
||||||
def _run_ff(self, cmd: list[bytes], vn: VFS, oom: int = 400) -> None:
|
def _run_ff(self, cmd: list[bytes], vn: VFS, oom: int = 400) -> None:
|
||||||
self.log((b" ".join(cmd)).decode("utf-8"))
|
# self.log((b" ".join(cmd)).decode("utf-8"))
|
||||||
ret, _, serr = runcmd(cmd, timeout=vn.flags["convt"], nice=True, oom=oom)
|
ret, _, serr = runcmd(cmd, timeout=vn.flags["convt"], nice=True, oom=oom)
|
||||||
if not ret:
|
if not ret:
|
||||||
return
|
return
|
||||||
|
@ -810,8 +813,33 @@ class ThumbSrv(object):
|
||||||
# fmt: on
|
# fmt: on
|
||||||
self._run_ff(cmd, vn, oom=300)
|
self._run_ff(cmd, vn, oom=300)
|
||||||
|
|
||||||
|
def conv_flac(self, abspath: str, tpath: str, fmt: str, vn: VFS) -> None:
|
||||||
|
if self.args.no_acode or self.args.no_flac:
|
||||||
|
raise Exception("disabled in server config")
|
||||||
|
|
||||||
|
self.wait4ram(0.2, tpath)
|
||||||
|
tags, rawtags = ffprobe(abspath, int(vn.flags["convt"] / 2))
|
||||||
|
if "ac" not in tags:
|
||||||
|
raise Exception("not audio")
|
||||||
|
|
||||||
|
self.log("conv2 flac", 6)
|
||||||
|
|
||||||
|
# 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"flac",
|
||||||
|
fsenc(tpath)
|
||||||
|
]
|
||||||
|
# fmt: on
|
||||||
|
self._run_ff(cmd, vn, oom=300)
|
||||||
|
|
||||||
def conv_wav(self, abspath: str, tpath: str, fmt: str, vn: VFS) -> None:
|
def conv_wav(self, abspath: str, tpath: str, fmt: str, vn: VFS) -> None:
|
||||||
if self.args.no_acode or not self.args.q_wav:
|
if self.args.no_acode or self.args.no_wav:
|
||||||
raise Exception("disabled in server config")
|
raise Exception("disabled in server config")
|
||||||
|
|
||||||
self.wait4ram(0.2, tpath)
|
self.wait4ram(0.2, tpath)
|
||||||
|
@ -824,12 +852,12 @@ class ThumbSrv(object):
|
||||||
bits = tags[".bprs"][1]
|
bits = tags[".bprs"][1]
|
||||||
|
|
||||||
codec = b"pcm_s32le"
|
codec = b"pcm_s32le"
|
||||||
if bits == 16.0:
|
if bits <= 16.0:
|
||||||
codec = b"pcm_s16le"
|
codec = b"pcm_s16le"
|
||||||
elif bits == 24.0:
|
elif bits <= 24.0:
|
||||||
codec = b"pcm_s24le"
|
codec = b"pcm_s24le"
|
||||||
|
|
||||||
self.log("conv2 wav-tmp", 6)
|
self.log("conv2 wav", 6)
|
||||||
|
|
||||||
# fmt: off
|
# fmt: off
|
||||||
cmd = [
|
cmd = [
|
||||||
|
@ -843,7 +871,6 @@ class ThumbSrv(object):
|
||||||
fsenc(tpath)
|
fsenc(tpath)
|
||||||
]
|
]
|
||||||
# fmt: on
|
# fmt: on
|
||||||
print(cmd)
|
|
||||||
self._run_ff(cmd, vn, oom=300)
|
self._run_ff(cmd, vn, oom=300)
|
||||||
|
|
||||||
def conv_opus(self, abspath: str, tpath: str, fmt: str, vn: VFS) -> None:
|
def conv_opus(self, abspath: str, tpath: str, fmt: str, vn: VFS) -> None:
|
||||||
|
|
|
@ -306,7 +306,8 @@ var Ls = {
|
||||||
"mt_c2owa": "opus-weba, for iOS 17.5 and newer\">owa",
|
"mt_c2owa": "opus-weba, for iOS 17.5 and newer\">owa",
|
||||||
"mt_c2caf": "opus-caf, for iOS 11 through 17\">caf",
|
"mt_c2caf": "opus-caf, for iOS 11 through 17\">caf",
|
||||||
"mt_c2mp3": "use this on very old devices\">mp3",
|
"mt_c2mp3": "use this on very old devices\">mp3",
|
||||||
"mt_c2wav": "use this for uncompressed playback\">wav",
|
"mt_c2flac": "best sound quality\">flac",
|
||||||
|
"mt_c2wav": "uncompressed playback\">wav",
|
||||||
"mt_c2ok": "nice, good choice",
|
"mt_c2ok": "nice, good choice",
|
||||||
"mt_c2nd": "that's not the recommended output format for your device, but that's fine",
|
"mt_c2nd": "that's not the recommended output format for your device, but that's fine",
|
||||||
"mt_c2ng": "your device does not seem to support this output format, but let's try anyways",
|
"mt_c2ng": "your device does not seem to support this output format, but let's try anyways",
|
||||||
|
@ -6803,6 +6804,7 @@ var mpl = (function () {
|
||||||
'<a href="#" id="ac2owa" class="tgl btn" tt="' + L.mt_c2owa + '</a>' +
|
'<a href="#" id="ac2owa" class="tgl btn" tt="' + L.mt_c2owa + '</a>' +
|
||||||
'<a href="#" id="ac2caf" class="tgl btn" tt="' + L.mt_c2caf + '</a>' +
|
'<a href="#" id="ac2caf" class="tgl btn" tt="' + L.mt_c2caf + '</a>' +
|
||||||
'<a href="#" id="ac2mp3" class="tgl btn" tt="' + L.mt_c2mp3 + '</a>' +
|
'<a href="#" id="ac2mp3" class="tgl btn" tt="' + L.mt_c2mp3 + '</a>' +
|
||||||
|
'<a href="#" id="ac2flac" class="tgl btn" tt="' + L.mt_c2flac + '</a>' +
|
||||||
'<a href="#" id="ac2wav" class="tgl btn" tt="' + L.mt_c2wav + '</a>' +
|
'<a href="#" id="ac2wav" class="tgl btn" tt="' + L.mt_c2wav + '</a>' +
|
||||||
'</div></div>'
|
'</div></div>'
|
||||||
) : '') +
|
) : '') +
|
||||||
|
@ -6946,8 +6948,11 @@ var mpl = (function () {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var dv = can_ogg ? 'opus' : can_caf ? 'caf' : can_mp3 ? 'mp3' : 'wav',
|
var dv = can_ogg ? 'opus' :
|
||||||
fmts = ['opus', 'owa', 'caf', 'mp3', 'wav'],
|
can_caf ? 'caf' :
|
||||||
|
can_mp3 ? 'mp3' :
|
||||||
|
can_flac ? 'flac' : 'wav',
|
||||||
|
fmts = ['opus', 'owa', 'caf', 'mp3', 'flac', 'wav'],
|
||||||
btns = [];
|
btns = [];
|
||||||
|
|
||||||
if (v === dv)
|
if (v === dv)
|
||||||
|
@ -6958,7 +6963,8 @@ var mpl = (function () {
|
||||||
if ((v == 'opus' && !can_ogg) ||
|
if ((v == 'opus' && !can_ogg) ||
|
||||||
(v == 'caf' && !can_caf) ||
|
(v == 'caf' && !can_caf) ||
|
||||||
(v == 'owa' && !can_owa) ||
|
(v == 'owa' && !can_owa) ||
|
||||||
(v == 'mp3' && !can_mp3))
|
(v == 'mp3' && !can_mp3) ||
|
||||||
|
(v == 'flac' && !can_flac))
|
||||||
toast.warn(15, L.mt_c2ng);
|
toast.warn(15, L.mt_c2ng);
|
||||||
|
|
||||||
if (v == 'owa' && IPHONE)
|
if (v == 'owa' && IPHONE)
|
||||||
|
@ -7097,12 +7103,14 @@ var za,
|
||||||
can_ogg = true,
|
can_ogg = true,
|
||||||
can_owa = false,
|
can_owa = false,
|
||||||
can_mp3 = false,
|
can_mp3 = false,
|
||||||
|
can_flac = false,
|
||||||
can_caf = APPLE && !/ OS ([1-9]|1[01])_/.test(UA);
|
can_caf = APPLE && !/ OS ([1-9]|1[01])_/.test(UA);
|
||||||
try {
|
try {
|
||||||
za = new Audio();
|
za = new Audio();
|
||||||
can_ogg = za.canPlayType('audio/ogg; codecs=opus') === 'probably';
|
can_ogg = za.canPlayType('audio/ogg; codecs=opus') === 'probably';
|
||||||
can_owa = za.canPlayType('audio/webm; codecs=opus') === 'probably';
|
can_owa = za.canPlayType('audio/webm; codecs=opus') === 'probably';
|
||||||
can_mp3 = za.canPlayType('audio/mpeg') === 'probably';
|
can_mp3 = za.canPlayType('audio/mpeg') === 'probably';
|
||||||
|
can_flac = za.canPlayType('audio/flac') === 'probably';
|
||||||
can_caf = za.canPlayType('audio/x-caf') && can_caf; //'maybe'
|
can_caf = za.canPlayType('audio/x-caf') && can_caf; //'maybe'
|
||||||
}
|
}
|
||||||
catch (ex) { }
|
catch (ex) { }
|
||||||
|
|
|
@ -390,6 +390,8 @@ var tl_browser = {
|
||||||
"mt_c2owa": "opus-weba, for iOS 17.5 and newer\">owa",
|
"mt_c2owa": "opus-weba, for iOS 17.5 and newer\">owa",
|
||||||
"mt_c2caf": "opus-caf, for iOS 11 through 17\">caf",
|
"mt_c2caf": "opus-caf, for iOS 11 through 17\">caf",
|
||||||
"mt_c2mp3": "use this on very old devices\">mp3",
|
"mt_c2mp3": "use this on very old devices\">mp3",
|
||||||
|
"mt_c2flac": "best sound quality\">flac",
|
||||||
|
"mt_c2wav": "uncompressed playback\">wav",
|
||||||
"mt_c2ok": "nice, good choice",
|
"mt_c2ok": "nice, good choice",
|
||||||
"mt_c2nd": "that's not the recommended output format for your device, but that's fine",
|
"mt_c2nd": "that's not the recommended output format for your device, but that's fine",
|
||||||
"mt_c2ng": "your device does not seem to support this output format, but let's try anyways",
|
"mt_c2ng": "your device does not seem to support this output format, but let's try anyways",
|
||||||
|
|
Loading…
Reference in a new issue