full offline video playback, VTT subtitle fixes, post-download improvements, minor fixes

This commit is contained in:
ThaUnknown 2021-02-02 01:11:04 +01:00
parent a2367f0c7e
commit afffffbfe5
6 changed files with 28 additions and 21 deletions

View file

@ -665,12 +665,8 @@
<input id="subtitle1" type="text" list="subtitle1list" class="form-control"
autocomplete="off" value="SubsPlease">
<datalist id="subtitle1list">
<option value="SubsPlease">Roboto
Medium,26,&H00FFFFFF,&H000000FF,&H00020713,&H00000000,0,0,0,0,100,100,0,0,1,1.3,0,2,20,20,23,1
</option>
<option value="Erai-raws">Open Sans
Semibold,45,&H00FFFFFF,&H000000FF,&H00020713,&H00000000,-1,0,0,0,100,100,0,0,1,1.7,0,2,10,10,25,1
</option>
<option value="SubsPlease">Roboto Medium,26,&H00FFFFFF,&H000000FF,&H00020713,&H00000000,0,0,0,0,100,100,0,0,1,1.3,0,2,20,20,23,1</option>
<option value="Erai-raws">Open Sans Semibold,45,&H00FFFFFF,&H000000FF,&H00020713,&H00000000,-1,0,0,0,100,100,0,0,1,1.7,0,2,10,10,25,1</option>
</datalist>
</div>
<div class="custom-switch mb-20" data-toggle="tooltip" data-placement="top" data-title="Displays Subtitles In PiP And ChromeCast, Requires chrome://flags/#disable-accelerated-2d-canvas Set To
@ -778,10 +774,10 @@
</div>
</div>
<script src="https://cdn.jsdelivr.net/gh/halfmoonui/halfmoon@1.1.1/js/halfmoon.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/webtorrent@latest/webtorrent.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/matroska-subtitles@latest/dist/matroska-subtitles.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/indexeddb-chunk-store@latest/idbchunkstore.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/anitomyscript@2.0.4/dist/anitomyscript.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/webtorrent@latest/webtorrent.min.js"></script>
<script src="js/settingsHandler.js"></script>
<script src="js/rangeParser.js"></script>
<script src="js/util.js"></script>

View file

