/* AUTHOR Trek Hopton LICENSE This file is Copyright (C) 2020 the Australian Ocean Lab (AusOcean) It is free software: you can redistribute it and/or modify them under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License in gpl.txt. If not, see http://www.gnu.org/licenses.. */ import Hls from "./hlsjs/hls.js"; let started = false; let player, viewer; // init gets DOM elements once the document has been loaded and adds listeners where necessary. function init() { document.addEventListener('DOMContentLoaded', load); document.addEventListener('DOMContentLoaded', function () { document.getElementById('urlBtn').addEventListener('click', load); document.getElementById('fileInput').addEventListener('change', play); viewer = document.getElementById('viewer'); } ); } init(); // load gets the URL from the URL input element or the browser's URL bar // and creates an Hls instance to load the content from the URL. function load() { let url = document.getElementById('url').value; if (url == "") { url = getQuery() document.getElementById('url').value = url; } if (url[0] == '/') { url = window.location.protocol + '//' + window.location.host + url; } if (url == "") { return; } let hls = new Hls(); hls.loadSource(url, append); } // getQuery gets everything after the question mark from the URL in the browser's URL bar. function getQuery() { let regex = new RegExp("\\?(.*)"); let match = regex.exec(window.location.href); if (match == null) { return ''; } else { return decodeURIComponent(match[1].replace(/\+/g, " ")); } } // append, on the first call, starts a player worker and passes it a frame rate and the video data, // on subsequent calls it passes the video data to the player worker. function append(data) { if (!started) { player = new Worker("player.js"); let rate = document.getElementById('rate'); if (rate.value && rate.value > 0) { player.postMessage({ msg: "setFrameRate", data: rate.value }); } player.onmessage = handleMessage; player.postMessage({ msg: "loadMtsMjpeg", data: data }, [data]); started = true; } else { player.postMessage({ msg: "appendMtsMjpeg", data: data }, [data]); } } // play will process and play the target file chosen with the file input element. function play() { const input = event.target.files[0]; const reader = new FileReader(); reader.onload = event => { const player = new Worker("player.js"); let rate = document.getElementById('rate'); if (rate.value && rate.value > 0) { player.postMessage({ msg: "setFrameRate", data: rate.value }); } player.onmessage = handleMessage; switch (input.name.split('.')[1]) { case "mjpeg": case "mjpg": player.postMessage({ msg: "loadMjpeg", data: event.target.result }, [event.target.result]); break; case "ts": player.postMessage({ msg: "loadMtsMjpeg", data: event.target.result }, [event.target.result]); break; default: console.error("unknown file format"); break; } }; reader.onerror = error => reject(error); reader.readAsArrayBuffer(input); } // handleMessage handles messgaes from the player workers, its main job is to update the display when a frame is received. function handleMessage(e) { switch (e.data.msg) { case "frame": const blob = new Blob([new Uint8Array(e.data.data)], { type: 'video/x-motion-jpeg' }); const url = URL.createObjectURL(blob); viewer.src = url; break; case "log": console.log(e.data.data); break; case "stop": console.log("stopped"); break; default: console.error("unknown message from player"); break; } }