Skip to content

Commit

Permalink
feat(web): document extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
ThaUnknown committed Jul 17, 2024
1 parent 13bed67 commit 7b71cd9
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 7 deletions.
2 changes: 1 addition & 1 deletion electron/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Miru",
"version": "5.2.3",
"version": "5.2.5",
"private": true,
"author": "ThaUnknown_ <ThaUnknown@users.noreply.github.com>",
"description": "Stream anime torrents, real-time with no waiting for downloads.",
Expand Down
32 changes: 32 additions & 0 deletions extensions/example.js
Original file line number Diff line number Diff line change
@@ -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')
}
}
42 changes: 42 additions & 0 deletions extensions/type-definitions.d.ts
Original file line number Diff line number Diff line change
@@ -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<Result[]>

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
}
66 changes: 66 additions & 0 deletions web/src/routes/extensions/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<div class='container font-size-18 pb-20'>
<div class='content'>
<div class='h-vh-half px-20 px-sm-0 d-flex justify-content-center flex-column'>
<h1 class='font-weight-bold text-white title'>About Extensions</h1>
<div class='font-size-18 text-muted'>Frequently Asked Questions about Extensions.</div>
</div>
<hr class='my-20' />
<h3 class='text-white font-weight-bold'>What are some recommended extensions and sources?</h3>
<p>Miru is bring-your-own-content and does not offer anything, however <kbd>anisearch</kbd> is recommended.</p>
<hr class='my-20' />
<h3 class='text-white font-weight-bold'>Is there a curated list of extensions and sources?</h3>
<p>No. Miru is not directly associated with any extensions or sources. It's merely a client for streaming one's own media.</p>
<hr class='my-20' />
<h3 class='text-white font-weight-bold'>How to install/uninstall extensions?</h3>
<p>Inside <kbd>Settings &gt; Torrent &gt; Extensions</kbd> you can add extensions by either inputting a full URL such as <kbd>https://example.website/file.js</kbd> or if an extension is published on npm <kbd>packagename</kbd> 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.</p>
<hr class='my-20' />
<h3 class='text-white font-weight-bold'>Can you disable sources?</h3>
<p>You can disable sources in the sources list by clicking on it's toggle.</p>
<hr class='my-20' />
<h3 class='text-white font-weight-bold'>How to develop new extensions?</h3>
<p>Extensions for Miru need to be written in JavaScriptn which are run in an isolated <a href='https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API' target='_blank'>Web Worker</a>. Make sure the data you're fetching is CORS enabled. Extension type definitions and example structures are available on <a href='https://github.com/ThaUnknown/miru/tree/master/extensions' target='_blank'>GitHub</a>.</p>
<p>Options object, which is passed to the class's single, batch and movie functions as the first parameters has the following fields:</p>
<ul>
<li>anilistId: number - Anilist anime id, can be used to query data from Anilist, such as MalID, episode metadata etc</li>
<li>anidbAid?: number - AniDB anime id, not always present, useful to query mapping API's</li>
<li>anidbEid?: number - AniDB episode id, not always present, useful to query specific data, as AnidbEIDs map to manually maintained files</li>
<li>titles: string[] - list of titles and alternative titles for the given anime</li>
<li>episode?: number - episode to look for, not always present</li>
<li>episodeCount?: number - total episode count for the series, not always present</li>
<li>resolution: '2160' | '1080' | '720' | '540' | '480' | '' - resolution height. empty string means any</li>
<li>exclusions: string[] - list of keywords to exclude from searches such as codecs unsuppored by the platform, etc</li>
</ul>
<p>Results object, array of which is returned by the functions of the class has the following fields:</p>
<ul>
<li>title: string - torrent title, this isn't always the file title as a torrent might include multiple files</li>
<li>link: string - http:// link to .torrent file, or magnet:// link</li>
<li>id?: number - unused for now</li>
<li>seeders: number</li>
<li>leechers: number</li>
<li>downloads: number</li>
<li>hash: string - info hash REQUIRED</li>
<li>size: number - size in bytes</li>
<li>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</li>
<li>date: Date - date the torrent was uploaded</li>
<li>type?: 'batch' | 'best' | 'alt' - type of the result best/alt means it's the best known release</li>
</ul>
</div>
</div>