@ -625,11 +625,11 @@ async function resolveFileMedia(opts) {
tempMedia = opts.media.relations.edges.filter(edge => edge.relationType == "SEQUEL" && (edge.node.format == "TV" || "TV_SHORT"))[0].node
increment = true
}
if (tempMedia.episodes && epMax - (opts.offset + tempMedia.episodes) > (media.episodes || media.nextAiringEpisode.episode)) {
if (tempMedia?.episodes && epMax - (opts.offset + tempMedia.episodes) > (media.episodes || media.nextAiringEpisode.episode)) {
// episode is still out of bounds
let nextEdge = await alRequest({ method: "SearchIDSingle", id: tempMedia.id })
await resolveSeason({ media: nextEdge.data.Media, episode: opts.episode, offset: opts.offset + nextEdge.data.Media.episodes, increment: increment })
} else if (tempMedia.episodes && epMax - (opts.offset + tempMedia.episodes) < (media.episodes || media.nextAiringEpisode.episode) && epMin - (opts.offset + tempMedia.episodes) > 0) {
} else if (tempMedia?.episodes && epMax - (opts.offset + tempMedia.episodes) < (media.episodes || media.nextAiringEpisode.episode) && epMin - (opts.offset + tempMedia.episodes) > 0) {
// episode is in range, seems good! overwriting media to count up "seasons"
if (opts.episode.constructor == Array) {
episode = `${elems.episode_number[0] - (opts.offset + tempMedia.episodes)} - ${elems.episode_number[elems.episode_number.length - 1] - (opts.offset + tempMedia.episodes)}`

View file

@ -154,7 +154,7 @@ async function buildVideo(torrent, opts) { // sets video source and creates a bu
if (playerData.nowPlaying[0].streamingEpisodes.length >= Number(playerData.nowPlaying[1])) {
let streamingEpisode = playerData.nowPlaying[0].streamingEpisodes.filter(episode => episodeRx.exec(episode.title) && episodeRx.exec(episode.title)[1] == Number(playerData.nowPlaying[1]))[0]
video.poster = streamingEpisode.thumbnail
document.title = `${playerData.nowPlaying[0].title.userPreferred} - ${Number(playerData.nowPlaying[1])} - EP ${episodeRx.exec(streamingEpisode.title)[2]} - Miru`
document.title = `${playerData.nowPlaying[0].title.userPreferred} - EP ${Number(playerData.nowPlaying[1])} - ${episodeRx.exec(streamingEpisode.title)[2]} - Miru`
mediaMetadata.artist = `Episode ${Number(playerData.nowPlaying[1])} - ${episodeRx.exec(streamingEpisode.title)[2]}`
mediaMetadata.artwork = [{
src: streamingEpisode.thumbnail,

View file

@ -14,6 +14,8 @@ function subStream(stream) { // subtitle parsing with seeking support
track.header = `[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,${Object.values(subtitle1list.options).filter(item => item.value == settings.subtitle1)[0].innerText}
[Events]
`
}
playerData.headers[track.number] = track
@ -28,8 +30,7 @@ Style: Default,${Object.values(subtitle1list.options).filter(item => item.value
let formatSub = "Dialogue: " + (subtitle.layer || 0) + "," + 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 || "Default") + "," + (subtitle.name || "") + "," + (subtitle.marginL || "0") + "," + (subtitle.marginR || "0") + "," + (subtitle.marginV || "0") + "," + (subtitle.effect || "") + "," + subtitle.text
if (!playerData.subtitles[trackNumber].has(formatSub)) {
playerData.subtitles[trackNumber].add(formatSub)
if (playerData.selectedHeader == trackNumber)
renderSubs.call(null, trackNumber)
if (playerData.selectedHeader == trackNumber) renderSubs(trackNumber)
}
}
@ -46,7 +47,7 @@ function renderSubs(trackNumber) {
video: video,
subContent: trackNumber ? playerData.headers[trackNumber].header.slice(0, -1) + Array.from(playerData.subtitles[trackNumber]).join("\n") : playerData.headers[3].header.slice(0, -1),
lossyRender: true,
fonts: playerData.fonts.length == 0 ? ["https://fonts.gstatic.com/s/roboto/v20/KFOlCnqEu92Fr1MmEU9fBBc4.woff2"] : playerData.fonts,
fonts: playerData.fonts?.length != 0 ? playerData.fonts : ["https://fonts.gstatic.com/s/roboto/v20/KFOlCnqEu92Fr1MmEU9fBBc4.woff2"] ,
workerUrl: 'js/subtitles-octopus-worker.js',
timeOffset: 0
};
@ -84,6 +85,8 @@ function postDownload(file) { // parse subtitles fully after a download is finis
track.header = `[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,${Object.values(subtitle1list.options).filter(item => item.value == settings.subtitle1)[0].innerText}
[Events]
`
}
headers[track.number] = track
@ -99,8 +102,10 @@ Style: Default,${Object.values(subtitle1list.options).filter(item => item.value
playerData.headers = headers
playerData.parsed = 1
playerData.subtitleStream = undefined
renderSubs.call(null, playerData.selectedHeader)
renderSubs(playerData.selectedHeader)
parser = undefined
video.pause();
playVideo();
});
file.createReadStream().pipe(parser)
}

View file

@ -19,7 +19,7 @@ var SubtitlesOctopus = function (options) {
self.dropAllAnimations = options.dropAllAnimations || false;
self.libassMemoryLimit = options.libassMemoryLimit || 0; // set libass bitmap cache memory limit in MiB (approximate)
self.libassGlyphLimit = options.libassGlyphLimit || 0; // set libass glyph cache memory limit in MiB (approximate)
self.targetFps = options.targetFps || 60;
self.targetFps = options.targetFps || 30;
self.prescaleTradeoff = options.prescaleTradeoff || null; // render subtitles less than viewport when less than 1.0 to improve speed, render to more than 1.0 to improve quality; set to null to disable scaling
self.softHeightLimit = options.softHeightLimit || 1080; // don't apply prescaleTradeoff < 1 when viewport height is less that this limit
self.hardHeightLimit = options.hardHeightLimit || 2160; // don't ever go above this limit

View file

@ -55,8 +55,8 @@ function t(a) {
// offline storage initial load
let offlineTorrents
async function loadOfflineStorage() {
offlineTorrents = new Set([...await indexedDB.databases()].map(object => { return object.name }));
[...offlineTorrents].forEach(torrentID => offlineDownload(torrentID, true)) // adds all offline store torrents to the client
offlineTorrents = JSON.parse(localStorage.getItem("offlineTorrents")) || {};
Object.values(offlineTorrents).forEach(torrentID => offlineDownload(new Blob([new Uint8Array(torrentID)]), true)) // adds all offline store torrents to the client
}
// add torrent for offline download
@ -66,12 +66,16 @@ function offlineDownload(torrentID, skipVerify) {
skipVerify: skipVerify
})
torrent.on("metadata", async () => {
offlineTorrents.add(torrent.infoHash)
console.log(torrent)
if (!offlineTorrents[torrent.infoHash]) {
offlineTorrents[torrent.infoHash] = Array.from(torrent.torrentFile);
localStorage.setItem("offlineTorrents", JSON.stringify(offlineTorrents))
}
let mediaInformation = await resolveFileMedia({ fileName: torrent.name, method: "SearchName" })
template = cardCreator(mediaInformation)
template.onclick = async () => {
addTorrent(torrent, { media: mediaInformation.media, episode: mediaInformation.parseObject.episode })
store[mediaInformation.parseObject.anime_title] = await alRequest({ id: mediaInformation.media?.id, method: "SearchIDSingle" }).then(res => res.data.Media)
store[mediaInformation.parseObject.anime_title] = await alRequest({ id: mediaInformation.media?.id, method: "SearchIDSingle" }).then(res => res.data.Media)
// force updates entry data on play in case its outdated, needs to be made cleaner and somewhere else...
}
document.querySelector(".downloads").appendChild(template)
@ -83,7 +87,7 @@ loadOfflineStorage()
// cleanup torrent and store
function cleanupTorrents() {
client.torrents.filter(torrent => {
return !offlineTorrents.has(torrent.infoHash) || torrent.progress != 1 // creates an array of all non-offline store torrents and removes them
return !(offlineTorrents[torrent.infoHash] || torrent.progress == 1) // creates an array of all non-offline store torrents and removes them
}).forEach(torrent => torrent.destroy({ destroyStore: true }))
}
@ -122,7 +126,9 @@ function addTorrent(torrentID, opts) {
document.location.hash = "#player"
cleanupVideo()
cleanupTorrents()
if (client.get(torrentID)) {
if (torrentID instanceof Object) {
playTorrent(torrentID, opts)
} else if (client.get(torrentID)) {
playTorrent(client.get(torrentID), opts)
} else {
client.add(torrentID, settings.torrent5 ? { store: IdbChunkStore } : {}, function (torrent) {