mirror of
https://github.com/ThaUnknown/miru.git
synced 2026-03-31 03:28:55 +00:00
codec support tables, squeezing every last bit out of canvas rendering
This commit is contained in:
parent
e67032be96
commit
35ab02456d
5 changed files with 291 additions and 86 deletions
|
|
@ -477,9 +477,9 @@ async function btnpip() {
|
|||
|
||||
function renderFrame() {
|
||||
if (running === true) {
|
||||
context.drawImage(video, 0, 0)
|
||||
context.drawImage(subtitleCanvas, 0, 0, canvas.width, canvas.height)
|
||||
window.requestAnimationFrame(renderFrame)
|
||||
context.drawImage(video, 0, 0);
|
||||
context.drawImage(subtitleCanvas, 0, 0, canvas.width, canvas.height);
|
||||
window.requestAnimationFrame(renderFrame);
|
||||
}
|
||||
}
|
||||
canvasVideo.srcObject = canvas.captureStream()
|
||||
|
|
|
|||
|
|
@ -9064,27 +9064,27 @@ self.fastRender = function (force) {
|
|||
self.offscreenRender = function (force) {
|
||||
self.rafId = 0;
|
||||
self.renderPending = false;
|
||||
// var startTime = performance.now();
|
||||
// let startTime = performance.now();
|
||||
let result = self.octObj.renderImage(self.getCurrentTime() + self.delay, self.changed),
|
||||
changed = Module.getValue(self.changed, "i32");
|
||||
if ((changed != 0 || force) && self.offscreenCanvas) {
|
||||
let images = self.buildResultImage(result);
|
||||
// var newTime = performance.now();
|
||||
// var libassTime = newTime - startTime;
|
||||
// let newTime = performance.now(),
|
||||
// libassTime = newTime - startTime;
|
||||
let promises = [];
|
||||
for (var i = 0; i < images.length; i++) {
|
||||
promises[i] = createImageBitmap(images[i].image)
|
||||
}
|
||||
Promise.all(promises).then(function (bitmaps) {
|
||||
// var decodeTime = performance.now() - newTime;
|
||||
// let decodeTime = performance.now() - newTime;
|
||||
function renderFastFrames() {
|
||||
// var beforeDrawTime = performance.now();
|
||||
// let beforeDrawTime = performance.now();
|
||||
self.offscreenCanvasCtx.clearRect(0, 0, self.offscreenCanvas.width, self.offscreenCanvas.height);
|
||||
for (var i = 0; i < bitmaps.length; i++) {
|
||||
self.offscreenCanvasCtx.drawImage(bitmaps[i], images[i].x, images[i].y);
|
||||
// var drawTime = Math.round(performance.now() - beforeDrawTime);
|
||||
// console.log(bitmaps.length + ' bitmaps, libass: ' + Math.round(libassTime) + 'ms, decode: ' + Math.round(decodeTime) + 'ms, draw: ' + drawTime + 'ms');
|
||||
}
|
||||
// let drawTime = performance.now() - beforeDrawTime;
|
||||
// console.log(bitmaps.length + ' bitmaps, libass: ' + libassTime + 'ms, decode: ' + decodeTime + 'ms, draw: ' + drawTime + 'ms');
|
||||
}
|
||||
self.requestAnimationFrame(renderFastFrames);
|
||||
})
|
||||
|
|
@ -9124,15 +9124,14 @@ self.buildResultImageItem = function (ptr) {
|
|||
data = new Uint32Array(buf);
|
||||
let bitmapPosition = 0,
|
||||
resultPosition = 0;
|
||||
for (var y = 0; y < h; ++y) {
|
||||
for (var x = 0; x < w; ++x) {
|
||||
const k = Module.HEAPU8[bitmap + bitmapPosition + x];
|
||||
for (let y = h; y--; bitmapPosition += stride) {
|
||||
const offset = bitmap + bitmapPosition;
|
||||
for (let x = 0, z = w; z--; ++x, resultPosition++) {
|
||||
const k = Module.HEAPU8[offset + x];
|
||||
if (k !== 0) {
|
||||
data[resultPosition] = a * k << 24 | c;
|
||||
}
|
||||
resultPosition++;
|
||||
}
|
||||
bitmapPosition += stride;
|
||||
}
|
||||
const image = new ImageData(buf8, w, h);
|
||||
x = ptr.dst_x;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ const announceList = [
|
|||
// ['ws://tracker.btsync.cf:6969/announce'],
|
||||
// ['ws://hub.bugout.link:80/announce']
|
||||
],
|
||||
videoExtensions = ['.avi', '.mp4', '.m4v', '.webm', '.mov', '.mkv', '.mpg', '.mpeg', '.ogv', '.wmv', '.m2ts'],
|
||||
videoExtensions = [".3g2", ".3gp", ".asf", ".avi", ".dv", ".flv", ".gxf", ".m2ts", ".m4a", ".m4b", ".m4p", ".m4r", ".m4v", ".mkv", ".mov", ".mp4", ".mpd", ".mpeg", ".mpg", ".mxf", ".nut", ".ogm", ".ogv", ".swf", ".ts", ".vob", ".webm", ".wmv", ".wtv"],
|
||||
scope = "/app/",
|
||||
sw = navigator.serviceWorker.register('sw.js', { scope }).then(e => {
|
||||
if (searchParams.get("file")) addTorrent(searchParams.get("file"), {}) // add a torrent if its in the link params
|
||||
|
|
@ -84,6 +84,7 @@ loadOfflineStorage()
|
|||
function cleanupTorrents() {
|
||||
// creates an array of all non-offline store torrents and removes them
|
||||
client.torrents.filter(torrent => !offlineTorrents[torrent.infoHash]).forEach(torrent => torrent.destroy({ destroyStore: true }))
|
||||
document.querySelector(".playlist").innerHTML = ""
|
||||
}
|
||||
|
||||
// manually add trackers
|
||||
|
|
@ -104,10 +105,8 @@ async function playTorrent(torrent, opts) {
|
|||
await sw
|
||||
videoFiles = torrent.files.filter(file => videoExtensions.some(ext => file.name.endsWith(ext)))
|
||||
if (videoFiles.length > 1) {
|
||||
if (!torrent.store.store._idbkvStore) {
|
||||
torrent.files.forEach(file => file.deselect());
|
||||
torrent.deselect(0, torrent.pieces.length - 1, false);
|
||||
}
|
||||
torrent.files.forEach(file => file.deselect());
|
||||
torrent.deselect(0, torrent.pieces.length - 1, false);
|
||||
let frag = document.createDocumentFragment()
|
||||
for (let file of videoFiles) {
|
||||
let mediaInformation = await resolveFileMedia({ fileName: file.name, method: "SearchName" })
|
||||
|
|
@ -153,7 +152,7 @@ function serveFile(file, req) {
|
|||
const res = {
|
||||
status: 200,
|
||||
headers: {
|
||||
'Content-Type': file._getMimeType() || 'video/webm', // lazy workaround for some browsers getting upset about no mime type
|
||||
'Content-Type': file._getMimeType(),
|
||||
// Support range-requests
|
||||
'Accept-Ranges': 'bytes'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,65 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title></title>
|
||||
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
|
||||
<style type="text/css">
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
// Following this idea: https://hacks.mozilla.org/2011/12/faster-canvas-pixel-manipulation-with-typed-arrays/
|
||||
var chartSize = 1000;
|
||||
var dataSize = 1000;
|
||||
|
||||
var dataset = d3.range(dataSize).map(function (d, i) {
|
||||
return d3.range(dataSize).map(function (d, i) {
|
||||
return ~~(Math.random() * 255);
|
||||
});
|
||||
});
|
||||
|
||||
var canvas = d3.select('body')
|
||||
.append('canvas')
|
||||
.style({
|
||||
position: 'absolute',
|
||||
width: chartSize + 'px',
|
||||
height: chartSize + 'px'
|
||||
})
|
||||
.attr({
|
||||
width: dataSize,
|
||||
height: dataSize
|
||||
})
|
||||
.node();
|
||||
|
||||
var canvasWidth = canvas.width;
|
||||
var canvasHeight = canvas.height;
|
||||
var ctx = canvas.getContext('2d');
|
||||
var imageData = ctx.getImageData(0, 0, canvasWidth, canvasHeight);
|
||||
|
||||
var buf = new ArrayBuffer(imageData.data.length);
|
||||
var buf8 = new Uint8ClampedArray(buf);
|
||||
var data = new Uint32Array(buf);
|
||||
for (var y = 0; y < canvasHeight; ++y) {
|
||||
for (var x = 0; x < canvasWidth; ++x) {
|
||||
var value = dataset[y][x];
|
||||
|
||||
console.log(value)
|
||||
data[y * canvasWidth + x] =
|
||||
(255 << 24) | // alpha
|
||||
(value << 16) | // blue
|
||||
(value << 8) | // green
|
||||
value; // red
|
||||
}
|
||||
}
|
||||
|
||||
imageData.data.set(buf8);
|
||||
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
272
support.html
Normal file
272
support.html
Normal file
|
|
@ -0,0 +1,272 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="apple-mobile-web-app-title" content="Miru">
|
||||
<meta name="description" content="Anime torrent streaming, ad free in a simple solution.">
|
||||
<meta name="theme-color" content="#111417" />
|
||||
|
||||
<link rel="apple-touch-icon" href="logo.png">
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
|
||||
<link rel="icon" href="logo.png">
|
||||
<title>Miru - FAQ</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/halfmoon@1.1.0/css/halfmoon-variables.min.css" rel="stylesheet" />
|
||||
</head>
|
||||
|
||||
<body class="dark-mode with-custom-webkit-scrollbars with-custom-css-scrollbars">
|
||||
<div class="page-wrapper">
|
||||
<div class="content-wrapper d-flex flex-column">
|
||||
<a href="/" class="w-200 align-self-center"><img src="logo.png" class="w-200" alt="logo"></a>
|
||||
<div class="container-lg">
|
||||
<table class="table table-striped bg-dark rounded my-5">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Containers</th>
|
||||
<th class="text-center">Chromium</th>
|
||||
<th class="text-center">Mobile Chromium</th>
|
||||
<th class="text-center">Edge Chromium</th>
|
||||
<th class="text-center">Firefox</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>3g2</th>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>3gp</th>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>avi</th>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>m2ts</th>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-secondary text-center">✓**</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>m4v etc.</th>
|
||||
<td class="text-secondary text-center">✓*</td>
|
||||
<td class="text-secondary text-center">✓*</td>
|
||||
<td class="text-secondary text-center">✓*</td>
|
||||
<td class="text-secondary text-center">✓*</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>mp4</th>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>mpeg</th>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>mov</th>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>ogm ogv</th>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>webm</th>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>mkv</th>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
* Container might be supported, but the container's codecs might not be.<br>
|
||||
** Documented as working, but can't reproduce.<br>
|
||||
Full list of all tested video extensions: <br>
|
||||
.3g2 .3gp .asf .avi .dv .flv .gxf .m2ts .m4a .m4b .m4p .m4r .m4v .mkv .mov .mp4 .mpd .mpeg .mpg .mxf
|
||||
.nut .ogm .ogv .swf .ts .vob .webm .wmv .wtv<br>
|
||||
Are any missing?
|
||||
<table class="table table-striped bg-dark rounded mt-15 mb-5">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Video Codecs</th>
|
||||
<th class="text-center">Chromium</th>
|
||||
<th class="text-center">Mobile Chromium</th>
|
||||
<th class="text-center">Edge Chromium</th>
|
||||
<th class="text-center">Firefox</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>AV1</th>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>H.263</th>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>H.264</th>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>H.265</th>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-secondary text-center">✓*</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>MPEG-2/4</th>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Theora</th>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>VP8/9</th>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
* Requires MSStore extension which you can get by clicking <a
|
||||
href="ms-windows-store://pdp/?ProductId=9n4wgh0z6vhq">this link</a> while using Edge.
|
||||
<table class="table table-striped bg-dark rounded mt-15 mb-5">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Audio Codecs</th>
|
||||
<th class="text-center">Chromium</th>
|
||||
<th class="text-center">Mobile Chromium</th>
|
||||
<th class="text-center">Edge Chromium</th>
|
||||
<th class="text-center">Firefox</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>AAC</th>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>AC3</th>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-secondary text-center">✓**</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>DTS</th>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>EAC3</th>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-secondary text-center">✓**</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>FLAC</th>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-secondary text-center">✓*</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>MP3</th>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Opus</th>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>TrueHD</th>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
<td class="text-danger text-center">✘</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Vorbis</th>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-success text-center">✓</td>
|
||||
<td class="text-secondary text-center">✓*</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
* Might not work in some video containers.<br>
|
||||
** Documented as working, but can't reproduce.<br><br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="https://cdn.jsdelivr.net/npm/halfmoon@1.1.0/js/halfmoon.min.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Loading…
Reference in a new issue