App-MHFS

 view release on metacpan or  search on metacpan

share/public_html/static/music_worklet_inprogress/player/mhfsplayer.js  view on Meta::CPAN

        if(! that.ByHash[pichash]) {
            that.ByHash[pichash] = [];
        }
        else {
            for(const elm of that.ByHash[pichash]) {
                if((elm.size === picture.picsize) && (elm.mime === picture.mime)) {
                    return elm.url;
                }
            }
        }
        const picurl = picture.toURL();
        console.log('loaded picture at ' + picurl);
        that.ByHash[pichash].push({
            size : picture.picsize,
            mime : picture.mime,
            url  : picurl
        });
        return picurl;
    };
    return that;
};

const FolderMap = function() {
    const that = {};
    that.ByFolder = {};

    const LookupFolder = function(trackname) {
        const lastSlash = trackname.lastIndexOf('/');
        return (lastSlash !== -1) ? trackname.substring(0, lastSlash) : '';
    };

    that.AddArtIfNotExists = function(trackname, url) {
        const foldername = LookupFolder(trackname);
        if(!foldername || that.ByFolder[foldername]) return;

        that.ByFolder[foldername] = url;
    };

    that.GetArt = function(trackname) {
        const foldername = LookupFolder(trackname);
        if(! foldername) return undefined;
        return that.ByFolder[foldername];
    };

    return that;
};

const MHFSPlayer = async function(opt) {
    let that = {};
    that.gui = opt.gui;

    that.artDB = ArtDB();
    that.trackdb = {};
    that.guiarturl = {};
    that.foldermap = FolderMap();

    const cdimage = new Blob ([CDIMAGE], { type: 'image/svg+xml' });
    that.cdimage = URL.createObjectURL(cdimage);

    const SetTrackArt = function(track, url) {
        // update the foldermap so we can guess the art for other tracks in the folder / album
        that.foldermap.AddArtIfNotExists(track.md.trackname, url);
        // set this as definite art for trackname
        track.md.artbloburl = url;
        // gui needs to reload track art urls
        that.gui.UpdateTrackImage(track);
    };

    const LoadTrackArt = function(track, dectrack) {
        if(! track.md.artbloburl) {
            let urlToSet;
            // first try loading the art directly from the file
            const embeddedart = dectrack._openPictureIfExists();
            if(embeddedart) {
                urlToSet = that.artDB.addPictureIfNotExists(embeddedart);
            }
            else {
                // try using the gui's art locater. We cache it all as blobs to avoid lookups
                const url = that.gui.getarturl(track.md.trackname);
                if(!that.guiarturl[url]) {
                    (async function() {
                        const fetchResponse = await fetch(url);
                        if(!fetchResponse.ok) return;
                        const blobert = await fetchResponse.blob();
                        that.guiarturl[url] = URL.createObjectURL(blobert);
                        SetTrackArt(track, that.guiarturl[url]);
                    })();
                    return;
                }
                urlToSet = that.guiarturl[url];
            }
            SetTrackArt(track, urlToSet);
        }
    };


    that.sampleRate = opt.sampleRate;
    that.channels   = opt.channels;
    that.pborder = "pborder_default";
    that.maxdecodetime = opt.maxdecodetime;

    that._createaudiocontext = function(options) {
        let mycontext = (window.hasWebKit) ? new webkitAudioContext(options) : (typeof AudioContext != "undefined") ? new AudioContext(options) : null;        
        return mycontext;
    };
    // create AC
    that.ac = that._createaudiocontext({'sampleRate' : opt.sampleRate, 'latencyHint' : 0.1});
    that.ac.suspend(); // save power start suspended
    that.lastACState = that.ac.state;
    that.ac.onstatechange = function() {
        console.log('changing acstate was ' + that.lastACState + ' now ' + that.ac.state);
        that.lastACState = that.ac.state;
        that.gui.onACStateUpdate(that.lastACState);
    };

    // connect GainNode  
    that.GainNode = that.ac.createGain();
    that.GainNode.connect(that.ac.destination);
    // create ring buffers
    that.ARBLen  = that.ac.sampleRate * 2;
    if (!self.SharedArrayBuffer) {



( run in 1.068 second using v1.01-cache-2.11-cpan-5837b0d9d2c )