Lastest releases doesnt re-build if the feed hasnt changed, subtitle renderer now uses embedded fonts, only create missing thumbnails, hardsubbed PiP, minor fixes

This commit is contained in:
ThaUnknown 2020-10-26 20:22:14 +01:00
parent 5d644589ad
commit 8d9edc8c99
7 changed files with 134 additions and 51 deletions

View file

@ -58,6 +58,9 @@
#player:target .player {
display: flex !important
}
#player.pip{
background: #000
}
.controls {
background: linear-gradient(to top, rgba(0, 0, 0, .8), rgba(0, 0, 0, .4) 25%, rgba(0, 0, 0, .2) 50%, rgba(0, 0, 0, .1) 75%, transparent);
@ -212,8 +215,10 @@
#player:fullscreen #btheatre,
#player:target>a,
#progress+img[src=" "],
video[src=""] {
display: none
video[src=""],
#player.pip video,
#player.pip canvas {
display: none !important
}
video::cue {

View file

@ -304,11 +304,17 @@
<option value="Roboto,Arial,Helvetica,sans-serif">Roboto</option>
</select>
</div>
<div class="custom-switch mb-20">
<div class="custom-switch mb-10">
<input type="checkbox" id="subtitle2">
<label for="subtitle2">Async Rendering [Might cause desync on low end devices but greatly
improves performance]</label>
</div>
<div class="custom-switch mb-20">
<input type="checkbox" id="subtitle3">
<label for="subtitle3">Video Canvas Merging [Displays subtitles in PiP and ChromeCast, requires
<a href="chrome://flags/#disable-accelerated-2d-canvas"
target="_blank">chrome://flags/#disable-accelerated-2d-canvas</a> set to Disabled]</label>
</div>
<h1 class="content-title font-size-22">
@ -360,7 +366,7 @@
<script src="https://cdn.jsdelivr.net/npm/webtorrent@latest/webtorrent.min.js"></script>
<script src="js/rangeParser.js"></script>
<script src="js/torrentHandler.js"></script>
<script src="https://cdn.jsdelivr.net/npm/matroska-subtitles@3.1.0/dist/matroska-subtitles.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/matroska-subtitles@3.2.0/dist/matroska-subtitles.min.js"></script>
<script src="js/subtitles-octopus.js"></script>
<script src="js/subtitleOctopus.js"></script>
</body>

View file

@ -319,41 +319,45 @@ async function nyaaRss(url) {
const regex = /((?:\[[^\]]*\])*)?\s*((?:[^\d\[\.](?!S\d))*)?\s*((?:S\d+[^\w\[]*E?)?[\d\-]*)\s*(.*)?/i,
eregex = /(\[.*\]\ ?)?(.+?(?=\ \\ \d))?(\ \\ )?(\d+)?/i,
plsregex = /(\[.[^\]]*\]\ ?)?(.+?(?=\ \-\ \d))?(\ \-\ )?(\d+)?(.*)?/i
let store = {};
let store = {},
lastResult
async function hsRss() {
if (document.location.href.endsWith("#releases")) {
let frag = document.createDocumentFragment(),
releases = document.querySelector(".releases"),
url = settings.torrent4 == "https://miru.kirdow.com/request/?url=https://www.erai-raws.info/rss-" ? settings.torrent4 + settings.torrent1 + "-magnet" : settings.torrent4 + settings.torrent1
releases.textContent = '';
releases.appendChild(skeletonCard)
res = await fetch(url)
await res.text().then(async (xmlTxt) => {
try {
let doc = DOMPARSER(xmlTxt, "text/xml")
let items = doc.querySelectorAll("item")
for (let item of items) {
let i = item.querySelector.bind(item),
regexParse = plsregex.exec(i("title").textContent)
if (!store.hasOwnProperty(regexParse[2]) && !alResponse.data.Page.media.some(media => (Object.values(media.title).concat(media.synonyms).filter(name => name != null).includes(regexParse[2]) && ((store[regexParse[2]] = media) && true)))) {
//shit not found, lookup
let res = await alRequest(regexParse[2], 1)
if (!res.data.Page.media[0]) {
res = await alRequest(regexParse[2].replace(" (TV)", "").replace(` (${new Date().getFullYear()})`, ""), 1)
if (lastResult != doc) {
releases.textContent = '';
releases.appendChild(skeletonCard)
lastResult = doc
let items = doc.querySelectorAll("item")
for (let item of items) {
let i = item.querySelector.bind(item),
regexParse = plsregex.exec(i("title").textContent)
if (!store.hasOwnProperty(regexParse[2]) && !alResponse.data.Page.media.some(media => (Object.values(media.title).concat(media.synonyms).filter(name => name != null).includes(regexParse[2]) && ((store[regexParse[2]] = media) && true)))) {
//shit not found, lookup
let res = await alRequest(regexParse[2], 1)
if (!res.data.Page.media[0]) {
res = await alRequest(regexParse[2].replace(" (TV)", "").replace(` (${new Date().getFullYear()})`, ""), 1)
}
store[regexParse[2]] = res.data.Page.media[0]
}
store[regexParse[2]] = res.data.Page.media[0]
let media = store[regexParse[2]],
template = cardCreator(media, regexParse)
template.onclick = () => {
playerData.selected = [regexParse[2], regexParse[4]]
addTorrent(i('link').textContent)
}
frag.appendChild(template)
}
let media = store[regexParse[2]],
template = cardCreator(media, regexParse)
template.onclick = () => {
playerData.selected = [regexParse[2], regexParse[4]]
addTorrent(i('link').textContent)
}
frag.appendChild(template)
releases.textContent = '';
releases.appendChild(frag)
}
releases.textContent = '';
releases.appendChild(frag)
} catch (e) {
console.error(e)
}

View file

@ -24,6 +24,9 @@ let playerData = {
function resetVideo() {
!!playerData.octopusInstance ? playerData.octopusInstance.dispose() : ""
!!playerData.fonts ? playerData.fonts.forEach(file => {
URL.revokeObjectURL(file)
}) : ""
playerData = {
tracks: [],
headers: undefined,
@ -31,6 +34,7 @@ function resetVideo() {
subtitles: [],
subtitleStream: undefined,
octopusInstance: undefined,
fonts: [],
nowPlaying: undefined,
selected: undefined,
thumbnails: []
@ -132,7 +136,8 @@ function createThumbnail(vid) {
function finishThumbnails(url) {
if (settings.player5 && settings.player8) {
let thumbVid = document.createElement("video")
let thumbVid = document.createElement("video"),
index = 0
thumbVid.src = url
thumbVid.addEventListener('loadeddata', () => {
@ -145,11 +150,15 @@ function finishThumbnails(url) {
})
function loadTime() {
while (playerData.thumbnails[index] && index <= Math.floor(thumbVid.duration / 5)) {
index++
}
if (thumbVid.currentTime != thumbVid.duration) {
thumbVid.currentTime = thumbVid.currentTime + 5;
thumbVid.currentTime = index * 5
} else {
thumbVid.remove()
}
index++
}
}
}
@ -276,7 +285,53 @@ updateVolume(parseInt(settings.player1))
// PiP
async function btnpip() {
video !== document.pictureInPictureElement ? await video.requestPictureInPicture() : await document.exitPictureInPicture();
if (!playerData.octopusInstance) {
video !== document.pictureInPictureElement ? await video.requestPictureInPicture() : await document.exitPictureInPicture();
} else {
if (document.pictureInPictureElement) {
await document.exitPictureInPicture()
} else {
let canvas = document.createElement("canvas"),
subtitleCanvas = document.querySelector(".libassjs-canvas"),
canvasVideo = document.createElement("video"),
context = canvas.getContext("2d", { alpha: false }),
running = true
canvas.width = subtitleCanvas.width
canvas.height = subtitleCanvas.height
player.classList.add("pip")
function renderFrame() {
if (running) {
context.drawImage(video, 0, 0, canvas.width, canvas.height)
context.drawImage(subtitleCanvas, 0, 0)
window.requestAnimationFrame(renderFrame)
}
}
window.requestAnimationFrame(renderFrame)
canvasVideo.srcObject = canvas.captureStream()
canvasVideo.onloadeddata = async function () {
canvasVideo.play()
await canvasVideo.requestPictureInPicture()
}
canvasVideo.onleavepictureinpicture = () => {
running = false
canvasVideo.remove()
canvas.remove()
player.classList.remove("pip")
}
}
}
}
function hardSub() {
let c1 = document.createElement("canvas"),
sub = document.querySelector(".libassjs-canvas")
c1.width = sub.width
c1.height = sub.height
let ctx1 = c1.getContext("2d")
ctx1.drawImage(video, 0, 0, c1.width, c1.height)
ctx1.drawImage(sub, 0, 0)
console.log(c1.toDataURL("image/jpeg"))
}
//miniplayer
@ -422,7 +477,7 @@ function selPlaying(sel) {
}
function updatePositionState() {
if ('setPositionState' in navigator.mediaSession) {
if ('setPositionState' in navigator.mediaSession && video.duration) {
navigator.mediaSession.setPositionState({
duration: video.duration || 0,
playbackRate: video.playbackRate || 0,

View file

@ -9,6 +9,7 @@ const settingsElements = {
player8: player8,
subtitle1: subtitle1,
subtitle2: subtitle2,
subtitle3: subtitle3,
torrent1: torrent1,
torrent2: torrent2,
torrent3: torrent3,
@ -28,6 +29,7 @@ function restoreDefaults() {
player8: true,
subtitle1: "'Open Sans', sans-serif",
subtitle2: true,
subtitle3: true,
torrent1: "1080",
torrent2: false,
torrent3: true,

View file

@ -27,7 +27,7 @@ function subStream(stream) {
}
})
}
playerData.subtitleStream.on('subtitle', function (subtitle, trackNumber) {
playerData.subtitleStream.on('subtitle', (subtitle, trackNumber) => {
if (playerData.headers) {
let formatSub = "Dialogue: " + subtitle.layer + "," + new Date(subtitle.time).toISOString().slice(12, -1).slice(0, -1) + "," + new Date(subtitle.time + subtitle.duration).toISOString().slice(12, -1).slice(0, -1) + "," + subtitle.style + "," + subtitle.name + "," + subtitle.marginL + "," + subtitle.marginR + "," + subtitle.marginV + "," + subtitle.effect + "," + subtitle.text
if (!playerData.subtitles[trackNumber].includes(formatSub)) {
@ -41,6 +41,9 @@ function subStream(stream) {
}
}
})
playerData.subtitleStream.on('file', file => {
file.mimetype == ("application/x-truetype-font" || "application/font-woff") ? playerData.fonts.push(window.URL.createObjectURL(new Blob([file.data],{type: file.mimetype}))) : ""
})
stream.pipe(playerData.subtitleStream)
}
}
@ -51,7 +54,7 @@ function renderSubs(trackNumber) {
video: video,
subContent: trackContent,
lossyRender: settings.subtitle2,
fonts: ["https://fonts.gstatic.com/s/roboto/v20/KFOlCnqEu92Fr1MmEU9fBBc4.woff2"],
fonts: playerData.fonts.length == 0 ? ["https://fonts.gstatic.com/s/roboto/v20/KFOlCnqEu92Fr1MmEU9fBBc4.woff2"] : playerData.fonts,
workerUrl: 'js/subtitles-octopus-worker.js'
};
playerData.octopusInstance = new SubtitlesOctopus(options);

View file

@ -99,31 +99,39 @@ async function addTorrent(magnet) {
}
function postDownload(url, file) {
if (settings.player8) {
let parser = new SubtitleParser(),
subtitles = []
parser.once('tracks', pTracks => {
pTracks.forEach(track => {
subtitles[track.number] = []
if (playerData.subtitleStream) {
let parser = new SubtitleParser(),
subtitles = []
parser.once('tracks', pTracks => {
pTracks.forEach(track => {
subtitles[track.number] = []
})
})
})
parser.on('subtitle', function (subtitle, trackNumber) {
if (playerData.headers) {
subtitles[trackNumber].push("Dialogue: " + subtitle.layer + "," + new Date(subtitle.time).toISOString().slice(12, -1).slice(0, -1) + "," + new Date(subtitle.time + subtitle.duration).toISOString().slice(12, -1).slice(0, -1) + "," + subtitle.style + "," + subtitle.name + "," + subtitle.marginL + "," + subtitle.marginR + "," + subtitle.marginV + "," + subtitle.effect + "," + subtitle.text)
} else if (!Object.values(playerData.tracks[trackNumber].cues).some(c => c.text == subtitle.text && c.startTime == subtitle.time / 1000 && c.endTime == (subtitle.time + subtitle.duration) / 1000)) {
let cue = new VTTCue(subtitle.time / 1000, (subtitle.time + subtitle.duration) / 1000, subtitle.text)
playerData.tracks[trackNumber].addCue(cue)
}
})
parser.on('finish', () => {
playerData.subtitles = subtitles
renderSubs.call(null, 3)
parser.on('subtitle', function (subtitle, trackNumber) {
if (playerData.headers) {
subtitles[trackNumber].push("Dialogue: " + subtitle.layer + "," + new Date(subtitle.time).toISOString().slice(12, -1).slice(0, -1) + "," + new Date(subtitle.time + subtitle.duration).toISOString().slice(12, -1).slice(0, -1) + "," + subtitle.style + "," + subtitle.name + "," + subtitle.marginL + "," + subtitle.marginR + "," + subtitle.marginV + "," + subtitle.effect + "," + subtitle.text)
} else if (!Object.values(playerData.tracks[trackNumber].cues).some(c => c.text == subtitle.text && c.startTime == subtitle.time / 1000 && c.endTime == (subtitle.time + subtitle.duration) / 1000)) {
let cue = new VTTCue(subtitle.time / 1000, (subtitle.time + subtitle.duration) / 1000, subtitle.text)
playerData.tracks[trackNumber].addCue(cue)
}
})
parser.on('finish', () => {
playerData.subtitles = subtitles
renderSubs.call(null, 3)
let time = video.currentTime,
playState = !video.paused
video.src = url
video.currentTime = time
playState ? video.play() : ""
});
file.createReadStream().pipe(parser)
} else {
let time = video.currentTime,
playState = !video.paused
video.src = url
video.currentTime = time
playState ? video.play() : ""
});
file.createReadStream().pipe(parser)
}
}
}
function onProgress() {