mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2025-09-08 23:18:43 +00:00
updated directory structure to fix root Service Worker issues and performance improvements
This commit is contained in:
457
webtorrent-docs/get-started.md
Normal file
457
webtorrent-docs/get-started.md
Normal file
@@ -0,0 +1,457 @@
|
||||
# Get Started with WebTorrent
|
||||
|
||||
**WebTorrent** is the first torrent client that works in the **browser**. It's easy
|
||||
to get started!
|
||||
|
||||
## Install
|
||||
|
||||
To start using WebTorrent, simply include the
|
||||
[`webtorrent`](https://esm.sh/webtorrent)
|
||||
script on your page.
|
||||
|
||||
```html
|
||||
<script type="module">
|
||||
import WebTorrent from "https://esm.sh/webtorrent";
|
||||
</script>
|
||||
```
|
||||
|
||||
### Browserify and Webpack
|
||||
|
||||
WebTorrent also works great with [browserify](http://browserify.org/), [webpack](https://webpack.js.org/) and other bundlers, which let
|
||||
you use [node.js](http://nodejs.org/) style `require()` to organize your browser
|
||||
code, and load packages installed by [npm](https://npmjs.org/).
|
||||
|
||||
For an example webpack config see [the webpack bundle config used by webtorrent](/scripts/browser.webpack.js).
|
||||
|
||||
```
|
||||
npm install webtorrent
|
||||
```
|
||||
|
||||
Then use `WebTorrent` like this:
|
||||
|
||||
```js
|
||||
import WebTorrent from "webtorrent";
|
||||
```
|
||||
|
||||
## Quick Examples
|
||||
|
||||
### Downloading a torrent (in the browser)
|
||||
|
||||
```js
|
||||
import WebTorrent from "webtorrent";
|
||||
|
||||
const client = new WebTorrent();
|
||||
|
||||
// Sintel, a free, Creative Commons movie
|
||||
const torrentId =
|
||||
"magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10&dn=Sintel&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fsintel.torrent";
|
||||
|
||||
// see tutorials.md for a full example of streaming media using service workers
|
||||
navigator.serviceWorker.register("sw.min.js");
|
||||
const controller = await navigator.serviceWorker.ready;
|
||||
client.createServer({ controller });
|
||||
|
||||
client.add(torrentId, (torrent) => {
|
||||
// Torrents can contain many files. Let's use the .mp4 file
|
||||
const file = torrent.files.find((file) => {
|
||||
return file.name.endsWith(".mp4");
|
||||
});
|
||||
|
||||
// Display the file by adding it to the DOM.
|
||||
// Supports video, audio, image files, and more!
|
||||
file.streamTo(document.querySelector("video"));
|
||||
});
|
||||
```
|
||||
|
||||
This supports video, audio, images, PDFs, HTML, right out of the box. There are additional ways to access file content directly, including as a node-style stream, ArrayBuffer, or Blob.
|
||||
|
||||
Video and audio content can be streamed, i.e. playback will start before the full file is downloaded. Seeking works too – WebTorrent dynamically fetches
|
||||
the needed torrent pieces from the network on-demand.
|
||||
|
||||
**Note:** Downloading a torrent automatically seeds it, making it available for download by other peers.
|
||||
|
||||
### Creating a new torrent and seed it (in the browser)
|
||||
|
||||
```js
|
||||
import dragDrop from "drag-drop";
|
||||
import WebTorrent from "webtorrent";
|
||||
|
||||
const client = new WebTorrent();
|
||||
|
||||
// When user drops files on the browser, create a new torrent and start seeding it!
|
||||
dragDrop("body", (files) => {
|
||||
client.seed(files, (torrent) => {
|
||||
console.log("Client is seeding " + torrent.magnetURI);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
This example uses the [`drag-drop`][drag-drop] package, to make the HTML5 Drag and
|
||||
Drop API easier to work with.
|
||||
|
||||
**Note:** If you do not use browserify, use the standalone file
|
||||
[`dragdrop.min.js`](https://bundle.run/drag-drop).
|
||||
This exports a `DragDrop` function on `window`.
|
||||
|
||||
### Download and save a torrent (in Node.js)
|
||||
|
||||
```js
|
||||
import WebTorrent from "webtorrent";
|
||||
|
||||
const client = new WebTorrent();
|
||||
|
||||
const magnetURI = "magnet: ...";
|
||||
|
||||
client.add(magnetURI, { path: "/path/to/folder" }, (torrent) => {
|
||||
torrent.on("done", () => {
|
||||
console.log("torrent download finished");
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Creating a new torrent and seed it (in Node.js)
|
||||
|
||||
**Note:** Seeding a torrent that can be downloaded by browser peers (i.e. with support for WebRTC) requires [webtorrent-hybrid](https://github.com/webtorrent/webtorrent-hybrid).
|
||||
|
||||
```js
|
||||
import WebTorrent from "webtorrent-hybrid";
|
||||
const client = new WebTorrent();
|
||||
|
||||
client.seed("/seed-me.txt", (torrent) => {
|
||||
console.log("Client is seeding " + torrent.magnetURI);
|
||||
});
|
||||
```
|
||||
|
||||
where **seed-me.txt** is a text file which is going to be seeded as a torrent.
|
||||
|
||||
### Complete HTML page example
|
||||
|
||||
Looking for a more complete example? Look no further! This HTML example has a form input
|
||||
where the user can paste a magnet link and start a download over WebTorrent.
|
||||
|
||||
Best of all, it's a single HTML page, under 70 lines!
|
||||
|
||||
If the torrent contains images, videos, audio, or other playable files (with supported
|
||||
codecs), they will be added to the DOM and streamed, even before the full content is
|
||||
downloaded.
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<h1>
|
||||
Download files using the WebTorrent protocol (BitTorrent over WebRTC).
|
||||
</h1>
|
||||
|
||||
<form>
|
||||
<label for="torrentId">Download from a magnet link: </label>
|
||||
<input
|
||||
name="torrentId"
|
||||
,
|
||||
placeholder="magnet:"
|
||||
value="magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10&dn=Sintel&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fsintel.torrent"
|
||||
/>
|
||||
<button type="submit">Download</button>
|
||||
</form>
|
||||
|
||||
<h2>Log</h2>
|
||||
<div class="log"></div>
|
||||
|
||||
<script type="module">
|
||||
// Include the latest version of WebTorrent
|
||||
import WebTorrent from "https://esm.sh/webtorrent";
|
||||
|
||||
const client = new WebTorrent();
|
||||
|
||||
client.on("error", (err) => {
|
||||
console.error("ERROR: " + err.message);
|
||||
});
|
||||
|
||||
document.querySelector("form").addEventListener("submit", (e) => {
|
||||
e.preventDefault(); // Prevent page refresh
|
||||
|
||||
const torrentId = document.querySelector(
|
||||
"form input[name=torrentId]"
|
||||
).value;
|
||||
log("Adding " + torrentId);
|
||||
client.add(torrentId, onTorrent);
|
||||
});
|
||||
|
||||
async function onTorrent(torrent) {
|
||||
log("Got torrent metadata!");
|
||||
log(
|
||||
"Torrent info hash: " +
|
||||
torrent.infoHash +
|
||||
" " +
|
||||
'<a href="' +
|
||||
torrent.magnetURI +
|
||||
'" target="_blank">[Magnet URI]</a> ' +
|
||||
'<a href="' +
|
||||
URL.createObjectURL(torrent.torrentFileBlob) +
|
||||
'" target="_blank" download="' +
|
||||
torrent.name +
|
||||
'.torrent">[Download .torrent]</a>'
|
||||
);
|
||||
|
||||
// Print out progress every 5 seconds
|
||||
const interval = setInterval(() => {
|
||||
log("Progress: " + (torrent.progress * 100).toFixed(1) + "%");
|
||||
}, 5000);
|
||||
|
||||
torrent.on("done", () => {
|
||||
log("Progress: 100%");
|
||||
clearInterval(interval);
|
||||
});
|
||||
|
||||
// Render all files into to the page
|
||||
for (const file of torrent.files) {
|
||||
try {
|
||||
const blob = await file.blob();
|
||||
document.querySelector(".log").append(file.name);
|
||||
log(
|
||||
'(Blob URLs only work if the file is loaded from a server. "http//localhost" works. "file://" does not.)'
|
||||
);
|
||||
log("File done.");
|
||||
log(
|
||||
'<a href="' +
|
||||
URL.createObjectURL(blob) +
|
||||
'">Download full file: ' +
|
||||
file.name +
|
||||
"</a>"
|
||||
);
|
||||
} catch (err) {
|
||||
if (err) log(err.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function log(str) {
|
||||
const p = document.createElement("p");
|
||||
p.innerHTML = str;
|
||||
document.querySelector(".log").appendChild(p);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
### HTML example with status showing UI
|
||||
|
||||
This complete HTML example mimics the UI of the
|
||||
[webtorrent.io](https://webtorrent.io) homepage. It downloads the
|
||||
[sintel.torrent](https://webtorrent.io/torrents/sintel.torrent) file, streams it in
|
||||
the browser and outputs some statistics to the user (peers, progress, remaining
|
||||
time, speed...).
|
||||
|
||||
You can try it right now on [CodePen](http://codepen.io/yciabaud/full/XdOeWM/) to
|
||||
see what it looks like and play around with it!
|
||||
|
||||
Feel free to replace `torrentId` with other torrent files, or magnet links, but
|
||||
keep in mind that the browser can only download torrents that are seeded by
|
||||
WebRTC peers (web peers). Use [WebTorrent Desktop](https://webtorrent.io/desktop)
|
||||
or [Instant.io](https://instant.io) to seed torrents to the WebTorrent network.
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>WebTorrent video player</title>
|
||||
<style>
|
||||
#output video {
|
||||
width: 100%;
|
||||
}
|
||||
#progressBar {
|
||||
height: 5px;
|
||||
width: 0%;
|
||||
background-color: #35b44f;
|
||||
transition: width 0.4s ease-in-out;
|
||||
}
|
||||
body.is-seed .show-seed {
|
||||
display: inline;
|
||||
}
|
||||
body.is-seed .show-leech {
|
||||
display: none;
|
||||
}
|
||||
.show-seed {
|
||||
display: none;
|
||||
}
|
||||
#status code {
|
||||
font-size: 90%;
|
||||
font-weight: 700;
|
||||
margin-left: 3px;
|
||||
margin-right: 3px;
|
||||
border-bottom: 1px dashed rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.is-seed {
|
||||
background-color: #154820;
|
||||
transition: 0.5s 0.5s background-color ease-in-out;
|
||||
}
|
||||
body {
|
||||
background-color: #2a3749;
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
}
|
||||
#status {
|
||||
color: #fff;
|
||||
font-size: 17px;
|
||||
padding: 5px;
|
||||
}
|
||||
a:link,
|
||||
a:visited {
|
||||
color: #30a247;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<div id="progressBar"></div>
|
||||
<video id="output" controls></video>
|
||||
</div>
|
||||
<!-- Statistics -->
|
||||
<div id="status">
|
||||
<div>
|
||||
<span class="show-leech">Downloading </span>
|
||||
<span class="show-seed">Seeding </span>
|
||||
<code>
|
||||
<!-- Informative link to the torrent file -->
|
||||
<a
|
||||
id="torrentLink"
|
||||
href="https://webtorrent.io/torrents/sintel.torrent"
|
||||
>sintel.torrent</a
|
||||
>
|
||||
</code>
|
||||
<span class="show-leech"> from </span>
|
||||
<span class="show-seed"> to </span>
|
||||
<code id="numPeers">0 peers</code>.
|
||||
</div>
|
||||
<div>
|
||||
<code id="downloaded"></code>
|
||||
of <code id="total"></code> — <span id="remaining"></span><br />
|
||||
↘<code id="downloadSpeed">0 b/s</code> / ↗<code
|
||||
id="uploadSpeed"
|
||||
>0 b/s</code
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Moment is used to show a human-readable remaining time -->
|
||||
<script src="http://momentjs.com/downloads/moment.min.js"></script>
|
||||
|
||||
<script type="module">
|
||||
// Include the latest version of WebTorrent
|
||||
import WebTorrent from "./webtorrent.min.js";
|
||||
|
||||
const torrentId = "https://webtorrent.io/torrents/sintel.torrent";
|
||||
|
||||
const client = new WebTorrent();
|
||||
|
||||
// HTML elements
|
||||
const $body = document.body;
|
||||
const $progressBar = document.querySelector("#progressBar");
|
||||
const $numPeers = document.querySelector("#numPeers");
|
||||
const $downloaded = document.querySelector("#downloaded");
|
||||
const $total = document.querySelector("#total");
|
||||
const $remaining = document.querySelector("#remaining");
|
||||
const $uploadSpeed = document.querySelector("#uploadSpeed");
|
||||
const $downloadSpeed = document.querySelector("#downloadSpeed");
|
||||
|
||||
navigator.serviceWorker
|
||||
.register("./sw.min.js", { scope: "./" })
|
||||
.then((reg) => {
|
||||
const worker = reg.active || reg.waiting || reg.installing;
|
||||
function checkState(worker) {
|
||||
return (
|
||||
worker.state === "activated" &&
|
||||
client.createServer({ controller: reg }) &&
|
||||
download()
|
||||
);
|
||||
}
|
||||
if (!checkState(worker)) {
|
||||
worker.addEventListener("statechange", ({ target }) =>
|
||||
checkState(target)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
function download() {
|
||||
// Download the torrent
|
||||
client.add(torrentId, (torrent) => {
|
||||
// Torrents can contain many files. Let's use the .mp4 file
|
||||
const file = torrent.files.find((file) => {
|
||||
return file.name.endsWith(".mp4");
|
||||
});
|
||||
|
||||
// Stream the file in the browser
|
||||
file.streamTo(document.querySelector("#output"));
|
||||
|
||||
// Trigger statistics refresh
|
||||
torrent.on("done", onDone);
|
||||
setInterval(onProgress, 500);
|
||||
onProgress();
|
||||
|
||||
// Statistics
|
||||
function onProgress() {
|
||||
// Peers
|
||||
$numPeers.innerHTML =
|
||||
torrent.numPeers + (torrent.numPeers === 1 ? " peer" : " peers");
|
||||
|
||||
// Progress
|
||||
const percent = Math.round(torrent.progress * 100 * 100) / 100;
|
||||
$progressBar.style.width = percent + "%";
|
||||
$downloaded.innerHTML = prettyBytes(torrent.downloaded);
|
||||
$total.innerHTML = prettyBytes(torrent.length);
|
||||
|
||||
// Remaining time
|
||||
let remaining;
|
||||
if (torrent.done) {
|
||||
remaining = "Done.";
|
||||
} else {
|
||||
remaining = moment
|
||||
.duration(torrent.timeRemaining / 1000, "seconds")
|
||||
.humanize();
|
||||
remaining =
|
||||
remaining[0].toUpperCase() +
|
||||
remaining.substring(1) +
|
||||
" remaining.";
|
||||
}
|
||||
$remaining.innerHTML = remaining;
|
||||
|
||||
// Speed rates
|
||||
$downloadSpeed.innerHTML =
|
||||
prettyBytes(torrent.downloadSpeed) + "/s";
|
||||
$uploadSpeed.innerHTML = prettyBytes(torrent.uploadSpeed) + "/s";
|
||||
}
|
||||
function onDone() {
|
||||
$body.className += " is-seed";
|
||||
onProgress();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Human readable bytes util
|
||||
function prettyBytes(num) {
|
||||
const units = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
||||
const neg = num < 0;
|
||||
if (neg) num = -num;
|
||||
if (num < 1) return (neg ? "-" : "") + num + " B";
|
||||
const exponent = Math.min(
|
||||
Math.floor(Math.log(num) / Math.log(1000)),
|
||||
units.length - 1
|
||||
);
|
||||
const unit = units[exponent];
|
||||
num = Number((num / Math.pow(1000, exponent)).toFixed(2));
|
||||
return (neg ? "-" : "") + num + " " + unit;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
## More Documentation
|
||||
|
||||
Check out the [API Documentation](//webtorrent.io/docs) and [FAQ](//webtorrent.io/faq) for more details.
|
||||
|
||||
[drag-drop]: https://npmjs.com/package/drag-drop
|
Reference in New Issue
Block a user