mirror of
https://github.com/NoCrypt/migu.git
synced 2026-04-23 09:32:10 +00:00
fix: memory leaks
This commit is contained in:
parent
68c05a71f9
commit
5e5aa7b6ab
4 changed files with 393 additions and 329 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Miru",
|
"name": "Miru",
|
||||||
"version": "4.0.8",
|
"version": "4.0.9",
|
||||||
"author": "ThaUnknown_ <ThaUnknown@users.noreply.github.com>",
|
"author": "ThaUnknown_ <ThaUnknown@users.noreply.github.com>",
|
||||||
"description": "Stream anime torrents, real-time with no waiting for downloads.",
|
"description": "Stream anime torrents, real-time with no waiting for downloads.",
|
||||||
"main": "build/main.js",
|
"main": "build/main.js",
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
"webpack": "^5.85.0",
|
"webpack": "^5.85.0",
|
||||||
"webpack-cli": "^5.1.3",
|
"webpack-cli": "^5.1.3",
|
||||||
"webpack-dev-server": "^4.15.0",
|
"webpack-dev-server": "^4.15.0",
|
||||||
"webtorrent": "^2.0.37"
|
"webtorrent": "^2.1.0"
|
||||||
},
|
},
|
||||||
"standard": {
|
"standard": {
|
||||||
"ignore": [
|
"ignore": [
|
||||||
|
|
|
||||||
595
pnpm-lock.yaml
595
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
|
@ -51,13 +51,19 @@ class TorrentClient extends WebTorrent {
|
||||||
async handleMessage ({ data }) {
|
async handleMessage ({ data }) {
|
||||||
switch (data.type) {
|
switch (data.type) {
|
||||||
case 'current': {
|
case 'current': {
|
||||||
this.current?.removeListener('done', this.boundParse)
|
|
||||||
this.cancelParse()
|
|
||||||
this.current = null
|
|
||||||
this.metadata = null
|
|
||||||
this.parsed = false
|
|
||||||
if (data.data) {
|
if (data.data) {
|
||||||
this.current = (await this.get(data.data.infoHash))?.files.find(file => file.path === data.data.path)
|
const found = (await this.get(data.data.infoHash))?.files.find(file => file.path === data.data.path)
|
||||||
|
if (this.current) {
|
||||||
|
this.current?.removeListener('done', this.boundParse)
|
||||||
|
this.current?.removeAllListeners('iterator')
|
||||||
|
// this is a patch, idfk why these leak
|
||||||
|
for (const iterator of this.current._iterators) {
|
||||||
|
iterator.destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.cancelParse()
|
||||||
|
this.parsed = false
|
||||||
|
this.current = found
|
||||||
if (this.current?.name.endsWith('.mkv')) {
|
if (this.current?.name.endsWith('.mkv')) {
|
||||||
// if (this.current.done) this.parseSubtitles()
|
// if (this.current.done) this.parseSubtitles()
|
||||||
// this.current.once('done', this.boundParse)
|
// this.current.once('done', this.boundParse)
|
||||||
|
|
@ -125,22 +131,23 @@ class TorrentClient extends WebTorrent {
|
||||||
|
|
||||||
cancelParse () {
|
cancelParse () {
|
||||||
this.parser?.destroy()
|
this.parser?.destroy()
|
||||||
|
this.metadata?.destroy()
|
||||||
|
this.metadata = undefined
|
||||||
this.parser = undefined
|
this.parser = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
parseFonts (file) {
|
parseFonts (file) {
|
||||||
const stream = new SubtitleParser(file)
|
this.metadata = new SubtitleParser(file)
|
||||||
this.handleSubtitleParser(stream)
|
this.handleSubtitleParser(this.metadata)
|
||||||
stream.once('tracks', tracks => {
|
this.metadata.once('tracks', tracks => {
|
||||||
if (!tracks.length) {
|
if (!tracks.length) {
|
||||||
this.parsed = true
|
this.parsed = true
|
||||||
stream.destroy()
|
this.metadata.destroy()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
stream.once('subtitle', () => {
|
this.metadata.once('subtitle', () => {
|
||||||
stream.destroy()
|
this.metadata.destroy()
|
||||||
})
|
})
|
||||||
this.metadata = stream
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSubtitleParser (parser, skipFile) {
|
handleSubtitleParser (parser, skipFile) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import { EbmlIteratorDecoder, EbmlTagId } from 'ebml-iterator'
|
import { EbmlIteratorDecoder, EbmlTagId } from 'ebml-iterator'
|
||||||
import { EventEmitter } from 'events'
|
import { EventEmitter } from 'events'
|
||||||
import join from 'join-async-iterator'
|
|
||||||
import { inflate } from 'pako'
|
import { inflate } from 'pako'
|
||||||
|
|
||||||
const SSA_TYPES = new Set(['ssa', 'ass'])
|
const SSA_TYPES = new Set(['ssa', 'ass'])
|
||||||
|
|
@ -53,10 +52,7 @@ export class SubtitleParserBase extends EventEmitter {
|
||||||
[EbmlTagId.BlockGroup]: this.handleBlockGroup.bind(this),
|
[EbmlTagId.BlockGroup]: this.handleBlockGroup.bind(this),
|
||||||
[EbmlTagId.Chapters]: this.handleChapters.bind(this)
|
[EbmlTagId.Chapters]: this.handleChapters.bind(this)
|
||||||
}
|
}
|
||||||
}
|
this.decoder = new EbmlIteratorDecoder({
|
||||||
|
|
||||||
async * [Symbol.asyncIterator] (stream) {
|
|
||||||
const decoder = new EbmlIteratorDecoder({
|
|
||||||
bufferTagIds: [
|
bufferTagIds: [
|
||||||
EbmlTagId.TimecodeScale,
|
EbmlTagId.TimecodeScale,
|
||||||
EbmlTagId.Tracks,
|
EbmlTagId.Tracks,
|
||||||
|
|
@ -64,20 +60,17 @@ export class SubtitleParserBase extends EventEmitter {
|
||||||
EbmlTagId.AttachedFile,
|
EbmlTagId.AttachedFile,
|
||||||
EbmlTagId.Chapters,
|
EbmlTagId.Chapters,
|
||||||
EbmlTagId.Duration
|
EbmlTagId.Duration
|
||||||
],
|
]
|
||||||
stream
|
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
for await (const chunk of stream) {
|
decoderWrite (chunk) {
|
||||||
if (this.destroyed) return null
|
const tags = this.decoder.parseTags(chunk)
|
||||||
const tags = decoder.parseTags(chunk)
|
for (const tag of tags) {
|
||||||
for (const tag of tags) {
|
this._tagMap[tag.id]?.(tag)
|
||||||
this._tagMap[tag.id]?.(tag)
|
if (tag.id === EbmlTagId.Tracks) {
|
||||||
if (tag.id === EbmlTagId.Tracks) {
|
if (!tag.Children.some(({ id }) => id === EbmlTagId.TrackEntry)) return this.destroy()
|
||||||
if (!tag.Children.some(({ id }) => id === EbmlTagId.TrackEntry)) return this.destroy()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
yield chunk
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -200,12 +193,16 @@ export class SubtitleParser extends SubtitleParserBase {
|
||||||
super()
|
super()
|
||||||
|
|
||||||
;(async () => {
|
;(async () => {
|
||||||
|
const iterator = stream[Symbol.asyncIterator]()
|
||||||
try {
|
try {
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
for await (const _ of super[Symbol.asyncIterator](stream)) {
|
for await (const chunk of iterator) {
|
||||||
if (this.destroyed) break
|
if (this.destroyed) return iterator.return()
|
||||||
|
this.decoderWrite(chunk)
|
||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {
|
||||||
|
iterator.return()
|
||||||
|
}
|
||||||
this.emit('finish')
|
this.emit('finish')
|
||||||
})()
|
})()
|
||||||
}
|
}
|
||||||
|
|
@ -227,35 +224,40 @@ export class SubtitleStream extends SubtitleParserBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async * [Symbol.asyncIterator] (stream = this._stream) {
|
destroy () {
|
||||||
while (true) {
|
this.destroyed = true
|
||||||
if (this.destroyed) return
|
this.emit('finish')
|
||||||
if (this.unstable) {
|
this._stream.return()
|
||||||
const iterator = stream[Symbol.asyncIterator]()
|
}
|
||||||
const { value: chunk } = await iterator.next()
|
|
||||||
if (!chunk) return
|
async * [Symbol.asyncIterator] () {
|
||||||
// the ebml decoder expects to see a tag, so we won't use it until we find a cluster
|
try {
|
||||||
for (let i = 0; i < chunk.length - 12; i++) {
|
for await (const chunk of this._stream) {
|
||||||
// cluster id 0x1F43B675
|
if (this.destroyed) return this._stream.return()
|
||||||
// https://matroska.org/technical/elements.html#LevelCluster
|
if (this.unstable) {
|
||||||
if (chunk[i] === 0x1f && chunk[i + 1] === 0x43 && chunk[i + 2] === 0xb6 && chunk[i + 3] === 0x75) {
|
// the ebml decoder expects to see a tag, so we won't use it until we find a cluster
|
||||||
// length of cluster size tag
|
for (let i = 0; i < chunk.length - 12; i++) {
|
||||||
const len = 8 - Math.floor(Math.log2(chunk[i + 4]))
|
// cluster id 0x1F43B675
|
||||||
// first tag in cluster is a valid EbmlTag
|
// https://matroska.org/technical/elements.html#LevelCluster
|
||||||
if (EbmlTagId[chunk[i + 4 + len]]) {
|
if (chunk[i] === 0x1f && chunk[i + 1] === 0x43 && chunk[i + 2] === 0xb6 && chunk[i + 3] === 0x75) {
|
||||||
// okay this is probably a cluster
|
// length of cluster size tag
|
||||||
this.unstable = false
|
const len = 8 - Math.floor(Math.log2(chunk[i + 4]))
|
||||||
yield chunk.slice(0, i)
|
// first tag in cluster is a valid EbmlTag
|
||||||
yield * super[Symbol.asyncIterator](join([[chunk.slice(i)], iterator]))
|
if (EbmlTagId[chunk[i + 4 + len]]) {
|
||||||
return
|
// okay this is probably a cluster
|
||||||
|
this.unstable = false
|
||||||
|
this.decoderWrite(chunk.slice(i))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
this.decoderWrite(chunk)
|
||||||
}
|
}
|
||||||
yield chunk
|
yield chunk
|
||||||
} else {
|
|
||||||
yield * super[Symbol.asyncIterator](stream)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
this._stream.return()
|
||||||
}
|
}
|
||||||
|
this._stream.return()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue