vers. 2.3.0
This commit is contained in:
1 parent
ae5a4a8153
commit
2b0b457166
9 files changed
+137
-47
No files matched your search
@@ -340,12 +340,14 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
*/
|
||||
|
||||
function initializePlayer() {
|
||||
console.log('Inizializzazione player audio (v2.0 - Hybrid Strategy)...');
|
||||
console.log('Inizializzazione player audio (v2.1 - Format Toggle)...');
|
||||
|
||||
const playPauseBtn = document.getElementById('playPauseBtn');
|
||||
const playIcon = document.querySelector('.play-icon');
|
||||
const pauseIcon = document.querySelector('.pause-icon');
|
||||
const playerStatus = document.getElementById('playerStatus');
|
||||
const formatToggleBtn = document.getElementById('formatToggleBtn');
|
||||
const formatLabel = document.getElementById('formatLabel');
|
||||
|
||||
if (!playPauseBtn) return;
|
||||
|
||||
@@ -360,8 +362,19 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
const streamFallback = playPauseBtn.getAttribute('data-stream-fallback');
|
||||
const stationName = playPauseBtn.getAttribute('data-station-name');
|
||||
|
||||
// Stato formato audio (preferenza salvata in localStorage)
|
||||
const storageKey = 'audioFormat_' + stationName;
|
||||
let currentFormat = localStorage.getItem(storageKey) || 'hls'; // 'hls' o 'direct'
|
||||
let isPlaying = false;
|
||||
|
||||
// Aggiorna label del formato
|
||||
function updateFormatLabel() {
|
||||
if (formatLabel) {
|
||||
formatLabel.textContent = currentFormat === 'hls' ? 'HLS' : 'MP3';
|
||||
}
|
||||
}
|
||||
updateFormatLabel();
|
||||
|
||||
// Configurazione HLS.js Ottimizzata per Qualità
|
||||
const hlsConfig = {
|
||||
debug: false,
|
||||
@@ -379,7 +392,16 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
* Logica di Selezione Player
|
||||
* Priorità: HLS.js (PC/Android) > Nativo (iOS) > Fallback (Direct Stream)
|
||||
*/
|
||||
function initStream() {
|
||||
function initStream(forceFormat = null) {
|
||||
const preferredFormat = forceFormat || currentFormat;
|
||||
|
||||
// Se l'utente ha scelto formato diretto, usa subito MP3/AAC
|
||||
if (preferredFormat === 'direct') {
|
||||
console.log('User preference: Direct stream (MP3/AAC)');
|
||||
useDirectStream();
|
||||
return;
|
||||
}
|
||||
|
||||
// STRATEGIA 1: HLS.js (Preferita per PC e Android)
|
||||
if (Hls.isSupported()) {
|
||||
console.log('Strategy: HLS.js (High Quality Control)');
|
||||
@@ -427,7 +449,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
hlsInstance.recoverMediaError();
|
||||
break;
|
||||
default:
|
||||
fallbackToDirectStream();
|
||||
useDirectStream();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -449,18 +471,54 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
|
||||
// STRATEGIA 3: Fallback (Stream MP3 diretto)
|
||||
console.log('Strategy: Direct Fallback');
|
||||
fallbackToDirectStream();
|
||||
useDirectStream();
|
||||
}
|
||||
|
||||
function fallbackToDirectStream() {
|
||||
function useDirectStream() {
|
||||
if (hlsInstance) {
|
||||
hlsInstance.destroy();
|
||||
hlsInstance = null;
|
||||
}
|
||||
console.log('Using direct stream:', streamFallback);
|
||||
audioPlayer.src = streamFallback;
|
||||
attemptPlay();
|
||||
}
|
||||
|
||||
// Funzione per cambiare formato
|
||||
function toggleFormat() {
|
||||
const wasPlaying = !audioPlayer.paused;
|
||||
|
||||
// Cambia formato
|
||||
currentFormat = currentFormat === 'hls' ? 'direct' : 'hls';
|
||||
localStorage.setItem(storageKey, currentFormat);
|
||||
console.log('Switching to format:', currentFormat);
|
||||
|
||||
// Aggiorna label
|
||||
updateFormatLabel();
|
||||
|
||||
// Ferma riproduzione corrente
|
||||
if (audioPlayer) {
|
||||
audioPlayer.pause();
|
||||
}
|
||||
|
||||
// Pulisci player precedente
|
||||
if (hlsInstance) {
|
||||
hlsInstance.destroy();
|
||||
hlsInstance = null;
|
||||
}
|
||||
audioPlayer.src = '';
|
||||
|
||||
// Reinizializza con nuovo formato
|
||||
initStream(currentFormat);
|
||||
|
||||
// Riprendi riproduzione se era in corso
|
||||
if (wasPlaying) {
|
||||
setTimeout(() => {
|
||||
togglePlay();
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
||||
function attemptPlay() {
|
||||
// Nota: chiamare .play() senza interazione utente fallirà.
|
||||
// Questa funzione prepara lo stato. Il vero play avviene al click.
|
||||
@@ -519,10 +577,18 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
updateUI(false);
|
||||
};
|
||||
|
||||
// Format toggle button listener
|
||||
if (formatToggleBtn) {
|
||||
formatToggleBtn.onclick = (e) => {
|
||||
e.preventDefault();
|
||||
toggleFormat();
|
||||
};
|
||||
}
|
||||
|
||||
// Setup Media Session
|
||||
setupMediaSession(stationName, playPauseBtn.getAttribute('data-station-slogan'), playPauseBtn.getAttribute('data-station-logo'), playIcon, pauseIcon);
|
||||
|
||||
console.log('Player System Ready.');
|
||||
console.log('Player System Ready with format toggle.');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -705,7 +771,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
* Setup modalità standalone (PWA)
|
||||
*/
|
||||
function setupStandaloneMode() {
|
||||
const appContainer = document.querySelector('.container');
|
||||
const appContainer = document.querySelector('.container') || document.querySelector('.container-fluid');
|
||||
if (!appContainer) return;
|
||||
|
||||
if (window.opener && !window.opener.closed) {
|
||||
@@ -748,7 +814,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
|
||||
setupOpenAppButton();
|
||||
|
||||
if (document.querySelector('.container')) {
|
||||
if (document.querySelector('.container') || document.querySelector('.container-fluid')) {
|
||||
setupStandaloneMode();
|
||||
attachLinkListeners();
|
||||
setupHistoryNavigation();
|
||||
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
/*!
|
||||
* Bootstrap v5.1.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t="transitionend",e=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?i.trim():null}return e},i=t=>{const i=e(t);return i&&document.querySelector(i)?i:null},n=t=>{const i=e(t);return i?document.querySelector(i):null},s=e=>{e.dispatchEvent(new Event(t))},o=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),r=t=>o(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(t):null,a=(t,e,i)=>{Object.keys(i).forEach((n=>{const s=i[n],r=e[n],a=r&&o(r)?"element":null==(l=r)?`${l}`:{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase();var l;if(!new RegExp(s).test(a))throw new TypeError(`${t.toUpperCase()}: Option "${n}" provided type "${a}" but expected type "${s}".`)}))},l=t=>!(!o(t)||0===t.getClientRects().length)&&"visible"===getComputedStyle(t).getPropertyValue("visibility"),c=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),h=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?h(t.parentNode):null},d=()=>{},u=t=>{t.offsetHeight},f=()=>{const{jQuery:t}=window;return t&&!document.body.hasAttribute("data-bs-no-jquery")?t:null},p=[],m=()=>"rtl"===document.documentElement.dir,g=t=>{var e;e=()=>{const e=f();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(p.length||document.addEventListener("DOMContentLoaded",(()=>{p.forEach((t=>t()))})),p.push(e)):e()},_=t=>{"function"==typeof t&&t()},b=(e,i,n=!0)=>{if(!n)return void _(e);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(i)+5;let r=!1;const a=({target:n})=>{n===i&&(r=!0,i.removeEventListener(t,a),_(e))};i.addEventListener(t,a),setTimeout((()=>{r||s(i)}),o)},v=(t,e,i,n)=>{let s=t.indexOf(e);if(-1===s)return t[!i&&n?t.length-1:0];const o=t.length;return s+=i?1:-1,n&&(s=(s+o)%o),t[Math.max(0,Math.min(s,o-1))]},y=/[^.]*(?=\..*)\.|.*/,w=/\..*/,E=/::\d+$/,A={};let T=1;const O={mouseenter:"mouseover",mouseleave:"mouseout"},C=/^(mouseenter|mouseleave)/i,k=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function L(t,e){return e&&`${e}::${T++}`||t.uidEvent||T++}function x(t){const e=L(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function D(t,e,i=null){const n=Object.keys(t);for(let s=0,o=n.length;s<o;s++){const o=t[n[s]];if(o.originalHandler===e&&o.delegationSelector===i)return o}return null}function S(t,e,i){const n="string"==typeof e,s=n?i:e;let o=P(t);return k.has(o)||(o=t),[n,s,o]}function N(t,e,i,n,s){if("string"!=typeof e||!t)return;if(i||(i=n,n=null),C.test(e)){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};n?n=t(n):i=t(i)}const[o,r,a]=S(e,i,n),l=x(t),c=l[a]||(l[a]={}),h=D(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=L(r,e.replace(y,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(let a=o.length;a--;)if(o[a]===r)return s.delegateTarget=r,n.oneOff&&j.off(t,s.type,e,i),i.apply(r,[s]);return null}}(t,i,n):function(t,e){return function i(n){return n.delegateTarget=t,i.oneOff&&j.off(t,n.type,e),e.apply(t,[n])}}(t,i);u.delegationSelector=o?i:null,u.originalHandler=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function I(t,e,i,n,s){const o=D(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function P(t){return t=t.replace(w,""),O[t]||t}const j={on(t,e,i,n){N(t,e,i,n,!1)},one(t,e,i,n){N(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=S(e,i,n),a=r!==e,l=x(t),c=e.startsWith(".");if(void 0!==o){if(!Line truncated
|
||||
//# sourceMappingURL=bootstrap.bundle.min.js.map
|
||||
Reference in new issue
Block a user