From 7b71cd925db9e572c3d04356661884b12e4b5605 Mon Sep 17 00:00:00 2001 From: ThaUnknown <6506529+ThaUnknown@users.noreply.github.com> Date: Wed, 17 Jul 2024 23:20:28 +0200 Subject: [PATCH] feat(web): document extensions --- electron/package.json | 2 +- extensions/example.js | 32 +++++++++++++ extensions/type-definitions.d.ts | 42 ++++++++++++++++ web/src/routes/extensions/+page.svelte | 66 ++++++++++++++++++++++++++ web/src/routes/faq/+page.svelte | 41 +++++++++++++--- 5 files changed, 176 insertions(+), 7 deletions(-) create mode 100644 extensions/example.js create mode 100644 extensions/type-definitions.d.ts create mode 100644 web/src/routes/extensions/+page.svelte diff --git a/electron/package.json b/electron/package.json index 2dd33b53..4fd40f61 100644 --- a/electron/package.json +++ b/electron/package.json @@ -1,6 +1,6 @@ { "name": "Miru", - "version": "5.2.3", + "version": "5.2.5", "private": true, "author": "ThaUnknown_ ", "description": "Stream anime torrents, real-time with no waiting for downloads.", diff --git a/extensions/example.js b/extensions/example.js new file mode 100644 index 00000000..74ef631e --- /dev/null +++ b/extensions/example.js @@ -0,0 +1,32 @@ +export default class AbstractSource { + name = 'Missing name' + description = 'No description provided' + /** @type {import('./type-definitions').Accuracy} */ + accuracy = 'Low' + /** @type {import('./type-definitions').Config} */ + config = {} + + /** + * Gets results for single episode + * @type {import('./type-definitions').SearchFunction} + */ + single (options) { + throw new Error('Source doesn\'t implement single') + } + + /** + * Gets results for batch of episodes + * @type {import('./type-definitions').SearchFunction} + */ + batch (options) { + throw new Error('Source doesn\'t implement batch') + } + + /** + * Gets results for a movie + * @type {import('./type-definitions').SearchFunction} + */ + movie (options) { + throw new Error('Source doesn\'t implement movie') + } +} diff --git a/extensions/type-definitions.d.ts b/extensions/type-definitions.d.ts new file mode 100644 index 00000000..b607faaf --- /dev/null +++ b/extensions/type-definitions.d.ts @@ -0,0 +1,42 @@ +export interface Result { + title: string // torrent title + link: string // link to .torrent file, or magnet link + id?: number + seeders: number + leechers: number + downloads: number + hash: string // info hash + size: number // size in bytes + verified: boolean // if it's a verified release, e.g. it's 100% certain it's the correct episode, manually verified by the provider e.g. anidb + date: Date // date the torrent was uploaded + type?: 'batch' | 'best' | 'alt' +} + +export interface Options { + anilistId: number // anilist anime id + anidbAid?: number // anidb anime id + anidbEid?: number // anidb episode id + titles: string[] // list of titles and alternative titles + episode?: number + episodeCount?: number // total episode count for the series + resolution: '2160' | '1080' | '720' | '540' | '480' | '' + exclusions: string[] // list of keywords to exclude from searches +} + +export type SearchFunction = (options: Options) => Promise + +export type Config = { + seed?: 'perma' | number // seed ratio to hit +} + +export type Accuracy = 'High' | 'Medium' | 'Low' + +export class Source { + name: string + description: string + accuracy: Accuracy + config: Config + single: SearchFunction + batch: SearchFunction + movie: SearchFunction +} diff --git a/web/src/routes/extensions/+page.svelte b/web/src/routes/extensions/+page.svelte new file mode 100644 index 00000000..7065572f --- /dev/null +++ b/web/src/routes/extensions/+page.svelte @@ -0,0 +1,66 @@ +
+
+
+

About Extensions

+
Frequently Asked Questions about Extensions.
+
+
+

What are some recommended extensions and sources?

+

Miru is bring-your-own-content and does not offer anything, however anisearch is recommended.

+
+

Is there a curated list of extensions and sources?

+

No. Miru is not directly associated with any extensions or sources. It's merely a client for streaming one's own media.

+
+

How to install/uninstall extensions?

+

Inside Settings > Torrent > Extensions you can add extensions by either inputting a full URL such as https://example.website/file.js or if an extension is published on npm packagename and pressing add. This will automatically import all sources the extension provides. You can then uninstall an extension by pressing the remove button next to it.

+
+

Can you disable sources?

+

You can disable sources in the sources list by clicking on it's toggle.

+
+

How to develop new extensions?

+

Extensions for Miru need to be written in JavaScriptn which are run in an isolated Web Worker. Make sure the data you're fetching is CORS enabled. Extension type definitions and example structures are available on GitHub.

+

Options object, which is passed to the class's single, batch and movie functions as the first parameters has the following fields:

+
    +
  • anilistId: number - Anilist anime id, can be used to query data from Anilist, such as MalID, episode metadata etc
  • +
  • anidbAid?: number - AniDB anime id, not always present, useful to query mapping API's
  • +
  • anidbEid?: number - AniDB episode id, not always present, useful to query specific data, as AnidbEIDs map to manually maintained files
  • +
  • titles: string[] - list of titles and alternative titles for the given anime
  • +
  • episode?: number - episode to look for, not always present
  • +
  • episodeCount?: number - total episode count for the series, not always present
  • +
  • resolution: '2160' | '1080' | '720' | '540' | '480' | '' - resolution height. empty string means any
  • +
  • exclusions: string[] - list of keywords to exclude from searches such as codecs unsuppored by the platform, etc
  • +
+

Results object, array of which is returned by the functions of the class has the following fields:

+
    +
  • title: string - torrent title, this isn't always the file title as a torrent might include multiple files
  • +
  • link: string - http:// link to .torrent file, or magnet:// link
  • +
  • id?: number - unused for now
  • +
  • seeders: number
  • +
  • leechers: number
  • +
  • downloads: number
  • +
  • hash: string - info hash REQUIRED
  • +
  • size: number - size in bytes
  • +
  • verified: boolean - if it's a verified release, e.g. it's 100% certain it's the correct episode, manually verified by the provider e.g. anidb
  • +
  • date: Date - date the torrent was uploaded
  • +
  • type?: 'batch' | 'best' | 'alt' - type of the result best/alt means it's the best known release
  • +
+
+
+ + diff --git a/web/src/routes/faq/+page.svelte b/web/src/routes/faq/+page.svelte index 1157cdb0..1e52cca5 100644 --- a/web/src/routes/faq/+page.svelte +++ b/web/src/routes/faq/+page.svelte @@ -1,22 +1,34 @@
-

Frequently Asked Questions

-

Won't this kill swarm health?

-

Depends. On average no. The app is always seeding 1 torrent as long as it's open. Additionally the upload speed is forced to be x1.5 that of the download speed. Those 2 things combined will already make this app seed more than the average leecher which removes the torrent the moment it's downloaded.

+
+

Frequently Asked Questions

+
Most commonly asked questions about Miru and its usage.
+
+
+

What extensions are there? How to make extensions?

+

You can find all information regarding extensions on the extensions page.

+

Can I close the miniplayer?

No. See above. The miniplayer provides feedback that something is happening in the background. Closing it would make the user feel like the app is lagging [because it's maxing out your internet in the background by torrenting] when nothing is happening.

+

Can I reduce the upload speed?

No. See above. This app is also meant to seed the torrents the user downloads, if you want freeleech go to some private tracker.

+

Does Miru stream the video or does it store it?

Miru only stores 1 torrent on your drive, unless Persist Files is enabled in settings. It doesn't stream the content as it also needs to seed the data it downloads to keep the swarm alive. It's important to note that it stores 1 torrent, not 1 video. A single torrent can sometimes consist of many video files, and as such take up a lot of space.

+

I have an existing media library, can Miru import it?

No. Miru does not scan libraries like Plex or Jellyfin. You can however specify Miru's Torrent Download Location in settings, and if you pick torrents which are already in the selected folder, Miru will use them without re-download them. Make sure that Persis Files is enabled, or Miru will delete content that was already watched.

+

Is this safe?

It's recommended that you read the guide about basics of torrenting.

+

Will this replace streaming sites?

Not really. The underlying source of video are still torrents, which aren't always seeded, so anime that's a few years old might not play back smoothly.

+

Can I log in with MAL?

No. You can however migrate MAL to AL, see this guide.

+

Why is anime X not playing?

One of four reasons:

    @@ -25,29 +37,46 @@
  • your ISP blocks Torrenting, see this tutorial for a potential fix, or simply use a VPN
  • the app couldn't find a matching torrent for the anime
+

I selected an episode to play, but Miru plays something else!

Finding desired episodes can sometimes be difficult, if Miru auto-selects an episode incorrectly you can either disable auto-play torrents in settings to select torrents yourself during episode choosing, or manually find and paste in a .torrent file URL or a magnet URL into Miru to play a desired episode manually.

+

Can I play my own torrents?

Yes. For the home menu you can specify a different RSS feed to check when the app looks for new releases. Additionally you can just paste/drag-drop a torrent file/magnet link anywhere when using the app, and it will try it's best to auto-detect what anime is playing.

+

Can I change what tracker torrents are found from?

Yes. If you find other community made extensions, you can import them in the app settings, however there is no curated list of community made extensions.

+

How is this different from sequential qBit?

Unlike qBit's sequential, this will prioritise downloading torrent pieces directly needed for playback, which with the user seeking isn't always just sequential.

+
+

Won't this kill swarm health?

+

Depends. On average no. The app is always seeding 1 torrent as long as it's open. Additionally the upload speed is forced to be x1.5 that of the download speed. Those 2 things combined will already make this app seed more than the average leecher which removes the torrent the moment it's downloaded.

+

Why is it a native app, not a website?

The BitTorrent protocol requires TCP/UDP to function, that is the only reason. Browsers can't access TCP/UDP which means they can't access the global BitTorrent swarm.

> Can't you make this just use WebRTC?

Yes. A BitTorrent implementation which uses WebRTC exists, but it's not yet adopted by any clients, and libtorrent [the library which qBit and others use] is still working on/just added support for WebRTC, which means there's no global swarm. This will hopefully change in the future.

+

Miru crashed too many times.

This is likely because Miru updated from a very old version to a very new one. Uninstall Miru, go to %appdata%/miru remove all files and re-install it. If this issue persists visit the Discord for help.