App-MHFS

 view release on metacpan or  search on metacpan

share/public_html/static/music_inc/music_inc_module.js  view on Meta::CPAN

                timerdel++;
            }
        }
        if(timerdel)AudioQueue[i].timers.splice(0, timerdel);
        
        // remove if it has passed
        if(AudioQueue[i].endTime <= MainAudioContext.currentTime) {
            console.log('aqid: ' + AudioQueue[i].aqid + ' segment elapsed, removing');
            toDelete++;
        }
    }
    if(toDelete) {
        // if the AQ is empty and there's a current track we fell behind
        if((toDelete === AudioQueue.length) && (Tracks_QueueCurrent)) {
            SetPlayText(Tracks_QueueCurrent.trackname + ' {LOADING}');
        }
        AudioQueue.splice(0, toDelete);
    }
}

//imprecise, in seconds
function AQ_unqueuedTime() { 
    let unqueuedtime = 0;
    for(let i = 0; i < AudioQueue.length; i++) {
        if(!AudioQueue[i].startTime) {
            unqueuedtime += (AudioQueue[i].duration / AudioQueue[i].track.sampleRate);
        }        
    }
    return unqueuedtime;
}

// returns the currently or about to be playing aqid
function AQ_ID() {
    AQ_clean();     
    for(let i = 0; i < AudioQueue.length; i++) {        
        return AudioQueue[i].aqid;                    
    }
    return -1;
}

function AQ_stopAudioWithoutID(aqid) {
    if(!AudioQueue.length) return;
    let dCount = 0;
    for(let i = AudioQueue.length-1; i >= 0; i--) {
        if(AudioQueue[i].aqid === aqid) {
            break;
        }
        dCount++;
        if(AudioQueue[i].source) {
            AudioQueue[i].source.disconnect();
            AudioQueue[i].source.stop();
        }
        console.log('aqid: ' + AudioQueue[i].aqid + ' AQ_stopAudioWithoutID delete, curr: ' + aqid);
    }
    if(dCount) {
        AudioQueue.splice(AudioQueue.length - dCount, dCount);
    }    
}

if(typeof abortablesleep === 'undefined') {
    //const sleep = m => new Promise(r => setTimeout(r, m));
    const abortablesleep = (ms, signal) => new Promise(function(resolve) {
        const onTimerDone = function() {
            resolve();
            signal.removeEventListener('abort', stoptimer);
        };
        let timer = setTimeout(function() {
            console.log('sleep done ' + ms);
            onTimerDone();
        }, ms);

        const stoptimer = function() {
            console.log('aborted sleep');            
            onTimerDone();
            clearTimeout(timer);            
        };
        signal.addEventListener('abort', stoptimer);
    });
    DeclareGlobalFunc('abortablesleep', abortablesleep);
}

let FAQ_MUTEX = new Mutex();
async function fillAudioQueue(time) {
    // starting a fresh queue, render the text
    if(Tracks_QueueCurrent) {
        let track = Tracks_QueueCurrent;
        let prevtext = track.prev ? track.prev.trackname : '';
        SetPrevText(prevtext);
        SetPlayText(track.trackname + ' {LOADING}');
        let nexttext =  track.next ? track.next.trackname : '';
        SetNextText(nexttext);
        SetCurtimeText(time || 0);
        if(!time) SetSeekbarValue(time || 0);
        SetEndtimeText(track.duration || 0);        
    }

    // Stop the previous FAQ before starting
    FACAbortController.abort();
    FACAbortController = new AbortController();
    let mysignal = FACAbortController.signal;
    let unlock = await FAQ_MUTEX.lock();    
    if(mysignal.aborted) {
        console.log('abort after mutex acquire');
        unlock();
        return;
    }
    let initializing = 1;
    
TRACKLOOP:while(1) {
        // advance the track
        AQID++;
        if(!initializing) {
            if(!document.getElementById("repeattrack").checked) {
                Tracks_QueueCurrent = Tracks_QueueCurrent.next;
            }
        }
        initializing = 0;        
        let track = Tracks_QueueCurrent;
        if(! track) {
            unlock();
            return;
        }
        
        // cleanup nwdrflac
        if(NWDRFLAC) {
            // we can reuse it if the urls match
            if(NWDRFLAC.url !== track.url)
            {
                await NWDRFLAC.close();
                NWDRFLAC = null;
                if(mysignal.aborted) {
                    console.log('abort after cleanup');
                    unlock();
                    return;
                }

share/public_html/static/music_inc/music_inc_module.js  view on Meta::CPAN

    if (seconds < 10) { seconds = "0" + seconds; }
    return str + minutes + ':' + seconds;
}

function SetCurtimeText(seconds) {   
    curtimetxt.value = seconds.toHHMMSS();
}

function SetEndtimeText(seconds) {   
    endtimetxt.value = seconds.toHHMMSS();
}

function SetNextText(text) {
    nexttxt.innerHTML = '<span>' + text + '</span>';
}

function SetPrevText(text) {
    prevtxt.innerHTML = '<span>' + text + '</span>';
}

function SetPlayText(text) {
    playtxt.innerHTML = '<span>' + text + '</span>';
}

function SetSeekbarValue(seconds) {
    seekbar.value = seconds;           
}

function SetPPText(text) {
    ppbtn.textContent = text;    
}


function InitPPText() {
    if(MainAudioContext.state === "suspended") {
        ppbtn.textContent = "PLAY";
    }
    else {
        ppbtn.textContent = "PAUSE";
    }        
}

let PTrackUrlParams;
function _BuildPTrack() {
    PTrackUrlParams = new URLSearchParams();
    /*if (MAX_SAMPLE_RATE) PTrackUrlParams.append('max_sample_rate', MAX_SAMPLE_RATE);
    if (BITDEPTH) PTrackUrlParams.append('bitdepth', BITDEPTH);
    if (USESEGMENTS) PTrackUrlParams.append('segments', USESEGMENTS);
    if (USEINCREMENTAL) PTrackUrlParams.append('inc', USEINCREMENTAL);*/
    /*Tracks.forEach(function (track) {
        PTrackUrlParams.append('ptrack', track.trackname);
    });
    */
   for(let track = Tracks_HEAD; track; track = track.next) {
       PTrackUrlParams.append('ptrack', track.trackname);
   }
}

function BuildPTrack() {
    // window.history.replaceState is slow :(
    setTimeout(function() {
    _BuildPTrack();
    var urlstring = PTrackUrlParams.toString();
    if (urlstring != '') {
        console.log('replace state begin');
        window.history.replaceState('playlist', 'Title', '?' + urlstring);
        console.log('replace state end');
    }
    }, 1000);
}


// Main
MainAudioContext = CreateAudioContext({'sampleRate' : 44100 });

// queue the tracks in the url
let orig_ptracks = urlParams.getAll('ptrack');
if (orig_ptracks.length > 0) {
    QueueTracks(orig_ptracks);
}

setInterval(function() {
    MainAudioLoop();
}, 25);
window.requestAnimationFrame(GraphicsLoop);
//QueueTrack("Chuck Person - Chuck Person's Eccojams Vol 1 (2016 WEB) [FLAC]/A1.flac");



( run in 0.612 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )