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"><<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">'module'</span>></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">'https://esm.sh/webtorrent'</span> 10</span><span class="hljs-tag"></<span class="hljs-name">script</span>></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">'webtorrent'</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">'webtorrent'</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">'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'</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">'sw.min.js'</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> =></span> { 37 <span class="hljs-comment">// Torrents can contain many files. Let'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> =></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">'.mp4'</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">'video'</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">'drag-drop'</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">'webtorrent'</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">'body'</span>, <span class="hljs-function"><span class="hljs-params">files</span> =></span> { 59 client.<span class="hljs-title function_">seed</span>
59(files, <span class="hljs-function"><span class="hljs-params">torrent</span> =></span> { 60 <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'Client is seeding '</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">'webtorrent'</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">'magnet: ...'</span> 75 76client.<span class="hljs-title function_">add</span>(magnetURI, { <span class="hljs-attr">path</span>: <span class="hljs-string">'/path/to/folder'</span> }, <span class="hljs-function"><span class="hljs-params">torrent</span> =></span> { 77 torrent.<span class="hljs-title function_">on</span>(<span class="hljs-string">'done'</span>, <span class="hljs-function">() =></span> { 78 <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'torrent download finished'</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">'webtorrent-hybrid'</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">'/seed-me.txt'</span>, <span class="hljs-function"><span class="hljs-params">torrent</span> =></span> { 88 <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">'Client is seeding '</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"><!doctype <span class="hljs-keyword">html</span>></span> 100<span class="hljs-tag"><<span class="hljs-name">html</span>></span> 101 <span class="hljs-tag"><<span class="hljs-name">body</span>></span> 102 <span class="hljs-tag"><<span class="hljs-name">h1</span>></span>Download files using the WebTorrent protocol (BitTorrent over WebRTC).<span class="hljs-tag"></<span class="hljs-name">h1</span>></span> 103 104 <span class="hljs-tag"><<span class="hljs-name">form</span>></span>
105 <span class="hljs-tag"><<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"torrentId"</span>></span>Download from a magnet link: <span class="hljs-tag"></<span class="hljs-name">label</span>></span> 106 <span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"torrentId"</span>, <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"magnet:"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"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"</span>></span> 107 <span class="hljs-tag"><<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>></span>Download<span class="hljs-tag"></<span class="hljs-name">button</span>></span> 108 <span class="hljs-tag"></<span class="hljs-name">form</span>></span> 109 110 <span class="hljs-tag"><<span class="hljs-name">h2</span>></span>Log<span class="hljs-tag"></<span class="hljs-name">h2</span>></span> 111 <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"log"</span>></span><span class="hljs-tag"></<span class="hljs-name">div</span>></span> 112 113 <span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">'module'</span>></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">'https://esm.sh/webtorrent'</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">'error'</span>, <span class="hljs-function"><span class="hljs-params">err</span> =></span> { 120 <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">error</span>(<span class="hljs-string">'ERROR: '</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">'form'</span>).<span class="hljs-title function_">addEventListener</span>(<span class="hljs-string">'submit'</span>, <span class="hljs-function"><span class="hljs-params">e</span> =></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">'form input[name=torrentId]'</span>).<span class="hljs-property">value</span> 127 <span class="hljs-title function_">log</span>(<span class="hljs-string">'Adding '</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">'Got torrent metadata!'</span>) 133 <span class="hljs-title function_">log</span>( 134 <span class="hljs-string">'Torrent info hash: '</span> + torrent.<span class="hljs-property">infoHash</span> + <span class="hljs-string">' '</span> + 135 <span class="hljs-string">'<a href="'</span> + torrent.<span class="hljs-property">magnetURI</span> + <span class="hljs-string">'" target="_blank">[Magnet URI]</a> '</span> + 136 <span class="hljs-string">'<a href="'</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">'" target="_blank" download="'</span> + torrent.<span class="hljs-property">name</span> + <span class="hljs-string">'.torrent">[Download .torrent]</a>'</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">() =></span> { 141 <span class="hljs-title function_">log</span>(<span class="hljs-string">'Progress: '</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">'%'</span>) 142 }, <span class="hljs-number">5000</span>) 143 144 torrent.<span class="hljs-title function_">on</span>(<span class="hljs-string">'done'</span>, <span class="hljs-function">() =></span> { 145 <span class="hljs-title function_">log</span>(<span class="hljs-string">'Progress: 100%'</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">'.log'</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">'(Blob URLs only work if the file is loaded from a server. "http//localhost" works. "file://" does not.)'</span>) 155 <span class="hljs-title function_">log</span>(<span class="hljs-string">'File done.'</span>) 156 <span class="hljs-title function_">log</span>(<span class="hljs-string">'<a href="'</span> + <span class="hljs-variable constant_">URL</span>.<span class="hljs-title function_">createObjectURL</span>(blob) + <span class="hljs-string">'">Download full file: '</span> + file.<span class="hljs-property">name</span> + <span class="hljs-string">'</a>'</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">'p'</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">'.log'</span>).<span class="hljs-title function_">appendChild</span>(p) 167 } 168 </span><span class="hljs-tag"></<span class="hljs-name">script</span>></span> 169 <span class="hljs-tag"></<span class="hljs-name">body</span>></span> 170<span class="hljs-tag"></<span class="hljs-name">html</span>></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"><!DOCTYPE <span class="hljs-keyword">html</span>></span> 185<span class="hljs-tag"><<span class="hljs-name">html</span>></span> 186 <span class="hljs-tag"><<span class="hljs-name">head</span>></span> 187 <span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span>></span> 188 <span class="hljs-tag"><<span class="hljs-name">title</span>></span>WebTorrent video player<span class="hljs-tag"></<span class="hljs-name">title</span>></span> 189 <span class="hljs-tag"><<span class="hljs-name">style</span>></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"></<span class="hljs-name">style</span>></span> 235 <span class="hljs-tag"></<span class="hljs-name">head</span>></span> 236 <span class="hljs-tag"><<span class="hljs-name">body</span>></span> 237 <span class="hljs-tag"><<span class="hljs-name">div</span>></span> 238 <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"progressBar"</span>></span><span class="hljs-tag"></<span class="hljs-name">div</span>></span> 239 <span class="hljs-tag"><<span class="hljs-name">video</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"output"</span> <span class="hljs-attr">controls</span>></span><span class="hljs-tag"></<span class="hljs-name">video</span>></span> 240 <span class="hljs-tag"></<span class="hljs-name">div</span>></span> 241 <span class="hljs-comment"><!-- Statistics --></span> 242 <span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"status"</span>></span> 243 <span class="hljs-tag"><<span class="hljs-name">div</span>></span> 244 <span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"show-leech"</span>></span>Downloading <span class="hljs-tag"></<span class="hljs-name">span</span>></span> 245 <span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"show-seed"</span>></span>Seeding <span class="hljs-tag"></<span class="hljs-name">span</span>></span> 246 <span class="hljs-tag"><<span class="hljs-name">code</span>></span> 247 <span class="hljs-comment"><!-- Informative link to the torrent file --></span> 248 <span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"torrentLink"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://webtorrent.io/torrents/sintel.torrent"</span>></span>sintel.torrent<span class="hljs-tag"></<span class="hljs-name">a</span>></span> 249 <span class="hljs-tag"></<span class="hljs-name">code</span>></span> 250 <span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"show-leech"</span>></span> from <span class="hljs-tag"></<span class="hljs-name">span</span>></span> 251 <span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"show-seed"</span>></span> to <span class="hljs-tag"></<span class="hljs-name">span</span>></span>
252 <span class="hljs-tag"><<span class="hljs-name">code</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"numPeers"</span>></span>0 peers<span class="hljs-tag"></<span class="hljs-name">code</span>></span>. 253 <span class="hljs-tag"></<span class="hljs-name">div</span>></span> 254 <span class="hljs-tag"><<span class="hljs-name">div</span>></span> 255 <span class="hljs-tag"><<span class="hljs-name">code</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"downloaded"</span>></span><span class="hljs-tag"></<span class="hljs-name">code</span>></span> 256 of <span class="hljs-tag"><<span class="hljs-name">code</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"total"</span>></span><span class="hljs-tag"></<span class="hljs-name">code</span>></span> 257 â <span class="hljs-tag"><<span class="hljs-name">span</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"remaining"</span>></span><span class="hljs-tag"></<span class="hljs-name">span</span>></span><span class="hljs-tag"><<span class="hljs-name">br</span>/></span> 258 <span class="hljs-symbol">&#x2198;</span><span class="hljs-tag"><<span class="hljs-name">code</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"downloadSpeed"</span>></span>0 b/s<span class="hljs-tag"></<span class="hljs-name">code</span>></span> 259 / <span class="hljs-symbol">&#x2197;</span><span class="hljs-tag"><<span class="hljs-name">code</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"uploadSpeed"</span>></span>0 b/s<span class="hljs-tag"></<span class="hljs-name">code</span>></span> 260 <span class="hljs-tag"></<span class="hljs-name">div</span>></span> 261 <span class="hljs-tag"></<span class="hljs-name">div</span>></span> 262 263 <span class="hljs-comment"><!-- Moment is used to show a human-readable remaining time --></span> 264 <span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"http://momentjs.com/downloads/moment.min.js"</span>></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span> 265 266 <span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"module"</span>></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">'./webtorrent.min.js'</span> 269 270 <span class="hljs-keyword">const</span> torrentId = <span class="hljs-string">'https://webtorrent.io/torrents/sintel.torrent'</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">'#progressBar'</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">'#numPeers'</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">'#downloaded'</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">'#total'</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">'#remaining'</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">'#uploadSpeed'</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">'#downloadSpeed'</span>) 283 284 navigator.<span class="hljs-property">serviceWorker</span>.<span class="hljs-title function_">register</span>(<span class="hljs-string">'./sw.min.js'</span>, { <span class="hljs-attr">scope</span>: <span class="hljs-string">'./'</span> }).<span class="hljs-title function_">then</span>(<span class="hljs-function"><span class="hljs-params">reg</span> =></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">'activated'</span> && client.<span class="hljs-title function_">createServer</span>({ <span class="hljs-attr">controller</span>: reg }) && <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">'statechange'</span>, <span class="hljs-function">(<span class="hljs-params">{ target }</span>) =></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> =></span> { 297 <span class="hljs-comment">// Torrents can contain many files. Let'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> =></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">'.mp4'</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">'#output'</span>)) 304 305 <span class="hljs-comment">// Trigger statistics refresh</span> 306 torrent.<span class="hljs-title function_">on</span>(<span class="hljs-string">'done'</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">' peer'</span> : <span class="hljs-string">' peers'</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">'%'</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">'Done.'</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">'seconds'</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">' remaining.'</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">'/s'</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">'/s'</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">' is-seed'</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">'B'</span>, <span class="hljs-string">'kB'</span>, <span class="hljs-string">'MB'</span>, <span class="hljs-string">'GB'</span>, <span class="hljs-string">'TB'</span>, <span class="hljs-string">'PB'</span>, <span class="hljs-string">'EB'</span>, <span class="hljs-string">'ZB'</span>, <span class="hljs-string">'YB'</span>] 345 <span class="hljs-keyword">const</span> neg = num < <span class="hljs-number">0</span> 346 <span class="hljs-keyword">if</span> (neg) num = -num 347 <span class="hljs-keyword">if</span> (num < <span class="hljs-number">1</span>) <span class="hljs-keyword">return</span> (neg ? <span class="hljs-string">'-'</span> : <span class="hljs-string">''</span>) + num + <span class="hljs-string">' B'</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">'-'</span> : <span class="hljs-string">''</span>) + num + <span class="hljs-string">' '</span> + unit 352 } 353 </span><span class="hljs-tag"></<span class="hljs-name">script</span>></span> 354 <span class="hljs-tag"></<span class="hljs-name">body</span>></span> 355<span class="hljs-tag"></<span class="hljs-name">html</span>></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&repo=webtorrent&type=star&count=true&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.