(function () {
var HLS_CDN = 'https://cdn.jsdelivr.net/npm/[email protected]/dist/hls.min.js';
var hls = null;
function isM3U8(u) {
return typeof u === 'string' && /\.m3u8(\?|#|$)/i.test(u);
}
function ensureHls(cb) {
if (window.Hls) { cb(); return; }
var s = document.createElement('script');
s.src = HLS_CDN;
s.onload = cb;
document.head.appendChild(s);
}
function attachHlsIfNeeded() {
var wrap = document.querySelector('.wplayer');
if (!wrap) return;
var audio = wrap.querySelector('audio');
if (!audio) return;
// исходный src из <source> (до инициализации hls)
var srcEl = audio.querySelector('source');
var src = (srcEl && srcEl.getAttribute('src')) || audio.currentSrc || '';
if (!isM3U8(src)) {
// если предыдущий трек был HLS — подчистим инстанс
if (hls) { try { hls.destroy(); } catch(e){} hls = null; }
return;
}
// Safari / iOS — нативно
if (audio.canPlayType('application/vnd.apple.mpegurl') || audio.canPlayType('application/x-mpegURL')) {
// гарантированно прописываем m3u8 напрямую
audio.src = src;
return;
}
// Chrome/Firefox/Edge — через MSE (hls.js)
ensureHls(function () {
if (!window.Hls || !window.Hls.isSupported()) return;
if (hls) { try { hls.destroy(); } catch(e){} }
hls = new window.Hls({
enableWorker: true,
lowLatencyMode: true,
liveDurationInfinity: true
});
hls.attachMedia(audio);
hls.on(window.Hls.Events.MEDIA_ATTACHED, function () {
hls.loadSource(src);
});
// если клик «Слушать» уже произошёл — гарантируем старт после парсинга манифеста
hls.on(window.Hls.Events.MANIFEST_PARSED, function () {
audio.play().catch(function(){ /* autoplay policies */ });
});
// базовое восстановление при фатальных ошибках сети/медиа
hls.on(window.Hls.Events.ERROR, function (event, data) {
if (!data || !data.fatal) return;
try {
switch (data.type) {
case window.Hls.ErrorTypes.NETWORK_ERROR:
hls.startLoad(); break;
case window.Hls.ErrorTypes.MEDIA_ERROR:
hls.recoverMediaError(); break;
default:
hls.destroy(); hls = null;
}
} catch(e){}
});
});
}
// Оборачиваем вашу apBuilding, чтобы после построения плеера подвесить HLS
function wrapApBuilding() {
if (!window.apBuilding || window.apBuilding.__wrapped) return;
var orig = window.apBuilding;
function patched(a, b, c) {
orig(a, b, c);
// dom уже отрисован .audioPlayer(), можно цепляться
setTimeout(attachHlsIfNeeded, 0);
}
patched.__wrapped = true;
window.apBuilding = patched;
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', wrapApBuilding);
} else {
wrapApBuilding();
}
// Переинициализация при AJAX/SPA событиях (ваши шаблоны их уже триггерят)
['spa:navigate','wajax:after','wajax:load','content:loaded'].forEach(function (ev) {
document.addEventListener(ev, function () { wrapApBuilding(); setTimeout(attachHlsIfNeeded, 0); });
});
})();