diff --git a/README.md b/README.md index 8535bea5..786244d7 100644 --- a/README.md +++ b/README.md @@ -225,6 +225,7 @@ also see [comparison to similar software](./docs/versus.md) * ☑ [navpane](#navpane) (directory tree sidebar) * ☑ file manager (cut/paste, delete, [batch-rename](#batch-rename)) * ☑ audio player (with [OS media controls](https://user-images.githubusercontent.com/241032/215347492-b4250797-6c90-4e09-9a4c-721edf2fb15c.png) and opus/mp3 transcoding) + * ☑ play video files as audio (converted on server) * ☑ image gallery with webm player * ☑ textfile browser with syntax hilighting * ☑ [thumbnails](#thumbnails) @@ -801,6 +802,7 @@ some hilights: * OS integration; control playback from your phone's lockscreen ([windows](https://user-images.githubusercontent.com/241032/233213022-298a98ba-721a-4cf1-a3d4-f62634bc53d5.png) // [iOS](https://user-images.githubusercontent.com/241032/142711926-0700be6c-3e31-47b3-9928-53722221f722.png) // [android](https://user-images.githubusercontent.com/241032/233212311-a7368590-08c7-4f9f-a1af-48ccf3f36fad.png)) * shows the audio waveform in the seekbar * not perfectly gapless but can get really close (see settings + eq below); good enough to enjoy gapless albums as intended +* videos can be played as audio, without wasting bandwidth on the video click the `play` link next to an audio file, or copy the link target to [share it](https://a.ocv.me/pub/demo/music/Ubiktune%20-%20SOUNDSHOCK%202%20-%20FM%20FUNK%20TERRROR!!/#af-1fbfba61&t=18) (optionally with a timestamp to start playing from, like that example does) diff --git a/copyparty/th_cli.py b/copyparty/th_cli.py index 0c69be5f..6bebd3de 100644 --- a/copyparty/th_cli.py +++ b/copyparty/th_cli.py @@ -59,7 +59,8 @@ class ThumbCli(object): want_opus = fmt in ("opus", "caf", "mp3") is_au = ext in self.fmt_ffa - if is_au: + is_vau = want_opus and ext in self.fmt_ffv + if is_au or is_vau: if want_opus: if self.args.no_acode: return None @@ -107,7 +108,7 @@ class ThumbCli(object): fmt = sfmt - elif fmt[:1] == "p" and not is_au: + elif fmt[:1] == "p" and not is_au and not is_vid: t = "cannot thumbnail [%s]: png only allowed for waveforms" self.log(t % (rem), 6) return None diff --git a/copyparty/th_srv.py b/copyparty/th_srv.py index 88d03395..0f9dcf1f 100644 --- a/copyparty/th_srv.py +++ b/copyparty/th_srv.py @@ -304,23 +304,29 @@ class ThumbSrv(object): ap_unpk = abspath if not bos.path.exists(tpath): + want_mp3 = tpath.endswith(".mp3") + want_opus = tpath.endswith(".opus") or tpath.endswith(".caf") + want_png = tpath.endswith(".png") + want_au = want_mp3 or want_opus for lib in self.args.th_dec: + can_au = lib == "ff" and (ext in self.fmt_ffa or ext in self.fmt_ffv) + if lib == "pil" and ext in self.fmt_pil: funs.append(self.conv_pil) elif lib == "vips" and ext in self.fmt_vips: funs.append(self.conv_vips) - elif lib == "ff" and ext in self.fmt_ffi or ext in self.fmt_ffv: - funs.append(self.conv_ffmpeg) - elif lib == "ff" and ext in self.fmt_ffa: - if tpath.endswith(".opus") or tpath.endswith(".caf"): + elif can_au and (want_png or want_au): + if want_opus: funs.append(self.conv_opus) - elif tpath.endswith(".mp3"): + elif want_mp3: funs.append(self.conv_mp3) - elif tpath.endswith(".png"): + elif want_png: funs.append(self.conv_waves) png_ok = True - else: - funs.append(self.conv_spec) + elif lib == "ff" and (ext in self.fmt_ffi or ext in self.fmt_ffv): + funs.append(self.conv_ffmpeg) + elif lib == "ff" and ext in self.fmt_ffa and not want_au: + funs.append(self.conv_spec) tdir, tfn = os.path.split(tpath) ttpath = os.path.join(tdir, "w", tfn) diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index d4f54be8..99aa7b68 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -360,6 +360,7 @@ var Ls = { "tvt_sel": "select file   ( for cut / delete / ... )$NHotkey: S\">sel", "tvt_edit": "open file in text editor$NHotkey: E\">✏️ edit", + "gt_vau": "don't show videos, just play the audio\">🎧", "gt_msel": "enable file selection; ctrl-click a file to override$N$N<em>when active: doubleclick a file / folder to open it</em>$N$NHotkey: S\">multiselect", "gt_crop": "center-crop thumbnails\">crop", "gt_3x": "hi-res thumbnails\">3x", @@ -874,6 +875,7 @@ var Ls = { "tvt_sel": "markér filen   ( for utklipp / sletting / ... )$NSnarvei: S\">merk", "tvt_edit": "redigér filen$NSnarvei: E\">✏️ endre", + "gt_vau": "ikke vis videofiler, bare spill lyden\">🎧", "gt_msel": "markér filer istedenfor å åpne dem; ctrl-klikk filer for å overstyre$N$N<em>når aktiv: dobbelklikk en fil / mappe for å åpne</em>$N$NSnarvei: S\">markering", "gt_crop": "beskjær ikonene så de passer bedre\">✂", "gt_3x": "høyere oppløsning på ikoner\">3x", @@ -1709,7 +1711,7 @@ catch (ex) { } var re_au_native = (can_ogg || have_acode) ? /\.(aac|flac|m4a|mp3|ogg|opus|wav)$/i : /\.(aac|flac|m4a|mp3|wav)$/i, - re_au_all = /\.(aac|ac3|aif|aiff|alac|alaw|amr|ape|au|dfpwm|dts|flac|gsm|it|itgz|itxz|itz|m4a|mdgz|mdxz|mdz|mo3|mod|mp2|mp3|mpc|mptm|mt2|mulaw|ogg|okt|opus|ra|s3m|s3gz|s3xz|s3z|tak|tta|ulaw|wav|wma|wv|xm|xmgz|xmxz|xmz|xpk)$/i; + re_au_all = /\.(aac|ac3|aif|aiff|alac|alaw|amr|ape|au|dfpwm|dts|flac|gsm|it|itgz|itxz|itz|m4a|mdgz|mdxz|mdz|mo3|mod|mp2|mp3|mpc|mptm|mt2|mulaw|ogg|okt|opus|ra|s3m|s3gz|s3xz|s3z|tak|tta|ulaw|wav|wma|wv|xm|xmgz|xmxz|xmz|xpk|3gp|asf|avi|flv|m4v|mkv|mov|mp4|mpeg|mpeg2|mpegts|mpg|mpg2|nut|ogm|ogv|rm|ts|vob|webm|wmv)$/i; // extract songs + add play column @@ -4410,7 +4412,7 @@ var showfile = (function () { var td = ebi(link.id).closest('tr').getElementsByTagName('td')[0]; - if (lang == 'md' && td.textContent != '-') + if (lang == 'ts' || (lang == 'md' && td.textContent != '-')) continue; td.innerHTML = '' + + '