ketr.photos/frontend/mvimg.html
James Ketrenos 9a1b001538 Fixed mvimg
Signed-off-by: James Ketrenos <james_gitlab@ketrenos.com>
2019-11-28 03:06:00 -08:00

174 lines
4.6 KiB
HTML

<html>
<script>'<base href="BASEPATH">';</script>
<style>
.static {
display: inline-block;
margin: 1em;
position: relative;
width: 320px;
height: 240px;
background-position: center;
background-size: contain;
background-color: black;
cursor: pointer;
overflow: hidden;
opacity: 0;
}
.static canvas {
display: inline-block;
pointer-events: none;
position: absolute;
top: 0px;
z-index: 0;
}
.video {
border: none;
z-index: 10;
position: relative;
display: inline-block;
opacity: 0;
width: 100%;
height: 100%;
}
.video:hover {
opacity: 1;
}
.video.loading:hover {
opacity: 0.5;
}
</style>
<script src="js/load-image.js"></script>
<script src="js/load-image-scale.js"></script>
<script src="js/load-image-meta.js"></script>
<script src="js/load-image-orientation.js"></script>
<script src="js/load-image-exif.js"></script>
<script src="js/load-image-exif-map.js"></script>
<script>
function createMvElement(url) {
var static = document.createElement("div");
static.classList.add("static");
var video = document.createElement("video");
video.classList.add("video");
video.classList.add("loading");
video.setAttribute("controls", true);
video.setAttribute("loop", true);
video.setAttribute("autoplay", true);
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", url, true);
xmlhttp.responseType = 'arraybuffer';
xmlhttp.onprogress = function (event) {
var alpha = 0;
if (event.total) {
alpha = event.loaded / event.total;
// console.log("Loaded: " + Math.ceil(100 * alpha) + "%");
} else {
// console.log("Loaded: N/A");
alhpa = 0;
}
static.style.opacity = alpha;
};
xmlhttp.onload = function(event) {
static.style.opacity = 1;
var uInt8Array = new Uint8Array(this.response),
i, codes = new Uint8Array(8);
codes.forEach(function(char, index) {
codes[index] = "ftypmp42".charCodeAt(index);
});
/* MP4 starts 4 bytes prior to the ftypmp42 header */
for (i = 4; i < uInt8Array.length - 8; i++) {
if (
(uInt8Array[i + 0] == codes[0]) &&
(uInt8Array[i + 1] == codes[1]) &&
(uInt8Array[i + 2] == codes[2]) &&
(uInt8Array[i + 3] == codes[3]) &&
(uInt8Array[i + 4] == codes[4]) &&
(uInt8Array[i + 5] == codes[5]) &&
(uInt8Array[i + 6] == codes[6]) &&
(uInt8Array[i + 7] == codes[7])
) {
break;
}
}
if (i == uInt8Array.length - 8) {
console.log("No MP4 found.");
i = this.response.byteLength;
} else {
console.log("Found MP4 at: " + i);
i -= 4; /* Go back to the start of the MP4 */
}
/* https://github.com/blueimp/JavaScript-Load-Image */
var imageBlob = new Blob([this.response.slice(0, i)], { type: "image/jpeg" }),
options = {
maxWidth: static.offsetWidth,
maxHeight: static.offsetHeight,
canvas: true,
pixelRatio: window.devicePixelRatio,
downsamplingRatio: 0.5,
meta: true,
contain: true,
orientation: true
};
/* Load the image and center it in our element */
loadImage(imageBlob, function (image, data) {
/*
if (data.exif) {
console.log("Orientation: ", data.exif.get('Orientation'));
}
*/
image.style.left = Math.floor((static.offsetWidth - image.width) * 0.5) + "px";
static.appendChild(image);
}, options);
/* If an MP4 wasn't found, we're done */
if (i == this.response.byteLength) {
return;
}
static.appendChild(video);
/* Set the src= *after* the element has been added to the DOM */
setTimeout(function(buffer) {
/* This can take some time to chunk through... can we spin it into
* a WebWorker or do something to prevent it from janking the UI
* thread? Maybe split it into chunks and do it 100k at a time or
* something? Or queue them up so only one is being processed? */
var base64 = window.btoa(new Uint8Array(buffer).reduce(function (data, byte) {
return data + String.fromCharCode(byte);
}, ''));
video.src = 'data:video/mp4;base64,' + base64;
video.classList.remove("loading");
}.bind(this, this.response.slice(i)), 5000);
};
xmlhttp.send();
return static;
}
document.addEventListener("DOMContentLoaded", function() {
window.fetch("api/v1/photos/mvimg/")
.then(res => res.json())
.then((data) => {
data.items.forEach((movie) => {
document.body.appendChild(createMvElement(movie.path + movie.filename));
});
}).catch((error) => {
console.error(error);
});
});
</script>
<body>
</body>