PageSourceSearch

https://webtorrent.io/intro

html webtorrent.io collected 2026-10-01 10:31:49 UTC 44,505 bytes, 364 lines download raw bytes

1<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>WebTorrent Tutorial - Get Started</title><meta property="og:title" content="WebTorrent Tutorial - Get Started"><meta name="description" content="WebTorrent, the streaming torrent client for the browser, Mac, Windows, and Linux"><meta property="og:description" content="WebTorrent, the streaming torrent client for the browser, Mac, Windows, and Linux"><meta property="og:type" content="website"><meta property="og:image" content="/img/WebTorrent.png"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon-76x76.png"><link rel="apple-touch-icon" sizes="120x120" href="/apple-touch-icon-120x120.png"><link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152x152.png"><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180x180.png"><link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32"><link rel="icon" type="image/png" href="/android-chrome-192x192.png" sizes="192x192"><link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96"><link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16"><link rel="manifest" href="/manifest.json"><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5"><meta name="msapplication-TileColor" content="#b91d47"><meta name="msapplication-TileImage" content="/mstile-144x144.png"><meta name="theme-color" content="#ffffff"><link rel="stylesheet" href="/style.css" charset="utf-8"><link rel="stylesheet" href="//fonts.googleapis.com/css?family=Asap:400,700"><link rel="stylesheet" href="//fonts.googleapis.com/css?family=Source+Sans+Pro:400,700,400italic,700italic"><link rel="stylesheet" href="//fonts.googleapis.com/css?family=Source+Code+Pro:400,700"></head><body><div class="headerWrap"><header class="header"><h1><a href="/">WebTorrent</a></h1><nav><a href="/intro">Get Started</a><a href="/docs">Docs</a><a href="/faq">FAQ</a><a class="new-release" href="/desktop">WebTorrent Desktop</a><a href="https://instant.io" target="_blank">Instant.io</a><a class="btn" href="https://github.com/webtorrent/webtorrent" target="_blank">GitHub</a></nav></header></div><main><article><h1>Get Started with WebTorrent</h1>
2<p><strong>WebTorrent</strong> is the first torrent client that works in the <strong>browser</strong>. It's easy
3to get started!</p>
4<h2>Install</h2>
5<p>To start using WebTorrent, simply include the
6<a href="https://esm.sh/webtorrent"><code>webtorrent</code></a>
7script on your page.</p>
8<pre><code class="language-html"><div class="hljs"><span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&#x27;module&#x27;</span>&gt;</span><span class="language-javascript">
9  <span class="hljs-keyword">import</span> <span class="hljs-title class_">WebTorrent</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;https://esm.sh/webtorrent&#x27;</span>
10</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
11</div></code></pre>
12<h3>Browserify and Webpack</h3>
13<p>WebTorrent also works great with <a href="http://browserify.org/">browserify</a>, <a href="https://webpack.js.org/">webpack</a> and other bundlers, which let
14you use <a href="http://nodejs.org/">node.js</a> style <code>require()</code> to organize your browser
15code, and load packages installed by <a href="https://npmjs.org/">npm</a>.</p>
16<p>For an example webpack config see <a href="/scripts/browser.webpack.js">the webpack bundle config used by webtorrent</a>.</p>
17<pre><code><div class="hljs">npm <span class="hljs-keyword">install</span> webtorrent
18</div></code></pre>
19<p>Then use <code>WebTorrent</code> like this:</p>
20<pre><code class="language-js"><div class="hljs"><span class="hljs-keyword">import</span> <span class="hljs-title class_">WebTorrent</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;webtorrent&#x27;</span>
21</div></code></pre>
22<h2>Quick Examples</h2>
23<h3>Downloading a torrent (in the browser)</h3>
24<pre><code class="language-js"><div class="hljs"><span class="hljs-keyword">
24import</span> <span class="hljs-title class_">WebTorrent</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;webtorrent&#x27;</span>
25
26<span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> <span class="hljs-title class_">WebTorrent</span>()
27
28<span class="hljs-comment">// Sintel, a free, Creative Commons movie</span>
29<span class="hljs-keyword">const</span> torrentId = <span class="hljs-string">&#x27;magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10&amp;dn=Sintel&amp;tr=udp%3A%2F%2Fexplodie.org%3A6969&amp;tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&amp;tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&amp;tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&amp;tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&amp;tr=wss%3A%2F%2Ftracker.btorrent.xyz&amp;tr=wss%3A%2F%2Ftracker.fastcast.nz&amp;tr=wss%3A%2F%2Ftracker.openwebtorrent.com&amp;ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&amp;xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fsintel.torrent&#x27;</span>
30
31<span class="hljs-comment">// see tutorials.md for a full example of streaming media using service workers</span>
32navigator.<span class="hljs-property">serviceWorker</span>.<span class="hljs-title function_">register</span>(<span class="hljs-string">&#x27;sw.min.js&#x27;</span>)
33<span class="hljs-keyword">const</span> controller = <span class="hljs-keyword">await</span> navigator.<span class="hljs-property">serviceWorker</span>.<span class="hljs-property">ready</span>
34client.<span class="hljs-title function_">createServer</span>({ controller })
35
36client.<span class="hljs-title function_">add</span>(torrentId, <span class="hljs-function"><span class="hljs-params">torrent</span> =&gt;</span> {
37  <span class="hljs-comment">// Torrents can contain many files. Let&#x27;s use the .mp4 file</span>
38  <span class="hljs-keyword">const</span> file = torrent.<span class="hljs-property">files</span>.<span class="hljs-title function_">find</span>(<span class="hljs-function"><span class="hljs-params">file</span> =&gt;</span> {
39    <span class="hljs-keyword">return</span> file.<span class="hljs-property">name</span>.<span class="hljs-title function_">endsWith</span>(<span class="hljs-string">&#x27;.mp4&#x27;</span>)
40  })
41
42  <span class="hljs-comment">// Display the file by adding it to the DOM.</span>
43  <span class="hljs-comment">// Supports video, audio, image files, and more!</span>
44  file.<span class="hljs-title function_">streamTo</span>(<span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">&#x27;video&#x27;</span>))
45})
46</div></code></pre>
47<p>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.</p>
48<p>Video and audio content can be streamed, i.e. playback will start before the full file is downloaded. Seeking works too – WebTorrent dynamically fetches
49the needed torrent pieces from the network on-demand.</p>
50<p><strong>Note:</strong> Downloading a torrent automatically seeds it, making it available for download by other peers.</p>
51<h3>Creating a new torrent and seed it (in the browser)</h3>
52<pre><code class="language-js"><div class="hljs"><span class="hljs-keyword">import</span> dragDrop <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;drag-drop&#x27;</span>
53<span class="hljs-keyword">import</span> <span class="hljs-title class_">WebTorrent</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;webtorrent&#x27;</span>
54
55<span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> <span class="hljs-title class_">WebTorrent</span>()
56
57<span class="hljs-comment">// When user drops files on the browser, create a new torrent and start seeding it!</span>
58<span class="hljs-title function_">dragDrop</span>(<span class="hljs-string">&#x27;body&#x27;</span>, <span class="hljs-function"><span class="hljs-params">files</span> =&gt;</span> {
59  client.<span class="hljs-title function_">seed</span>
59(files, <span class="hljs-function"><span class="hljs-params">torrent</span> =&gt;</span> {
60    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;Client is seeding &#x27;</span> + torrent.<span class="hljs-property">magnetURI</span>)
61  })
62})
63</div></code></pre>
64<p>This example uses the <a href="https://npmjs.com/package/drag-drop"><code>drag-drop</code></a> package, to make the HTML5 Drag and
65Drop API easier to work with.</p>
66<p><strong>Note:</strong> If you do not use browserify, use the standalone file
67<a href="https://bundle.run/drag-drop"><code>dragdrop.min.js</code></a>.
68This exports a <code>DragDrop</code> function on <code>window</code>.</p>
69<h3>Download and save a torrent (in Node.js)</h3>
70<pre><code class="language-js"><div class="hljs"><span class="hljs-keyword">import</span> <span class="hljs-title class_">WebTorrent</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;webtorrent&#x27;</span>
71
72<span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> <span class="hljs-title class_">WebTorrent</span>()
73
74<span class="hljs-keyword">const</span> magnetURI = <span class="hljs-string">&#x27;magnet: ...&#x27;</span>
75
76client.<span class="hljs-title function_">add</span>(magnetURI, { <span class="hljs-attr">path</span>: <span class="hljs-string">&#x27;/path/to/folder&#x27;</span> }, <span class="hljs-function"><span class="hljs-params">torrent</span> =&gt;</span> {
77  torrent.<span class="hljs-title function_">on</span>(<span class="hljs-string">&#x27;done&#x27;</span>, <span class="hljs-function">() =&gt;</span> {
78    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;torrent download finished&#x27;</span>)
79  })
80})
81</div></code></pre>
82<h3>Creating a new torrent and seed it (in Node.js)</h3>
83<p><strong>Note:</strong> Seeding a torrent that can be downloaded by browser peers (i.e. with support for WebRTC) requires <a href="https://github.com/webtorrent/webtorrent-hybrid">webtorrent-hybrid</a>.</p>
84<pre><code class="language-js"><div class="hljs"><span class="hljs-keyword">import</span> <span class="hljs-title class_">WebTorrent</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;webtorrent-hybrid&#x27;</span>
85<span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> <span class="hljs-title class_">WebTorrent</span>()
86
87client.<span class="hljs-title function_">seed</span>(<span class="hljs-string">&#x27;/seed-me.txt&#x27;</span>, <span class="hljs-function"><span class="hljs-params">torrent</span> =&gt;</span> {
88    <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;Client is seeding &#x27;</span> + torrent.<span class="hljs-property">magnetURI</span>)
89})
90</div></code></pre>
91<p>where <strong>seed-me.txt</strong> is a text file which is going to be seeded as a torrent.</p>
92<h3>Complete HTML page example</h3>
93<p>Looking for a more complete example? Look no further! This HTML example has a form input
94where the user can paste a magnet link and start a download over WebTorrent.</p>
95<p>Best of all, it's a single HTML page, under 70 lines!</p>
96<p>If the torrent contains images, videos, audio, or other playable files (with supported
97codecs), they will be added to the DOM and streamed, even before the full content is
98downloaded.</p>
99<pre><code class="language-html"><div class="hljs"><span class="hljs-meta">&lt;!doctype <span class="hljs-keyword">html</span>&gt;</span>
100<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
101  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
102    <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Download files using the WebTorrent protocol (BitTorrent over WebRTC).<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
103
104    <span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
105      <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">&quot;torrentId&quot;</span>&gt;</span>Download from a magnet link: <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
106      <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">name</span>=<span class="hljs-string">&quot;torrentId&quot;</span>, <span class="hljs-attr">placeholder</span>=<span class="hljs-string">&quot;magnet:&quot;</span> <span class="hljs-attr">value</span>=<span class="hljs-string">&quot;magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10&amp;dn=Sintel&amp;tr=udp%3A%2F%2Fexplodie.org%3A6969&amp;tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&amp;tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&amp;tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&amp;tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&amp;tr=wss%3A%2F%2Ftracker.btorrent.xyz&amp;tr=wss%3A%2F%2Ftracker.fastcast.nz&amp;tr=wss%3A%2F%2Ftracker.openwebtorrent.com&amp;ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&amp;xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fsintel.torrent&quot;</span>&gt;</span>
107      <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;submit&quot;</span>&gt;</span>Download<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
108    <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
109
110    <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Log<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
111    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;log&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
112
113    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&#x27;module&#x27;</span>&gt;</span><span class="language-javascript">
114      <span class="hljs-comment">// Include the latest version of WebTorrent</span>
115      <span class="hljs-keyword">import</span> <span class="hljs-title class_">WebTorrent</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;https://esm.sh/webtorrent&#x27;</span>
116      
117      <span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> <span class="hljs-title class_">WebTorrent</span>()
118
119      client.<span class="hljs-title function_">on</span>(<span class="hljs-string">&#x27;error&#x27;</span>, <span class="hljs-function"><span class="hljs-params">err</span> =&gt;</span> {
120        <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">&#x27;ERROR: &#x27;</span> + err.<span class="hljs-property">message</span>)
121      })
122
123      <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">&#x27;form&#x27;</span>).<span class="hljs-title function_">addEventListener</span>(<span class="hljs-string">&#x27;submit&#x27;</span>, <span class="hljs-function"><span class="hljs-params">e</span> =&gt;</span> {
124        e.<span class="hljs-title function_">preventDefault</span>() <span class="hljs-comment">// Prevent page refresh</span>
125
126        <span class="hljs-keyword">const</span> torrentId = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">&#x27;form input[name=torrentId]&#x27;</span>).<span class="hljs-property">value</span>
127        <span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;Adding &#x27;</span> + torrentId)
128        client.<span class="hljs-title function_">add</span>(torrentId, onTorrent)
129      })
130
131      <span class="hljs-keyword">async</span> <span class="hljs-keyword">function</span> <span class="hljs-title function_">onTorrent</span> (torrent) {
132        <span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;Got torrent metadata!&#x27;</span>)
133        <span class="hljs-title function_">log</span>(
134          <span class="hljs-string">&#x27;Torrent info hash: &#x27;</span> + torrent.<span class="hljs-property">infoHash</span> + <span class="hljs-string">&#x27; &#x27;</span> +
135          <span class="hljs-string">&#x27;&lt;a href=&quot;&#x27;</span> + torrent.<span class="hljs-property">magnetURI</span> + <span class="hljs-string">&#x27;&quot; target=&quot;_blank&quot;&gt;[Magnet URI]&lt;/a&gt; &#x27;</span> +
136          <span class="hljs-string">&#x27;&lt;a href=&quot;&#x27;</span> + <span class="hljs-variable constant_">URL</span>.<span class="hljs-title function_">createObjectURL</span>(torrent.<span class="hljs-property">torrentFileBlob</span>) + <span class="hljs-string">&#x27;&quot; target=&quot;_blank&quot; download=&quot;&#x27;</span> + torrent.<span class="hljs-property">name</span> + <span class="hljs-string">&#x27;.torrent&quot;&gt;[Download .torrent]&lt;/a&gt;&#x27;</span>
137        )
138
139        <span class="hljs-comment">// Print out progress every 5 seconds</span>
140        <span class="hljs-keyword">const</span> interval = <span class="hljs-built_in">setInterval</span>(<span class="hljs-function">() =&gt;</span> {
141          <span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;Progress: &#x27;</span> + (torrent.<span class="hljs-property">progress</span> * <span class="hljs-number">100</span>).<span class="hljs-title function_">toFixed</span>(<span class="hljs-number">1</span>) + <span class="hljs-string">&#x27;%&#x27;</span>)
142        }, <span class="hljs-number">5000</span>)
143
144        torrent.<span class="hljs-title function_">on</span>(<span class="hljs-string">&#x27;done&#x27;</span>, <span class="hljs-function">() =&gt;</span> {
145          <span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;Progress: 100%&#x27;</span>)
146          <span class="hljs-built_in">clearInterval</span>(interval)
147        })
148
149        <span class="hljs-comment">// Render all files into to the page</span>
150        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> file <span class="hljs-keyword">of</span> torrent.<span class="hljs-property">files</span>) {
151          <span class="hljs-keyword">try</span> {
152            <span class="hljs-keyword">const</span> blob = <span class="hljs-keyword">await</span> file.<span class="hljs-title function_">blob</span>()
153            <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">&#x27;.log&#x27;</span>).<span class="hljs-title function_">append</span>(file.<span class="hljs-property">name</span>)
154            <span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;(Blob URLs only work if the file is loaded from a server. &quot;http//localhost&quot; works. &quot;file://&quot; does not.)&#x27;</span>)
155            <span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;File done.&#x27;</span>)
156            <span class="hljs-title function_">log</span>(<span class="hljs-string">&#x27;&lt;a href=&quot;&#x27;</span> + <span class="hljs-variable constant_">URL</span>.<span class="hljs-title function_">createObjectURL</span>(blob) + <span class="hljs-string">&#x27;&quot;&gt;Download full file: &#x27;</span> + file.<span class="hljs-property">name</span> + <span class="hljs-string">&#x27;&lt;/a&gt;&#x27;</span>)
157          } <span class="hljs-keyword">catch</span> (err) {
158            <span class="hljs-keyword">if</span> (err) <span class="hljs-title function_">log</span>(err.<span class="hljs-property">message</span>)
159          }
160        }
161      }
162
163      <span class="hljs-keyword">function</span> <span class="hljs-title function_">log</span> (str) {
164        <span class="hljs-keyword">const</span> p = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">createElement</span>(<span class="hljs-string">&#x27;p&#x27;</span>)
165        p.<span class="hljs-property">innerHTML</span> = str
166        <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">&#x27;.log&#x27;</span>).<span class="hljs-title function_">appendChild</span>(p)
167      }
168    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
169  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
170<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
171</div></code></pre>
172<h3>HTML example with status showing UI</h3>
173<p>This complete HTML example mimics the UI of the
174<a href="https://webtorrent.io">webtorrent.io</a> homepage. It downloads the
175<a href="https://webtorrent.io/torrents/sintel.torrent">sintel.torrent</a> file, streams it in
176the browser and outputs some statistics to the user (peers, progress, remaining
177time, speed...).</p>
178<p>You can try it right now on <a href="http://codepen.io/yciabaud/full/XdOeWM/">CodePen</a> to
179see what it looks like and play around with it!</p>
180<p>Feel free to replace <code>torrentId</code> with other torrent files, or magnet links, but
181keep in mind that the browser can only download torrents that are seeded by
182WebRTC peers (web peers). Use <a href="https://webtorrent.io/desktop">WebTorrent Desktop</a>
183or <a href="https://instant.io">Instant.io</a> to seed torrents to the WebTorrent network.</p>
184<pre><code class="language-html"><div class="hljs"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-keyword">html</span>&gt;</span>
185<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
186  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
187    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">&quot;UTF-8&quot;</span>&gt;</span>
188    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>WebTorrent video player<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
189    <span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="language-css">
190      <span class="hljs-selector-id">#output</span> <span class="hljs-selector-tag">video</span> {
191        <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
192      }
193      <span class="hljs-selector-id">#progressBar</span> {
194        <span class="hljs-attribute">height</span>: <span class="hljs-number">5px</span>;
195        <span class="hljs-attribute">width</span>: <span class="hljs-number">0%</span>;
196        <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#35b44f</span>;
197        <span class="hljs-attribute">transition</span>: width .<span class="hljs-number">4s</span> ease-in-out;
198      }
199      <span class="hljs-selector-tag">body</span><span class="hljs-selector-class">.is-seed</span> <span class="hljs-selector-class">.show-seed</span> {
200        <span class="hljs-attribute">display</span>: inline;
201      }
202      <span class="hljs-selector-tag">body</span><span class="hljs-selector-class">.is-seed</span> <span class="hljs-selector-class">.show-leech</span> {
203        <span class="hljs-attribute">display</span>: none;
204      }
205      <span class="hljs-selector-class">.show-seed</span> {
206        <span class="hljs-attribute">display</span>: none;
207      }
208      <span class="hljs-selector-id">#status</span> <span class="hljs-selector-tag">code</span> {
209        <span class="hljs-attribute">font-size</span>: <span class="hljs-number">90%</span>;
210        <span class="hljs-attribute">font-weight</span>: <span class="hljs-number">700</span>;
211        <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">3px</span>;
212        <span class="hljs-attribute">margin-right</span>: <span class="hljs-number">3px</span>;
213        <span class="hljs-attribute">border-bottom</span>: <span class="hljs-number">1px</span> dashed <span class="hljs-built_in">rgba</span>(<span class="hljs-number">255</span>,<span class="hljs-number">255</span>,<span class="hljs-number">255</span>,<span class="hljs-number">0.3</span>);
214      }
215
216      <span class="hljs-selector-class">.is-seed</span> {
217        <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#154820</span>;
218        <span class="hljs-attribute">transition</span>: .<span class="hljs-number">5s</span> .<span class="hljs-number">5s</span> background-color ease-in-out;
219      }
220      <span class="hljs-selector-tag">body</span> {
221        <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#2a3749</span>;
222        <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
223        <span class="hljs-attribute">height</span>: <span class="hljs-number">100%</span>;
224      }
225      <span class="hljs-selector-id">#status</span> {
226        <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;
227        <span class="hljs-attribute">font-size</span>: <span class="hljs-number">17px</span>;
228        <span class="hljs-attribute">padding</span>: <span class="hljs-number">5px</span>;
229      }
230      <span class="hljs-selector-tag">a</span><span class="hljs-selector-pseudo">:link</span>, <span class="hljs-selector-tag">a</span><span class="hljs-selector-pseudo">:visited</span> {
231        <span class="hljs-attribute">color</span>: <span class="hljs-number">#30a247</span>;
232        <span class="hljs-attribute">text-decoration</span>: none;
233      }
234    </span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
235  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
236  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
237    <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
238      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;progressBar&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
239      <span class="hljs-tag">&lt;<span class="hljs-name">video</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;output&quot;</span> <span class="hljs-attr">controls</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">video</span>&gt;</span>
240    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
241    <span class="hljs-comment">&lt;!-- Statistics --&gt;</span>
242    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;status&quot;</span>&gt;</span>
243      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
244        <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;show-leech&quot;</span>&gt;</span>Downloading <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
245        <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;show-seed&quot;</span>&gt;</span>Seeding <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
246        <span class="hljs-tag">&lt;<span class="hljs-name">code</span>&gt;</span>
247          <span class="hljs-comment">&lt;!-- Informative link to the torrent file --&gt;</span>
248          <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;torrentLink&quot;</span> <span class="hljs-attr">href</span>=<span class="hljs-string">&quot;https://webtorrent.io/torrents/sintel.torrent&quot;</span>&gt;</span>sintel.torrent<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
249        <span class="hljs-tag">&lt;/<span class="hljs-name">code</span>&gt;</span>
250        <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;show-leech&quot;</span>&gt;</span> from <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
251        <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;show-seed&quot;</span>&gt;</span> to <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
252        <span class="hljs-tag">&lt;<span class="hljs-name">code</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;numPeers&quot;</span>&gt;</span>0 peers<span class="hljs-tag">&lt;/<span class="hljs-name">code</span>&gt;</span>.
253      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
254      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
255        <span class="hljs-tag">&lt;<span class="hljs-name">code</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;downloaded&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">code</span>&gt;</span>
256        of <span class="hljs-tag">&lt;<span class="hljs-name">code</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;total&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">code</span>&gt;</span>
257        — <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;remaining&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>/&gt;</span>
258        <span class="hljs-symbol">&amp;#x2198;</span><span class="hljs-tag">&lt;<span class="hljs-name">code</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;downloadSpeed&quot;</span>&gt;</span>0 b/s<span class="hljs-tag">&lt;/<span class="hljs-name">code</span>&gt;</span>
259        / <span class="hljs-symbol">&amp;#x2197;</span><span class="hljs-tag">&lt;<span class="hljs-name">code</span> <span class="hljs-attr">id</span>=<span class="hljs-string">&quot;uploadSpeed&quot;</span>&gt;</span>0 b/s<span class="hljs-tag">&lt;/<span class="hljs-name">code</span>&gt;</span>
260      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
261    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
262    
263    <span class="hljs-comment">&lt;!-- Moment is used to show a human-readable remaining time --&gt;</span>
264    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;http://momentjs.com/downloads/moment.min.js&quot;</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
265
266    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">&quot;module&quot;</span>&gt;</span><span class="language-javascript">
267      <span class="hljs-comment">// Include the latest version of WebTorrent</span>
268      <span class="hljs-keyword">import</span> <span class="hljs-title class_">WebTorrent</span> <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;./webtorrent.min.js&#x27;</span>
269
270      <span class="hljs-keyword">const</span> torrentId = <span class="hljs-string">&#x27;https://webtorrent.io/torrents/sintel.torrent&#x27;</span>
271
272      <span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> <span class="hljs-title class_">WebTorrent</span>()
273
274      <span class="hljs-comment">// HTML elements</span>
275      <span class="hljs-keyword">const</span> $body = <span class="hljs-variable language_">document</span>.<span class="hljs-property">body</span>
276      <span class="hljs-keyword">const</span> $progressBar = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">&#x27;#progressBar&#x27;</span>)
277      <span class="hljs-keyword">const</span> $numPeers = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">&#x27;#numPeers&#x27;</span>)
278      <span class="hljs-keyword">const</span> $downloaded = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">&#x27;#downloaded&#x27;</span>)
279      <span class="hljs-keyword">const</span> $total = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">&#x27;#total&#x27;</span>)
280      <span class="hljs-keyword">const</span> $remaining = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">&#x27;#remaining&#x27;</span>)
281      <span class="hljs-keyword">const</span> $uploadSpeed = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">&#x27;#uploadSpeed&#x27;</span>)
282      <span class="hljs-keyword">const</span> $downloadSpeed = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">&#x27;#downloadSpeed&#x27;</span>)
283
284      navigator.<span class="hljs-property">serviceWorker</span>.<span class="hljs-title function_">register</span>(<span class="hljs-string">&#x27;./sw.min.js&#x27;</span>, { <span class="hljs-attr">scope</span>: <span class="hljs-string">&#x27;./&#x27;</span> }).<span class="hljs-title function_">then</span>(<span class="hljs-function"><span class="hljs-params">reg</span> =&gt;</span> {
285        <span class="hljs-keyword">const</span> worker = reg.<span class="hljs-property">active</span> || reg.<span class="hljs-property">waiting</span> || reg.<span class="hljs-property">installing</span>
286        <span class="hljs-keyword">function</span> <span class="hljs-title function_">checkState</span> (worker) {
287          <span class="hljs-keyword">return</span> worker.<span class="hljs-property">state</span> === <span class="hljs-string">&#x27;activated&#x27;</span> &amp;&amp; client.<span class="hljs-title function_">createServer</span>({ <span class="hljs-attr">controller</span>: reg }) &amp;&amp; <span class="hljs-title function_">download</span>()
288        }
289        <span class="hljs-keyword">if</span> (!<span class="hljs-title function_">checkState</span>(worker)) {
290          worker.<span class="hljs-title function_">addEventListener</span>(<span class="hljs-string">&#x27;statechange&#x27;</span>, <span class="hljs-function">(<span class="hljs-params">{ target }</span>) =&gt;</span> <span class="hljs-title function_">checkState</span>(target))
291        }
292      })
293
294      <span class="hljs-keyword">function</span> <span class="hljs-title function_">download</span> () {
295        <span class="hljs-comment">// Download the torrent</span>
296        client.<span class="hljs-title function_">add</span>(torrentId, <span class="hljs-function"><span class="hljs-params">torrent</span> =&gt;</span> {
297          <span class="hljs-comment">// Torrents can contain many files. Let&#x27;s use the .mp4 file</span>
298          <span class="hljs-keyword">const</span> file = torrent.<span class="hljs-property">files</span>.<span class="hljs-title function_">find</span>(<span class="hljs-function"><span class="hljs-params">file</span> =&gt;</span> {
299            <span class="hljs-keyword">return</span> file.<span class="hljs-property">name</span>.<span class="hljs-title function_">endsWith</span>(<span class="hljs-string">&#x27;.mp4&#x27;</span>)
300          })
301
302          <span class="hljs-comment">// Stream the file in the browser</span>
303          file.<span class="hljs-title function_">streamTo</span>(<span class="hljs-variable language_">document</span>.<span class="hljs-title function_">querySelector</span>(<span class="hljs-string">&#x27;#output&#x27;</span>))
304
305          <span class="hljs-comment">// Trigger statistics refresh</span>
306          torrent.<span class="hljs-title function_">on</span>(<span class="hljs-string">&#x27;done&#x27;</span>, onDone)
307          <span class="hljs-built_in">setInterval</span>(onProgress, <span class="hljs-number">500</span>)
308          <span class="hljs-title function_">onProgress</span>()
309
310          <span class="hljs-comment">// Statistics</span>
311          <span class="hljs-keyword">function</span> <span class="hljs-title function_">onProgress</span> () {
312          <span class="hljs-comment">// Peers</span>
313            $numPeers.<span class="hljs-property">innerHTML</span> = torrent.<span class="hljs-property">numPeers</span> + (torrent.<span class="hljs-property">numPeers</span> === <span class="hljs-number">1</span> ? <span class="hljs-string">&#x27; peer&#x27;</span> : <span class="hljs-string">&#x27; peers&#x27;</span>)
314
315            <span class="hljs-comment">// Progress</span>
316            <span class="hljs-keyword">const</span> percent = <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">round</span>(torrent.<span class="hljs-property">progress</span> * <span class="hljs-number">100</span> * <span class="hljs-number">100</span>) / <span class="hljs-number">100</span>
317            $progressBar.<span class="hljs-property">style</span>.<span class="hljs-property">width</span> = percent + <span class="hljs-string">&#x27;%&#x27;</span>
318            $downloaded.<span class="hljs-property">innerHTML</span> = <span class="hljs-title function_">prettyBytes</span>(torrent.<span class="hljs-property">downloaded</span>)
319            $total.<span class="hljs-property">innerHTML</span> = <span class="hljs-title function_">prettyBytes</span>(torrent.<span class="hljs-property">length</span>)
320
321            <span class="hljs-comment">// Remaining time</span>
322            <span class="hljs-keyword">let</span> remaining
323            <span class="hljs-keyword">if</span> (torrent.<span class="hljs-property">done</span>) {
324              remaining = <span class="hljs-string">&#x27;Done.&#x27;</span>
325            } <span class="hljs-keyword">else</span> {
326              remaining = moment.<span class="hljs-title function_">duration</span>(torrent.<span class="hljs-property">timeRemaining</span> / <span class="hljs-number">1000</span>, <span class="hljs-string">&#x27;seconds&#x27;</span>).<span class="hljs-title function_">humanize</span>()
327              remaining = remaining[<span class="hljs-number">0</span>].<span class="hljs-title function_">toUpperCase</span>() + remaining.<span class="hljs-title function_">substring</span>(<span class="hljs-number">1</span>) + <span class="hljs-string">&#x27; remaining.&#x27;</span>
328            }
329            $remaining.<span class="hljs-property">innerHTML</span> = remaining
330
331            <span class="hljs-comment">// Speed rates</span>
332            $downloadSpeed.<span class="hljs-property">innerHTML</span> = <span class="hljs-title function_">prettyBytes</span>(torrent.<span class="hljs-property">downloadSpeed</span>) + <span class="hljs-string">&#x27;/s&#x27;</span>
333            $uploadSpeed.<span class="hljs-property">innerHTML</span> = <span class="hljs-title function_">prettyBytes</span>(torrent.<span class="hljs-property">uploadSpeed</span>) + <span class="hljs-string">&#x27;/s&#x27;</span>
334          }
335          <span class="hljs-keyword">function</span> <span class="hljs-title function_">onDone</span> () {
336            $body.<span class="hljs-property">className</span> += <span class="hljs-string">&#x27; is-seed&#x27;</span>
337            <span class="hljs-title function_">onProgress</span>()
338          }
339        })
340      }
341
342      <span class="hljs-comment">// Human readable bytes util</span>
343      <span class="hljs-keyword">function</span> <span class="hljs-title function_">prettyBytes</span> (num) {
344        <span class="hljs-keyword">const</span> units = [<span class="hljs-string">&#x27;B&#x27;</span>, <span class="hljs-string">&#x27;kB&#x27;</span>, <span class="hljs-string">&#x27;MB&#x27;</span>, <span class="hljs-string">&#x27;GB&#x27;</span>, <span class="hljs-string">&#x27;TB&#x27;</span>, <span class="hljs-string">&#x27;PB&#x27;</span>, <span class="hljs-string">&#x27;EB&#x27;</span>, <span class="hljs-string">&#x27;ZB&#x27;</span>, <span class="hljs-string">&#x27;YB&#x27;</span>]
345        <span class="hljs-keyword">const</span> neg = num &lt; <span class="hljs-number">0</span>
346        <span class="hljs-keyword">if</span> (neg) num = -num
347        <span class="hljs-keyword">if</span> (num &lt; <span class="hljs-number">1</span>) <span class="hljs-keyword">return</span> (neg ? <span class="hljs-string">&#x27;-&#x27;</span> : <span class="hljs-string">&#x27;&#x27;</span>) + num + <span class="hljs-string">&#x27; B&#x27;</span>
348        <span class="hljs-keyword">const</span> exponent = <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">min</span>(<span class="hljs-title class_">Math</span>.<span class="hljs-title function_">floor</span>(<span class="hljs-title class_">Math</span>.<span class="hljs-title function_">log</span>(num) / <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">log</span>(<span class="hljs-number">1000</span>)), units.<span class="hljs-property">length</span> - <span class="hljs-number">1</span>)
349        <span class="hljs-keyword">const</span> unit = units[exponent]
350        num = <span class="hljs-title class_">Number</span>((num / <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">pow</span>(<span class="hljs-number">1000</span>, exponent)).<span class="hljs-title function_">toFixed</span>(<span class="hljs-number">2</span>))
351        <span class="hljs-keyword">return</span> (neg ? <span class="hljs-string">&#x27;-&#x27;</span> : <span class="hljs-string">&#x27;&#x27;</span>) + num + <span class="hljs-string">&#x27; &#x27;</span> + unit
352      }
353    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
354  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
355<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
356</div></code></pre>
357<h2>More Documentation</h2>
358<p>Check out the <a href="//webtorrent.io/docs">API Documentation</a> and <a href="//webtorrent.io/faq">FAQ</a> for more details.</p>
359</article></main><div class="footerWrap"><footer class="clearfix"><section><h3>Learn</h3><a href="/intro">Get Started</a><a href="/docs">Docs</a><a href="/faq">FAQ</a><a href="/desktop">WebTorrent Desktop</a></section><section><h3>Connect</h3><a href="https://twitter.com/WebTorrentApp">Twitter</a><a href="https://github.com/webtorrent/webtorrent">GitHub</a><iframe class="gh-button" src="https://ghbtns.com/github-btn.html?user=webtorrent&amp;repo=webtorrent&amp;type=star&amp;count=true&amp;size=large" frameborder="0" scrolling="0" width="160px" height="30px"></iframe></section><section><h3>Support</h3><a href="https://discord.gg/cnXkm4Z" target="_blank">Join our Discord</a><a href="https://github.com/webtorrent/webtorrent/discussions" target="_blank">Start a GitHub discussion</a><a href="https://github.com/webtorrent/webtorrent/issues" target="_blank">Open an issue</a></section><section class="sponsors"><h3>Sponsors</h3><a href="https://socket.dev" target="_blank">Socket – JavaScript Security</a><a href="https://wormhole.app" target="_blank">Wormhole</a></section></footer></div>
359<script src="/bundle.js"></script>
359<script>window.ga = window.ga || function () {
360  (ga.q = ga.q || []).push(arguments)
361}
362ga.l = +new Date
363ga('create', 'UA-3898076-19', 'auto')
364ga('send', 'pageview')</script>
364<script async src="//www.google-analytics.com/analytics.js"></script>
364</body></html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.