mirror of
https://github.com/9001/copyparty.git
synced 2025-08-18 01:22:13 -06:00
add audio transcoder
This commit is contained in:
parent
26c8589399
commit
f6f9fc5a45
|
@ -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")
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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"]:
|
||||
|
|
|
@ -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,6 +208,9 @@ class ThumbSrv(object):
|
|||
elif ext in FMT_FFV:
|
||||
fun = self.conv_ffmpeg
|
||||
elif ext in FMT_FFA:
|
||||
if tpath.endswith(".opus"):
|
||||
fun = self.conv_opus
|
||||
else:
|
||||
fun = self.conv_spec
|
||||
|
||||
if fun:
|
||||
|
@ -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
|
||||
|
|
|
@ -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 }},
|
||||
|
|
|
@ -320,6 +320,14 @@ var mpl = (function () {
|
|||
'<a href="#" class="tgl btn" tt="load the next folder and continue">📂 next-folder</a>' +
|
||||
'</div></div>' +
|
||||
|
||||
(have_acode ? (
|
||||
'<div><h3>transcode</h3><div>' +
|
||||
'<a href="#" id="ac_flac" class="tgl btn" tt="convert flac to opus">flac</a>' +
|
||||
'<a href="#" id="ac_aac" class="tgl btn" tt="convert aac/m4a to opus">aac</a>' +
|
||||
'<a href="#" id="ac_oth" class="tgl btn" tt="convert all others (not mp3) to opus">oth</a>' +
|
||||
'</div></div>'
|
||||
) : '') +
|
||||
|
||||
'<div><h3>tint</h3><div>' +
|
||||
'<input type="text" id="pb_tint" size="3" value="0" tt="background level (0-100) on the seekbar$Nto make buffering less distracting" />' +
|
||||
'</div></div>' +
|
||||
|
@ -335,6 +343,9 @@ var mpl = (function () {
|
|||
bcfg_bind(r, 'clip', 'au_npclip', false, function (v) {
|
||||
clmod(ebi('wtoggle'), 'np', v && mp.au);
|
||||
});
|
||||
bcfg_bind(r, 'ac_flac', 'ac_flac', true);
|
||||
bcfg_bind(r, 'ac_aac', 'ac_aac', false);
|
||||
bcfg_bind(r, 'ac_oth', 'ac_oth', true, reload_mp);
|
||||
|
||||
ebi('au_os_ctl').onclick = function (e) {
|
||||
ev(e);
|
||||
|
@ -373,6 +384,23 @@ var mpl = (function () {
|
|||
};
|
||||
set_tint();
|
||||
|
||||
r.acode = function (url) {
|
||||
var c = true;
|
||||
if (!have_acode)
|
||||
c = false;
|
||||
else if (/\.flac$/i.exec(url))
|
||||
c = r.ac_flac;
|
||||
else if (/\.(aac|m4a)$/i.exec(url))
|
||||
c = r.ac_aac;
|
||||
else if (re_au_native.exec(url))
|
||||
c = false;
|
||||
|
||||
if (!c)
|
||||
return url;
|
||||
|
||||
return url + (url.indexOf('?') < 0 ? '?' : '&') + 'th=opus';
|
||||
};
|
||||
|
||||
r.pp = function () {
|
||||
if (!r.os_ctl)
|
||||
return;
|
||||
|
@ -441,6 +469,10 @@ var mpl = (function () {
|
|||
})();
|
||||
|
||||
|
||||
var re_au_native = /\.(opus|ogg|m4a|aac|mp3|wav|flac)$/i,
|
||||
re_au_all = /\.(aac|m4a|ogg|opus|flac|alac|mp3|mp2|ac3|dts|wma|ra|wav|aif|aiff|au|amr|gsm|ape|tak|tta|wv)$/i;
|
||||
|
||||
|
||||
// extract songs + add play column
|
||||
function MPlayer() {
|
||||
var r = this;
|
||||
|
@ -454,7 +486,7 @@ function MPlayer() {
|
|||
r.tracks = {};
|
||||
r.order = [];
|
||||
|
||||
var re_audio = /\.(opus|ogg|m4a|aac|mp3|wav|flac)$/i,
|
||||
var re_audio = mpl.ac_oth ? re_au_all : re_au_native,
|
||||
trs = QSA('#files tbody tr');
|
||||
|
||||
for (var a = 0, aa = trs.length; a < aa; a++) {
|
||||
|
@ -552,6 +584,7 @@ function MPlayer() {
|
|||
|
||||
r.preload = function (url) {
|
||||
var au = null;
|
||||
url = mpl.acode(url);
|
||||
if (need_ogv_for(url)) {
|
||||
au = mp.au_ogvjs2;
|
||||
if (!au && window['OGVPlayer']) {
|
||||
|
@ -1033,7 +1066,7 @@ var mpui = (function () {
|
|||
if (pos > 0 && pos > len - 10) {
|
||||
preloaded = mp.au.src;
|
||||
try {
|
||||
mp.preload(ebi(mp.order[mp.order.indexOf(mp.au.tid) + 1]).href);
|
||||
mp.preload(mp.tracks[mp.order[mp.order.indexOf(mp.au.tid) + 1]]);
|
||||
}
|
||||
catch (ex) {
|
||||
console.log("preload failed", ex);
|
||||
|
@ -1078,7 +1111,7 @@ catch (ex) { }
|
|||
|
||||
|
||||
function need_ogv_for(url) {
|
||||
return need_ogv && /\.(ogg|opus)$/i.test(url);
|
||||
return need_ogv && /\.(ogg|opus)|\?th=opus/i.test(url);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1378,7 +1411,7 @@ function play(tid, is_ev, seek, call_depth) {
|
|||
// ogv.js breaks on .play() unless directly user-triggered
|
||||
var attempt_play = true;
|
||||
|
||||
var url = mp.tracks[tid];
|
||||
var url = mpl.acode(mp.tracks[tid]);
|
||||
if (need_ogv_for(url)) {
|
||||
var m = /.* Version\/([0-9]+)\.[0-9\.]+ Mobile\/[^ ]+ Safari\/[0-9\.]+$/.exec(navigator.userAgent),
|
||||
safari = m ? parseInt(m[1]) : 99;
|
||||
|
@ -1435,7 +1468,7 @@ function play(tid, is_ev, seek, call_depth) {
|
|||
|
||||
audio_eq.apply();
|
||||
|
||||
url += (url.indexOf('?') < 0 ? '?cache' : '&cache');
|
||||
url += (url.indexOf('?') < 0 ? '?' : '&') + 'cache';
|
||||
if (mp.au.src == url)
|
||||
mp.au.currentTime = 0;
|
||||
else {
|
||||
|
@ -4450,6 +4483,10 @@ function reload_mp() {
|
|||
}
|
||||
mpl.stop();
|
||||
widget.close();
|
||||
var plays = QSA('tr>td:first-child>a.play');
|
||||
for (var a = plays.length - 1; a >= 0; a--)
|
||||
plays[a].parentNode.innerHTML = '-';
|
||||
|
||||
mp = new MPlayer();
|
||||
setTimeout(pbar.onresize, 1);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue