{"version":"1.0.1","templatekey":"pw-onceaudio","name":"Player - Once Audio","instructions":"<p>An HTML5 audio player that will only play the audio file it manages once.  Insert an audio player or audio link between the tags.</p>","content":"<div id='{{AUTOID}}_container' class=\"poodll_onceplayer my-3\">\n  <audio id='{{AUTOID}}_player' class=\"nomediaplugin\"></audio>\n  <div class='d-flex flex-wrap align-items-center gap-2 bg-dark text-white px-2 py-1 rounded shadow-sm'>\n    <button type='button' id='{{AUTOID}}' class='btn btn-dark px-2'\n            aria-label=\"{{#str}} play, filter_genericotwo {{/str}}\">\n      <i class=\"fa {{play}} fa-lg\" aria-hidden=\"true\"></i>\n    </button>\n    <div class=\"lh-sm\">\n      <div id='{{AUTOID}}_time' class='small font-monospace'></div>\n      <div id='{{AUTOID}}_state' class=\"small text-white-50\"></div>\n    </div>\n    <div class=\"d-flex align-items-center gap-1 ms-auto\">\n      <button type=\"button\" id=\"{{AUTOID}}_vol-down\" class=\"btn btn-dark btn-sm px-1\"\n              aria-label=\"{{#str}} volumedown, filter_genericotwo {{/str}}\">\n        <i class=\"fa fa-volume-down\" aria-hidden=\"true\"></i>\n      </button>\n      <div class=\"progress\">\n        <div id=\"{{AUTOID}}_indicator\" class=\"progress-bar\"></div>\n      </div>\n      <button type=\"button\" id=\"{{AUTOID}}_vol-up\" class=\"btn btn-dark btn-sm px-1\"\n              aria-label=\"{{#str}} volumeup, filter_genericotwo {{/str}}\">\n        <i class=\"fa fa-volume-up\" aria-hidden=\"true\"></i>\n      </button>\n    </div>\n  </div>\n</div>\n<div id=\"{{AUTOID}}_original\" class=\"poodllplayerwidgetnoshow\" style=\"display: none\">\n{{canpause}}\n{{volume}}\n","templateend":"</div>","variabledefaults":"canpause=0,play=fa-play,playing=fa-circle-o-notch,over=fa-minus,volume=0.4|0.5|0.6|0.7|0.8|0.9","jscontent":"require(['filter_genericotwo/mediaparser'], (parser) => {\n\n    const playButton = document.getElementById('{{AUTOID}}');\n    const icon = playButton.querySelector('.fa');\n    const player = document.getElementById('{{AUTOID}}_player');\n    const timeDisplay = document.getElementById('{{AUTOID}}_time');\n    const stateDisplay = document.getElementById('{{AUTOID}}_state');\n    const indicator = document.getElementById('{{AUTOID}}_indicator');\n    const canPause = '{{canpause}}' !== '0';\n\n    const secondsToTime = (seconds) => {\n        if (!Number.isFinite(seconds)) {\n            return '00:00:00';\n        }\n        const date = new Date(0);\n        date.setSeconds(seconds);\n        return date.toISOString().substring(11, 19);\n    };\n\n    const fetchTimeDisplay = () => {\n        const currentTime = isNaN(player.currentTime) ? 0 : player.currentTime;\n        const duration = isNaN(player.duration) ? 0 : player.duration;\n        return secondsToTime(Math.floor(currentTime)) + ' / ' + secondsToTime(Math.floor(duration));\n    };\n\n    const setPlayerVolume = (newVolume) => {\n        player.volume = newVolume;\n        indicator.style.width = (player.volume * 100) + '%';\n    };\n\n    // Fetch the media url.\n    const details = parser.parse('{{AUTOID}}_original', 'audio');\n    player.src = details.mediaurl;\n\n    // Set the base volume: the {{volume}} variable if valid, otherwise 0.4.\n    const baseVolume = Number('{{volume}}');\n    if ('{{volume}}' !== '' && Number.isFinite(baseVolume) && baseVolume >= 0 && baseVolume <= 1) {\n        setPlayerVolume(baseVolume);\n    } else {\n        setPlayerVolume(0.4);\n    }\n\n    stateDisplay.textContent = '{{#str}} ready, filter_genericotwo {{/str}}';\n    timeDisplay.textContent = fetchTimeDisplay();\n\n    // Volume buttons.\n    document.getElementById('{{AUTOID}}_vol-up').addEventListener('click', () => {\n        if (player.volume + 0.1 > 1) {\n            return;\n        }\n        setPlayerVolume(player.volume + 0.1);\n    });\n    document.getElementById('{{AUTOID}}_vol-down').addEventListener('click', () => {\n        if (player.volume - 0.1 < 0) {\n            return;\n        }\n        setPlayerVolume(player.volume - 0.1);\n    });\n\n    player.addEventListener('timeupdate', () => {\n        timeDisplay.textContent = fetchTimeDisplay();\n    });\n\n    player.addEventListener('durationchange', () => {\n        timeDisplay.textContent = fetchTimeDisplay();\n    });\n\n    player.addEventListener('ended', () => {\n        player.pause();\n        icon.classList.remove('{{playing}}', 'fa-spin', '{{play}}');\n        icon.classList.add('{{over}}');\n        stateDisplay.textContent = '{{#str}} finished, filter_genericotwo {{/str}}';\n        playButton.disabled = true;\n    });\n\n    playButton.addEventListener('click', () => {\n        if (player.ended) {\n            return;\n        }\n        if (!player.paused && canPause) {\n            player.pause();\n            stateDisplay.textContent = '{{#str}} paused, filter_genericotwo {{/str}}';\n            icon.classList.remove('{{playing}}', 'fa-spin');\n            icon.classList.add('{{play}}');\n        } else if (player.paused) {\n            player.play();\n            stateDisplay.textContent = '{{#str}} playing, filter_genericotwo {{/str}}';\n            icon.classList.remove('{{play}}');\n            icon.classList.add('{{playing}}', 'fa-spin');\n        }\n    });\n});\n","importcss":"","customcss":".poodll_onceplayer {\n    max-width: 400px;\n}\n.poodll_onceplayer .progress {\n    width: 5rem;\n    height: 0.5rem;\n}\n","dataset":"","datasetvars":"","allowedcontexts":"","allowedcontextids":""}