trick iphones into preloading natively

This commit is contained in:
ed 2021-11-15 03:01:11 +01:00
parent 9629fcde68
commit c1dccbe0ba

View file

@ -307,7 +307,8 @@ function set_files_html(html) {
} }
var ACtx = window.AudioContext || window.webkitAudioContext; var ACtx = window.AudioContext || window.webkitAudioContext,
actx = ACtx && new ACtx();
var mpl = (function () { var mpl = (function () {
@ -324,8 +325,8 @@ var mpl = (function () {
'</div></div>' + '</div></div>' +
'<div><h3>playback mode</h3><div id="pb_mode">' + '<div><h3>playback mode</h3><div id="pb_mode">' +
'<a href="#" class="tgl btn" tt="loop the open folder">🔁 loop-folder</a>' + '<a href="#" class="tgl btn" tt="loop the open folder">🔁 loop</a>' +
'<a href="#" class="tgl btn" tt="load the next folder and continue">📂 next-folder</a>' + '<a href="#" class="tgl btn" tt="load the next folder and continue">📂 next</a>' +
'</div></div>' + '</div></div>' +
(have_acode ? ( (have_acode ? (
@ -343,7 +344,7 @@ var mpl = (function () {
'<div><h3>audio equalizer</h3><div id="audio_eq"></div></div>'); '<div><h3>audio equalizer</h3><div id="audio_eq"></div></div>');
var r = { var r = {
"pb_mode": sread('pb_mode') || 'loop-folder', "pb_mode": (sread('pb_mode') || 'loop').split('-')[0],
"os_ctl": bcfg_get('au_os_ctl', have_mctl) && have_mctl, "os_ctl": bcfg_get('au_os_ctl', have_mctl) && have_mctl,
}; };
bcfg_bind(r, 'preload', 'au_preload', true); bcfg_bind(r, 'preload', 'au_preload', true);
@ -357,6 +358,11 @@ var mpl = (function () {
bcfg_bind(r, 'ac_aac', 'ac_aac', false); bcfg_bind(r, 'ac_aac', 'ac_aac', false);
bcfg_bind(r, 'ac_oth', 'ac_oth', true, reload_mp); bcfg_bind(r, 'ac_oth', 'ac_oth', true, reload_mp);
if (IPHONE) {
ebi('au_fullpre').style.display = 'none';
r.fullpre = false;
}
ebi('au_os_ctl').onclick = function (e) { ebi('au_os_ctl').onclick = function (e) {
ev(e); ev(e);
r.os_ctl = !r.os_ctl && have_mctl; r.os_ctl = !r.os_ctl && have_mctl;
@ -536,7 +542,7 @@ function MPlayer() {
} }
} }
r.vol = clamp(fcfg_get('vol', 0.5), 0, 1); r.vol = clamp(fcfg_get('vol', IPHONE ? 1 : 0.5), 0, 1);
r.expvol = function (v) { r.expvol = function (v) {
return 0.5 * v + 0.5 * v * v; return 0.5 * v + 0.5 * v * v;
@ -1102,10 +1108,10 @@ var mpui = (function () {
if (mpl.preload && preloaded != mp.au.rsrc) { if (mpl.preload && preloaded != mp.au.rsrc) {
var pos = mp.au.currentTime, var pos = mp.au.currentTime,
len = mp.au.duration, len = mp.au.duration,
rem = pos > 0 ? len - pos : 999, rem = pos > 1 ? len - pos : 999,
full = null; full = null;
if (rem < (mpl.fullpre && !(is_touch && IPHONE)) ? 7 : 20) { if (rem < (mpl.fullpre ? 7 : 20)) {
preloaded = fpreloaded = mp.au.rsrc; preloaded = fpreloaded = mp.au.rsrc;
full = false; full = false;
} }
@ -1151,15 +1157,18 @@ var audio_eq = (function () {
"gains": [4, 3, 2, 1, 0, 0, 1, 2, 3, 4], "gains": [4, 3, 2, 1, 0, 0, 1, 2, 3, 4],
"filters": [], "filters": [],
"amp": 0, "amp": 0,
"last_au": null "last_au": null,
"acst": {}
}; };
if (!actx)
ebi('audio_eq').parentNode.style.display = 'none';
// some browsers have insane high-frequency boost // some browsers have insane high-frequency boost
// (or rather the actual problem is Q but close enough) // (or rather the actual problem is Q but close enough)
r.cali = (function () { r.cali = (function () {
try { try {
var ac = new AudioContext(), var fi = actx.createBiquadFilter(),
fi = ac.createBiquadFilter(),
freqs = new Float32Array(1), freqs = new Float32Array(1),
mag = new Float32Array(1), mag = new Float32Array(1),
phase = new Float32Array(1); phase = new Float32Array(1);
@ -1219,35 +1228,27 @@ var audio_eq = (function () {
r.apply = function () { r.apply = function () {
r.draw(); r.draw();
if (!ACtx) if (!actx)
bcfg_set('au_eq', false); bcfg_set('au_eq', false);
if (!ACtx || !mp.au) if (!actx || !mp.au || (!r.en && !mp.acs))
return; return;
if (!r.en && !mp.ac) if (mp.acs) {
return;
if (mp.ac) {
for (var a = 0; a < r.filters.length; a++) for (var a = 0; a < r.filters.length; a++)
r.filters[a].disconnect(); r.filters[a].disconnect();
mp.acs.disconnect();
}
if (!mp.ac || mp.au != r.last_au) {
if (mp.ac)
mp.ac.close();
r.last_au = mp.au;
mp.ac = new ACtx();
mp.acs = mp.ac.createMediaElementSource(mp.au);
}
r.filters = []; r.filters = [];
mp.acs.disconnect();
mp.acs = null;
}
mp.au.id = mp.au.id || Date.now();
mp.acs = r.acst[mp.au.id] = r.acst[mp.au.id] || actx.createMediaElementSource(mp.au);
if (!r.en) { if (!r.en) {
mp.acs.connect(mp.ac.destination); mp.acs.connect(actx.destination);
return; return;
} }
@ -1266,7 +1267,7 @@ var audio_eq = (function () {
gains.unshift(gains[0]); gains.unshift(gains[0]);
for (var a = 0; a < cfg.length; a++) { for (var a = 0; a < cfg.length; a++) {
var fi = mp.ac.createBiquadFilter(); var fi = actx.createBiquadFilter();
fi.frequency.value = cfg[a][0]; fi.frequency.value = cfg[a][0];
fi.gain.value = cfg[a][2] * gains[a]; fi.gain.value = cfg[a][2] * gains[a];
fi.Q.value = cfg[a][1]; fi.Q.value = cfg[a][1];
@ -1275,12 +1276,12 @@ var audio_eq = (function () {
} }
// pregain, keep first in chain // pregain, keep first in chain
fi = mp.ac.createGain(); fi = actx.createGain();
fi.gain.value = r.amp + 0.94; // +.137 dB measured; now -.25 dB and almost bitperfect fi.gain.value = r.amp + 0.94; // +.137 dB measured; now -.25 dB and almost bitperfect
r.filters.push(fi); r.filters.push(fi);
for (var a = r.filters.length - 1; a >= 0; a--) for (var a = r.filters.length - 1; a >= 0; a--)
r.filters[a].connect(a > 0 ? r.filters[a - 1] : mp.ac.destination); r.filters[a].connect(a > 0 ? r.filters[a - 1] : actx.destination);
mp.acs.connect(r.filters[r.filters.length - 1]); mp.acs.connect(r.filters[r.filters.length - 1]);
} }
@ -1396,20 +1397,20 @@ function play(tid, is_ev, seek, call_depth) {
} }
if (tn >= mp.order.length) { if (tn >= mp.order.length) {
if (mpl.pb_mode == 'loop-folder') { if (mpl.pb_mode == 'loop') {
tn = 0; tn = 0;
} }
else if (mpl.pb_mode == 'next-folder') { else if (mpl.pb_mode == 'next') {
treectl.ls_cb = next_song; treectl.ls_cb = next_song;
return tree_neigh(1); return tree_neigh(1);
} }
} }
if (tn < 0) { if (tn < 0) {
if (mpl.pb_mode == 'loop-folder') { if (mpl.pb_mode == 'loop') {
tn = mp.order.length - 1; tn = mp.order.length - 1;
} }
else if (mpl.pb_mode == 'next-folder') { else if (mpl.pb_mode == 'next') {
treectl.ls_cb = prev_song; treectl.ls_cb = prev_song;
return tree_neigh(-1); return tree_neigh(-1);
} }
@ -1424,7 +1425,6 @@ function play(tid, is_ev, seek, call_depth) {
else { else {
mp.au = new Audio(); mp.au = new Audio();
mp.au2 = new Audio(); mp.au2 = new Audio();
mp.dummyctx = new ACtx(); // reduces .play() latency somehow
mp.au.onerror = evau_error; mp.au.onerror = evau_error;
mp.au.onprogress = pbar.drawpos; mp.au.onprogress = pbar.drawpos;
mp.au.onended = next_song; mp.au.onended = next_song;
@ -1436,6 +1436,15 @@ function play(tid, is_ev, seek, call_depth) {
if (mp.au.rsrc == url) if (mp.au.rsrc == url)
mp.au.currentTime = 0; mp.au.currentTime = 0;
else if (mp.au2.rsrc == url) {
var t = mp.au;
mp.au = mp.au2;
mp.au2 = t;
t.onerror = t.onprogress = t.onended = null;
mp.au.onerror = evau_error;
mp.au.onprogress = pbar.drawpos;
mp.au.onended = next_song;
}
else else
mp.au.src = mp.au.rsrc = url; mp.au.src = mp.au.rsrc = url;
@ -4948,6 +4957,7 @@ function reload_mp() {
mpl.unbuffer(); mpl.unbuffer();
mp = new MPlayer(); mp = new MPlayer();
audio_eq.acst = {};
setTimeout(pbar.onresize, 1); setTimeout(pbar.onresize, 1);
} }