<style>
a {
--dm-link-text-color: #1890ff !important;
--dm-link-text-color-hover: #45a3fb !important;
}
h3 {
margin-top: 0;
padding-top: 0.75em;
}
p {
margin-bottom: 0;
padding-bottom: 1em;
}
.title {
font-size: 5rem
}
</style>
41 changes: 35 additions & 6 deletions web/src/routes/faq/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,22 +1,34 @@
<div class='container font-size-18 pb-20'>
<div class='content'>
<h1 class='text-white font-weight-bold'>Frequently Asked Questions</h1>
<h3 class='text-white font-weight-bold'>Won't this kill swarm health?</h3>
<p>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.</p>
<div class='h-vh-half row px-20 px-sm-0 d-flex justify-content-center flex-column'>
<h1 class='font-weight-bold text-white title'>Frequently Asked Questions</h1>
<div class='font-size-18 text-muted'>Most commonly asked questions about Miru and its usage.</div>
</div>
<hr class='my-20' />
<h3 class='text-white font-weight-bold'>What extensions are there? How to make extensions?</h3>
<p>You can find all information regarding extensions on the <a href='../extensions/' target='_blank'>extensions</a> page.</p>
<hr class='my-20' />
<h3 class='text-white font-weight-bold'>Can I close the miniplayer?</h3>
<p>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.</p>
<hr class='my-20' />
<h3 class='text-white font-weight-bold'>Can I reduce the upload speed?</h3>
<p>No. See above. This app is also meant to seed the torrents the user downloads, if you want freeleech go to some private tracker.</p>
<hr class='my-20' />
<h3 class='text-white font-weight-bold'>Does Miru stream the video or does it store it?</h3>
<p>Miru only stores 1 torrent on your drive, unless <kbd>Persist Files</kbd> 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.</p>
<hr class='my-20' />
<h3 class='text-white font-weight-bold'>I have an existing media library, can Miru import it?</h3>
<p>No. Miru does not scan libraries like Plex or Jellyfin. You can however specify Miru's <kbd>Torrent Download Location</kbd> 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 <kbd>Persis Files</kbd> is enabled, or Miru will delete content that was already watched.</p>
<hr class='my-20' />
<h3 class='text-white font-weight-bold'>Is this safe?</h3>
<p>It's recommended that you read the <a href='https://thewiki.moe/getting-started/torrenting/' target='_blank'>guide about basics of torrenting</a>.</p>
<hr class='my-20' />
<h3 class='text-white font-weight-bold'>Will this replace streaming sites?</h3>
<p>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.</p>
<hr class='my-20' />
<h3 class='text-white font-weight-bold'>Can I log in with MAL?</h3>
<p>No. You can however migrate MAL to AL, <a href='https://anilist.co/forum/thread/3393' target='_blank'>see this guide</a>.</p>
<hr class='my-20' />
<h3 class='text-white font-weight-bold'>Why is anime X not playing?</h3>
<p>One of four reasons:</p>
<ul>
Expand All @@ -25,29 +37,46 @@
<li>your ISP blocks Torrenting, see <a href='https://thewiki.moe/tutorials/unblock/' target='_blank'>this tutorial</a> for a potential fix, or simply use a VPN</li>
<li>the app couldn't find a matching torrent for the anime</li>
</ul>
<hr class='my-20' />
<h3 class='text-white font-weight-bold'>I selected an episode to play, but Miru plays something else!</h3>
<p>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.</p>
<hr class='my-20' />
<h3 class='text-white font-weight-bold'>Can I play my own torrents?</h3>
<p>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.</p>
<hr class='my-20' />
<h3 class='text-white font-weight-bold'>Can I change what tracker torrents are found from?</h3>
<p>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.</p>
<hr class='my-20' />
<h3 class='text-white font-weight-bold'>How is this different from sequential qBit?</h3>
<p>Unlike qBit's sequential, this will prioritise downloading torrent pieces directly needed for playback, which with the user seeking isn't always just sequential.</p>
<hr class='my-20' />
<h3 class='text-white font-weight-bold'>Won't this kill swarm health?</h3>
<p>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.</p>
<hr class='my-20' />
<h3 class='text-white font-weight-bold'>Why is it a native app, not a website?</h3>
<p>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.</p>
<h5 class='text-white font-weight-bold'>&gt; Can't you make this just use WebRTC?</h5>
<p>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.</p>
<hr class='my-20' />
<h3 class='text-white font-weight-bold'>Miru crashed too many times.</h3>
<p>This is likely because Miru updated from a very old version to a very new one. Uninstall Miru, go to <kbd>%appdata%/miru</kbd> remove all files and re-install it. If this issue persists visit the Discord for help.</p>
</div>
</div>

<style>
.container {
padding-top: 10rem;
}
a {
--dm-link-text-color: #1890ff !important;
--dm-link-text-color-hover: #45a3fb !important;
}
h3 {
margin-top: 0;
padding-top: 0.75em;
}
p {
margin-bottom: 0;
padding-bottom: 1em;
}
.title {
font-size: 5rem
}
</style>

0 comments on commit 7b71cd9

Please sign in to comment.