KeenEthics Experience-Sharing: How to Create a Simple Torrent Player?
Have you ever heard about PopcornTime? This app allows you to play a video from BitTorrent without downloading the whole file. Why not develop a similar thing but for audio? It is a good opportunity to practice and to learn some Node.js basics.

Here, I will show only how to work with mp3, but you may easily reimplement other formats using libraries. As a source tracker, I will use rutracker. I have tried to use PirateBay, but it does not have a way to get tracks path without taking torrent info, which is useful to play a single track faster.
I use Electron since it is simpler, but you can easily take it to usual Node.js + simple static server. I have three main js scripts: rutracker search wrapper, client code, and server-side code. The code is not perfect, and it is very simplified for POC.
Rutracker.js: Rutracker Search Wrapper
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
<span class="react-syntax-highlighter-line-number">1 </span><span class="react-syntax-highlighter-line-number">2 </span><span class="react-syntax-highlighter-line-number">3 </span><span class="react-syntax-highlighter-line-number">4 </span><span class="react-syntax-highlighter-line-number">5 </span><span class="react-syntax-highlighter-line-number">6 </span><span class="react-syntax-highlighter-line-number">7 </span><span class="react-syntax-highlighter-line-number">8 </span><span class="react-syntax-highlighter-line-number">9 </span><span class="react-syntax-highlighter-line-number">10 </span><span class="react-syntax-highlighter-line-number">11 </span><span class="react-syntax-highlighter-line-number">12 </span><span class="react-syntax-highlighter-line-number">13 </span><span class="react-syntax-highlighter-line-number">14 </span><span class="react-syntax-highlighter-line-number">15 </span><span class="react-syntax-highlighter-line-number">16 </span><span class="react-syntax-highlighter-line-number">17 </span><span class="react-syntax-highlighter-line-number">18 </span><span class="react-syntax-highlighter-line-number">19 </span><span class="react-syntax-highlighter-line-number">20 </span><span class="react-syntax-highlighter-line-number">21 </span><span class="react-syntax-highlighter-line-number">22 </span><span class="react-syntax-highlighter-line-number">23 </span><span class="react-syntax-highlighter-line-number">24 </span><span class="react-syntax-highlighter-line-number">25 </span><span class="react-syntax-highlighter-line-number">26 </span><span class="react-syntax-highlighter-line-number">27 </span><span class="react-syntax-highlighter-line-number">28 </span><span class="react-syntax-highlighter-line-number">29 </span><span class="react-syntax-highlighter-line-number">30 </span><span class="react-syntax-highlighter-line-number">31 </span><span class="react-syntax-highlighter-line-number">32 </span><span class="react-syntax-highlighter-line-number">33 </span><span class="react-syntax-highlighter-line-number">34 </span><span class="react-syntax-highlighter-line-number">35 </span><span class="react-syntax-highlighter-line-number">36 </span><span class="react-syntax-highlighter-line-number">37 </span><span class="react-syntax-highlighter-line-number">38 </span><span class="react-syntax-highlighter-line-number">39 </span><span class="react-syntax-highlighter-line-number">40 </span><span class="react-syntax-highlighter-line-number">41 </span><span class="react-syntax-highlighter-line-number">42 </span><span class="react-syntax-highlighter-line-number">43 </span><span class="react-syntax-highlighter-line-number">44 </span><span class="react-syntax-highlighter-line-number">45 </span><span class="react-syntax-highlighter-line-number">46 </span><span class="react-syntax-highlighter-line-number">47 </span><span class="react-syntax-highlighter-line-number">48 </span><span class="react-syntax-highlighter-line-number">49 </span><span class="react-syntax-highlighter-line-number">50 </span><span class="react-syntax-highlighter-line-number">51 </span><span class="react-syntax-highlighter-line-number">52 </span><span class="react-syntax-highlighter-line-number">53 </span><span class="react-syntax-highlighter-line-number">54 </span><span class="react-syntax-highlighter-line-number">55 </span><span class="react-syntax-highlighter-line-number">56 </span><span class="react-syntax-highlighter-line-number">57 </span><span class="react-syntax-highlighter-line-number">58 </span><span class="react-syntax-highlighter-line-number">59 </span><span class="react-syntax-highlighter-line-number">60 </span><span class="react-syntax-highlighter-line-number">61 </span><span class="react-syntax-highlighter-line-number">62 </span><span class="react-syntax-highlighter-line-number">63 </span><span class="react-syntax-highlighter-line-number">64 </span><span class="react-syntax-highlighter-line-number">65 </span><span class="react-syntax-highlighter-line-number">66 </span><span class="react-syntax-highlighter-line-number">67 </span><span class="react-syntax-highlighter-line-number">68 </span><span class="react-syntax-highlighter-line-number">69 </span></code><code style="color: black; background: none; text-shadow: white 0px 1px; font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; text-align: left; white-space: pre; word-spacing: normal; word-break: normal; overflow-wrap: normal; line-height: 1.5; tab-size: 4; hyphens: none;"><span class="token" style="color: rgb(0, 119, 170);">const</span> torrentStream <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(221, 74, 104);">require</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'torrent-stream'</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> <span class="token maybe-class-name">RutrackerAPI</span> <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(221, 74, 104);">require</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'rutracker-api-2'</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> pRequest <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(221, 74, 104);">require</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'request-promise'</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> cheerio <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(221, 74, 104);">require</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'cheerio'</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> rutracker <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(0, 119, 170);">new</span> <span class="token" style="color: rgb(221, 74, 104);">RutrackerAPI</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">let</span> trackerCookie<span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> <span class="token" style="color: rgb(153, 0, 85);">RUTRACKER_LOGIN</span> <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(102, 153, 0);">"searchertrack"</span><span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(153, 0, 85);">RUTRACKER_PASSWORD</span> <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(102, 153, 0);">"1q1Q1q1Q"</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(0, 119, 170);">async</span> <span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token arrow" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=></span><span class="token" style="color: rgb(153, 153, 153);">{</span> trackerCookie <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(0, 119, 170);">await</span> rutracker<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">login</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(153, 0, 85);">RUTRACKER_LOGIN</span><span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(153, 0, 85);">RUTRACKER_PASSWORD</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(153, 153, 153);">}</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> <span class="token function-variable" style="color: rgb(221, 74, 104);">getTrackerMP3List</span> <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token parameter">html<span class="token" style="color: rgb(153, 153, 153);">,</span> magnetHTML</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token arrow" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=></span> <span class="token" style="color: rgb(153, 153, 153);">{</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> $ <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> cheerio<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">load</span><span class="token" style="color: rgb(153, 153, 153);">(</span>html<span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> $m <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> cheerio<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">load</span><span class="token" style="color: rgb(153, 153, 153);">(</span>magnetHTML<span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> elem <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(221, 74, 104);">$</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'.ftree'</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> magnet <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(221, 74, 104);">$m</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'[class*="magnet-link-"]'</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">attr</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'href'</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> result <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token known-class-name" style="color: rgb(221, 74, 104);">Array</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token module" style="color: rgb(0, 119, 170);">from</span><span class="token" style="color: rgb(153, 153, 153);">(</span>$elem<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">find</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'b:contains(.mp3)'</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">map</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token parameter">x<span class="token" style="color: rgb(153, 153, 153);">,</span> i</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token arrow" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=></span> <span class="token" style="color: rgb(153, 153, 153);">{</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> title <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(221, 74, 104);">$</span><span class="token" style="color: rgb(153, 153, 153);">(</span>x<span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">text</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> $dir <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(221, 74, 104);">$</span><span class="token" style="color: rgb(153, 153, 153);">(</span>x<span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">parents</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'.dir'</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> pathParts <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token known-class-name" style="color: rgb(221, 74, 104);">Array</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token module" style="color: rgb(0, 119, 170);">from</span><span class="token" style="color: rgb(153, 153, 153);">(</span>$dir<span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">map</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token parameter">x</span> <span class="token arrow" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=></span> <span class="token" style="color: rgb(221, 74, 104);">$</span><span class="token" style="color: rgb(153, 153, 153);">(</span>x<span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">find</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'>div b'</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">text</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">replace</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'./'</span><span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(102, 153, 0);">''</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">reverse</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> pathParts<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">push</span><span class="token" style="color: rgb(153, 153, 153);">(</span>title<span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> resultPath <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> pathParts<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">join</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">' || '</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">return</span> <span class="token" style="color: rgb(153, 153, 153);">{</span> id<span class="token" style="color: rgb(153, 153, 153);">:</span> <span class="token template-string"><span class="token template-punctuation" style="color: rgb(102, 153, 0);">`</span><span class="token interpolation"><span class="token interpolation-punctuation" style="color: rgb(153, 153, 153);">${</span><span class="token known-class-name" style="color: rgb(221, 74, 104);">Date</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">now</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token interpolation-punctuation" style="color: rgb(153, 153, 153);">}</span></span><span class="token interpolation"><span class="token interpolation-punctuation" style="color: rgb(153, 153, 153);">${</span>i<span class="token interpolation-punctuation" style="color: rgb(153, 153, 153);">}</span></span><span class="token template-punctuation" style="color: rgb(102, 153, 0);">`</span></span><span class="token" style="color: rgb(153, 153, 153);">,</span> trackPath<span class="token" style="color: rgb(153, 153, 153);">:</span> resultPath<span class="token" style="color: rgb(153, 153, 153);">,</span> shortname<span class="token" style="color: rgb(153, 153, 153);">:</span> title<span class="token" style="color: rgb(153, 153, 153);">,</span> title<span class="token" style="color: rgb(153, 153, 153);">:</span> resultPath<span class="token" style="color: rgb(153, 153, 153);">,</span> isTracker<span class="token" style="color: rgb(153, 153, 153);">:</span> <span class="token" style="color: rgb(153, 0, 85);">true</span><span class="token" style="color: rgb(153, 153, 153);">,</span> magnet<span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(153, 153, 153);">}</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(153, 153, 153);">}</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">return</span> result<span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(153, 153, 153);">}</span><span class="token" style="color: rgb(153, 153, 153);">;</span> module<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">exports</span> <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(153, 153, 153);">{</span> <span class="token function-variable" style="color: rgb(221, 74, 104);"><span class="token maybe-class-name">TrackerFiles</span></span><span class="token" style="color: rgb(153, 153, 153);">:</span> <span class="token" style="color: rgb(0, 119, 170);">async</span> <span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token parameter">url</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token arrow" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=></span> <span class="token" style="color: rgb(153, 153, 153);">{</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> id <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> url<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">replace</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'http://rutracker.org/forum/viewtopic.php?t='</span><span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(102, 153, 0);">''</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> magnetHTML <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(0, 119, 170);">await</span> <span class="token" style="color: rgb(221, 74, 104);">pRequest</span><span class="token" style="color: rgb(153, 153, 153);">(</span>url<span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(153, 153, 153);">{</span> headers<span class="token" style="color: rgb(153, 153, 153);">:</span> <span class="token" style="color: rgb(153, 153, 153);">{</span> cookie<span class="token" style="color: rgb(153, 153, 153);">:</span> trackerCookie<span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(153, 153, 153);">}</span><span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(153, 153, 153);">}</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> html <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(0, 119, 170);">await</span> <span class="token" style="color: rgb(221, 74, 104);">pRequest</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'https://rutracker.org/forum/viewtorrent.php'</span><span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(153, 153, 153);">{</span> method<span class="token" style="color: rgb(153, 153, 153);">:</span> <span class="token" style="color: rgb(102, 153, 0);">"POST"</span><span class="token" style="color: rgb(153, 153, 153);">,</span> headers<span class="token" style="color: rgb(153, 153, 153);">:</span> <span class="token" style="color: rgb(153, 153, 153);">{</span> cookie<span class="token" style="color: rgb(153, 153, 153);">:</span> trackerCookie<span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(153, 153, 153);">}</span><span class="token" style="color: rgb(153, 153, 153);">,</span> form<span class="token" style="color: rgb(153, 153, 153);">:</span> <span class="token" style="color: rgb(153, 153, 153);">{</span> t<span class="token" style="color: rgb(153, 153, 153);">:</span> id <span class="token" style="color: rgb(153, 153, 153);">}</span> <span class="token" style="color: rgb(153, 153, 153);">}</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> result <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(221, 74, 104);">getTrackerMP3List</span><span class="token" style="color: rgb(153, 153, 153);">(</span>html<span class="token" style="color: rgb(153, 153, 153);">,</span> magnetHTML<span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">return</span> result<span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(153, 153, 153);">}</span><span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token function-variable" style="color: rgb(221, 74, 104);"><span class="token maybe-class-name">Search</span></span><span class="token" style="color: rgb(153, 153, 153);">:</span> <span class="token" style="color: rgb(0, 119, 170);">async</span> <span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token parameter">str</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token arrow" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=></span> <span class="token" style="color: rgb(153, 153, 153);">{</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> data <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(0, 119, 170);">await</span> rutracker<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">search</span><span class="token" style="color: rgb(153, 153, 153);">(</span>str<span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(102, 153, 0);">'size'</span><span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(153, 0, 85);">false</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">return</span> <span class="token" style="color: rgb(153, 153, 153);">{</span> playlist<span class="token" style="color: rgb(153, 153, 153);">:</span> data <span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">filter</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token parameter">x</span> <span class="token arrow" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=></span> x<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">title</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">toLowerCase</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">indexOf</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'mp3'</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">></span> <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">-</span><span class="token" style="color: rgb(153, 0, 85);">1</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">map</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token parameter">x</span> <span class="token arrow" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=></span> <span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(153, 153, 153);">{</span> permalink_url<span class="token" style="color: rgb(153, 153, 153);">:</span> x<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">url</span><span class="token" style="color: rgb(153, 153, 153);">,</span> title<span class="token" style="color: rgb(153, 153, 153);">:</span> x<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">title</span> <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">||</span> <span class="token" style="color: rgb(102, 153, 0);">"NO_TITLE"</span><span class="token" style="color: rgb(153, 153, 153);">,</span> id<span class="token" style="color: rgb(153, 153, 153);">:</span> x<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">id</span><span class="token" style="color: rgb(153, 153, 153);">,</span> type<span class="token" style="color: rgb(153, 153, 153);">:</span> <span class="token" style="color: rgb(102, 153, 0);">'tracker'</span><span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(153, 153, 153);">}</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">,</span> user<span class="token" style="color: rgb(153, 153, 153);">:</span> <span class="token" style="color: rgb(153, 153, 153);">[</span><span class="token" style="color: rgb(153, 153, 153);">]</span><span class="token" style="color: rgb(153, 153, 153);">,</span> track<span class="token" style="color: rgb(153, 153, 153);">:</span> <span class="token" style="color: rgb(153, 153, 153);">[</span><span class="token" style="color: rgb(153, 153, 153);">]</span> <span class="token" style="color: rgb(153, 153, 153);">}</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(153, 153, 153);">}</span> <span class="token" style="color: rgb(153, 153, 153);">}</span><span class="token" style="color: rgb(153, 153, 153);">;</span> |
There are two exported methods. The second one is used for distribution search to filter the titles that contain “mp3”. The first one is used for retrieving the list of tracks inside the distribution. Now, it merely displays the entire track path, which can be transformed to the tree view if needed. This code uses non-official rutracker API and simple page scraping, so it does not require any specific comments here.
Serv.js: Server-Side Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
<span class="react-syntax-highlighter-line-number">1 </span><span class="react-syntax-highlighter-line-number">2 </span><span class="react-syntax-highlighter-line-number">3 </span><span class="react-syntax-highlighter-line-number">4 </span><span class="react-syntax-highlighter-line-number">5 </span><span class="react-syntax-highlighter-line-number">6 </span><span class="react-syntax-highlighter-line-number">7 </span><span class="react-syntax-highlighter-line-number">8 </span><span class="react-syntax-highlighter-line-number">9 </span><span class="react-syntax-highlighter-line-number">10 </span><span class="react-syntax-highlighter-line-number">11 </span><span class="react-syntax-highlighter-line-number">12 </span><span class="react-syntax-highlighter-line-number">13 </span><span class="react-syntax-highlighter-line-number">14 </span><span class="react-syntax-highlighter-line-number">15 </span><span class="react-syntax-highlighter-line-number">16 </span><span class="react-syntax-highlighter-line-number">17 </span><span class="react-syntax-highlighter-line-number">18 </span><span class="react-syntax-highlighter-line-number">19 </span><span class="react-syntax-highlighter-line-number">20 </span><span class="react-syntax-highlighter-line-number">21 </span><span class="react-syntax-highlighter-line-number">22 </span><span class="react-syntax-highlighter-line-number">23 </span><span class="react-syntax-highlighter-line-number">24 </span><span class="react-syntax-highlighter-line-number">25 </span><span class="react-syntax-highlighter-line-number">26 </span><span class="react-syntax-highlighter-line-number">27 </span><span class="react-syntax-highlighter-line-number">28 </span><span class="react-syntax-highlighter-line-number">29 </span><span class="react-syntax-highlighter-line-number">30 </span><span class="react-syntax-highlighter-line-number">31 </span><span class="react-syntax-highlighter-line-number">32 </span><span class="react-syntax-highlighter-line-number">33 </span><span class="react-syntax-highlighter-line-number">34 </span><span class="react-syntax-highlighter-line-number">35 </span><span class="react-syntax-highlighter-line-number">36 </span><span class="react-syntax-highlighter-line-number">37 </span><span class="react-syntax-highlighter-line-number">38 </span><span class="react-syntax-highlighter-line-number">39 </span><span class="react-syntax-highlighter-line-number">40 </span><span class="react-syntax-highlighter-line-number">41 </span><span class="react-syntax-highlighter-line-number">42 </span><span class="react-syntax-highlighter-line-number">43 </span><span class="react-syntax-highlighter-line-number">44 </span><span class="react-syntax-highlighter-line-number">45 </span><span class="react-syntax-highlighter-line-number">46 </span><span class="react-syntax-highlighter-line-number">47 </span><span class="react-syntax-highlighter-line-number">48 </span><span class="react-syntax-highlighter-line-number">49 </span><span class="react-syntax-highlighter-line-number">50 </span><span class="react-syntax-highlighter-line-number">51 </span><span class="react-syntax-highlighter-line-number">52 </span><span class="react-syntax-highlighter-line-number">53 </span></code><code style="color: black; background: none; text-shadow: white 0px 1px; font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; text-align: left; white-space: pre; word-spacing: normal; word-break: normal; overflow-wrap: normal; line-height: 1.5; tab-size: 4; hyphens: none;"><span class="token" style="color: rgb(0, 119, 170);">const</span> torrentStream <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(221, 74, 104);">require</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'torrent-stream'</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> fastify <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(221, 74, 104);">require</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'fastify'</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> util <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(221, 74, 104);">require</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'util'</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> module<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method-variable function-variable method property-access" style="color: rgb(221, 74, 104);">exports</span> <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token parameter">port</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token arrow" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=></span> <span class="token" style="color: rgb(153, 153, 153);">{</span> <span class="token" style="color: rgb(0, 119, 170);">let</span> engine<span class="token" style="color: rgb(153, 153, 153);">,</span> track<span class="token" style="color: rgb(153, 153, 153);">;</span> fastify<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">get</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'/trackerStream'</span><span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(0, 119, 170);">async</span> <span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token parameter">request<span class="token" style="color: rgb(153, 153, 153);">,</span> response</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token arrow" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=></span> <span class="token" style="color: rgb(153, 153, 153);">{</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> <span class="token" style="color: rgb(153, 153, 153);">{</span> trackPath<span class="token" style="color: rgb(153, 153, 153);">,</span> magnet <span class="token" style="color: rgb(153, 153, 153);">}</span> <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> request<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">query</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> filePathTorr <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> trackPath<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">split</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">' || '</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">join</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'\\'</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> filePathTorrLinux <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> trackPath<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">split</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">' || '</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">join</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'/'</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">if</span> <span class="token" style="color: rgb(153, 153, 153);">(</span>engine<span class="token" style="color: rgb(153, 153, 153);">)</span> engine<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">destroy</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> engine <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(221, 74, 104);">torrentStream</span><span class="token" style="color: rgb(153, 153, 153);">(</span>magnet<span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> engine<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">on</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'error'</span><span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token parameter">err</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token arrow" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=></span> <span class="token console" style="color: rgb(221, 74, 104);">console</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">log</span><span class="token" style="color: rgb(153, 153, 153);">(</span>err<span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">await</span> util<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">promisify</span><span class="token" style="color: rgb(153, 153, 153);">(</span>engine<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">on</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'ready'</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> track <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> engine<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">files</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">find</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token parameter">x</span> <span class="token arrow" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=></span> x<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">path</span> <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">===</span> filePathTorr <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">||</span> x<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">path</span> <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">===</span> filePathTorrLinux<span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> total <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> track<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">length</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> range <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> request<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">headers</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">range</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">if</span> <span class="token" style="color: rgb(153, 153, 153);">(</span>range<span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token" style="color: rgb(153, 153, 153);">{</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> parts <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> range<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">replace</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(238, 153, 0);"><span class="token regex-delimiter">/</span><span class="token language-regex">bytes=</span><span class="token regex-delimiter">/</span></span><span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(102, 153, 0);">""</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">split</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">"-"</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> partialstart <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> parts<span class="token" style="color: rgb(153, 153, 153);">[</span><span class="token" style="color: rgb(153, 0, 85);">0</span><span class="token" style="color: rgb(153, 153, 153);">]</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> partialend <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> parts<span class="token" style="color: rgb(153, 153, 153);">[</span><span class="token" style="color: rgb(153, 0, 85);">1</span><span class="token" style="color: rgb(153, 153, 153);">]</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> start <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(221, 74, 104);">parseInt</span><span class="token" style="color: rgb(153, 153, 153);">(</span>partialstart<span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(153, 0, 85);">10</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> end <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> partialend <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">?</span> <span class="token" style="color: rgb(221, 74, 104);">parseInt</span><span class="token" style="color: rgb(153, 153, 153);">(</span>partialend<span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(153, 0, 85);">10</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token" style="color: rgb(153, 153, 153);">:</span> total <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">-</span> <span class="token" style="color: rgb(153, 0, 85);">1</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> chunksize <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(153, 153, 153);">(</span>end <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">-</span> start<span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">+</span> <span class="token" style="color: rgb(153, 0, 85);">1</span><span class="token" style="color: rgb(153, 153, 153);">;</span> response <span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">code</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(153, 0, 85);">206</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">header</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'Content-Range'</span><span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(102, 153, 0);">'bytes '</span> <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">+</span> start <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">+</span> <span class="token" style="color: rgb(102, 153, 0);">'-'</span> <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">+</span> end <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">+</span> <span class="token" style="color: rgb(102, 153, 0);">'/'</span> <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">+</span> total<span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">header</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'Accept-Ranges'</span><span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(102, 153, 0);">'bytes'</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">header</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'Content-Length'</span><span class="token" style="color: rgb(153, 153, 153);">,</span> chunksize<span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">header</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'Content-Type'</span><span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(102, 153, 0);">'audio/mpeg'</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">send</span><span class="token" style="color: rgb(153, 153, 153);">(</span>track <span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">createReadStream</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(153, 153, 153);">{</span> start<span class="token" style="color: rgb(153, 153, 153);">,</span> end <span class="token" style="color: rgb(153, 153, 153);">}</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">on</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'end'</span><span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token arrow" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=></span> <span class="token" style="color: rgb(153, 153, 153);">{</span> <span class="token console" style="color: rgb(221, 74, 104);">console</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">log</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'Downloaded'</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> engine<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">destroy</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(153, 153, 153);">}</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(153, 153, 153);">}</span> <span class="token" style="color: rgb(0, 119, 170);">else</span> <span class="token" style="color: rgb(153, 153, 153);">{</span> response <span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">header</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'Content-Type'</span><span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(102, 153, 0);">'audio/mpeg'</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">send</span><span class="token" style="color: rgb(153, 153, 153);">(</span>track<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">createReadStream</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(153, 153, 153);">}</span> <span class="token" style="color: rgb(153, 153, 153);">}</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> <span class="token function-variable" style="color: rgb(221, 74, 104);">start</span> <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(0, 119, 170);">async</span> <span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token arrow" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=></span> <span class="token" style="color: rgb(153, 153, 153);">{</span> <span class="token" style="color: rgb(0, 119, 170);">try</span> <span class="token" style="color: rgb(153, 153, 153);">{</span> <span class="token" style="color: rgb(0, 119, 170);">await</span> fastify<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">listen</span><span class="token" style="color: rgb(153, 153, 153);">(</span>port<span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token console" style="color: rgb(221, 74, 104);">console</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">log</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token template-string"><span class="token template-punctuation" style="color: rgb(102, 153, 0);">`</span><span class="token" style="color: rgb(102, 153, 0);">server listening on </span><span class="token interpolation"><span class="token interpolation-punctuation" style="color: rgb(153, 153, 153);">${</span>fastify<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">server</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">address</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">port</span><span class="token interpolation-punctuation" style="color: rgb(153, 153, 153);">}</span></span><span class="token template-punctuation" style="color: rgb(102, 153, 0);">`</span></span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(153, 153, 153);">}</span> <span class="token" style="color: rgb(0, 119, 170);">catch</span> <span class="token" style="color: rgb(153, 153, 153);">(</span>err<span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token" style="color: rgb(153, 153, 153);">{</span> <span class="token console" style="color: rgb(221, 74, 104);">console</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">error</span><span class="token" style="color: rgb(153, 153, 153);">(</span>err<span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(153, 153, 153);">}</span> <span class="token" style="color: rgb(153, 153, 153);">}</span> <span class="token" style="color: rgb(221, 74, 104);">start</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token" style="color: rgb(153, 153, 153);">}</span> <span class="token" style="color: rgb(153, 153, 153);">}</span> |
I use fastify as a server framework. It exposes only one route, which is used for streaming torrent to audio tag. At the same time, it has 2 limitations.
Firstly, web-torrent does not support TCP/UDP in browser, while Node.js development does. Respectively, I can only use torrents that have seeders based on WebRTC fallback. In case I want to get magnet url from tracker and just play i, it will not work.
Secondly, I just choose a simpler way to pipe Node.js readable Stream to browser audio. I have found an alternative way, but it does not seem to support track seeking.
Let’s see what the code does.
I select a track on the client side and pass trackPath argument to the server. It contains the full path to a specific track including the directory structure.
Then, I get torrent info by magnet, find a specific file inside, take read stream, and pipe it to response. This url is used as file inside audio tag src. A good thing is that createReadStream supports ranges, so it is easy to implement audio seeking.
Main.js: Client Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
<span class="react-syntax-highlighter-line-number">1 </span><span class="react-syntax-highlighter-line-number">2 </span><span class="react-syntax-highlighter-line-number">3 </span><span class="react-syntax-highlighter-line-number">4 </span><span class="react-syntax-highlighter-line-number">5 </span><span class="react-syntax-highlighter-line-number">6 </span><span class="react-syntax-highlighter-line-number">7 </span><span class="react-syntax-highlighter-line-number">8 </span><span class="react-syntax-highlighter-line-number">9 </span><span class="react-syntax-highlighter-line-number">10 </span><span class="react-syntax-highlighter-line-number">11 </span><span class="react-syntax-highlighter-line-number">12 </span><span class="react-syntax-highlighter-line-number">13 </span><span class="react-syntax-highlighter-line-number">14 </span><span class="react-syntax-highlighter-line-number">15 </span><span class="react-syntax-highlighter-line-number">16 </span><span class="react-syntax-highlighter-line-number">17 </span><span class="react-syntax-highlighter-line-number">18 </span><span class="react-syntax-highlighter-line-number">19 </span><span class="react-syntax-highlighter-line-number">20 </span><span class="react-syntax-highlighter-line-number">21 </span><span class="react-syntax-highlighter-line-number">22 </span><span class="react-syntax-highlighter-line-number">23 </span><span class="react-syntax-highlighter-line-number">24 </span><span class="react-syntax-highlighter-line-number">25 </span><span class="react-syntax-highlighter-line-number">26 </span><span class="react-syntax-highlighter-line-number">27 </span><span class="react-syntax-highlighter-line-number">28 </span><span class="react-syntax-highlighter-line-number">29 </span></code><code style="color: black; background: none; text-shadow: white 0px 1px; font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; text-align: left; white-space: pre; word-spacing: normal; word-break: normal; overflow-wrap: normal; line-height: 1.5; tab-size: 4; hyphens: none;"><span class="token" style="color: rgb(0, 119, 170);">const</span> <span class="token maybe-class-name">RuTracker</span> <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(221, 74, 104);">require</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'./js/rutracker.js'</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> fs <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(221, 74, 104);">require</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'fs'</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> port <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(153, 0, 85);">3007</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(221, 74, 104);">require</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'./js/serv.js'</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">(</span>port<span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token dom" style="color: rgb(238, 153, 0);">document</span> <span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">querySelector</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'#searchSubmit'</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">addEventListener</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'click'</span><span class="token" style="color: rgb(153, 153, 153);">,</span> <span class="token" style="color: rgb(0, 119, 170);">async</span> <span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token arrow" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=></span> <span class="token" style="color: rgb(153, 153, 153);">{</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> searchStr <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token dom" style="color: rgb(238, 153, 0);">document</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">querySelector</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'#searchStr'</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">value</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">toLowerCase</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">try</span> <span class="token" style="color: rgb(153, 153, 153);">{</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> result <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(0, 119, 170);">await</span> <span class="token maybe-class-name">RuTracker</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);"><span class="token maybe-class-name">Search</span></span><span class="token" style="color: rgb(153, 153, 153);">(</span>searchStr<span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> items <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> result <span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">playlist</span> <span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">map</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token parameter">x</span> <span class="token arrow" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=></span> <span class="token template-string"><span class="token template-punctuation" style="color: rgb(102, 153, 0);">`</span><span class="token" style="color: rgb(102, 153, 0);"><div class="searchItem" onClick="listTracks('</span><span class="token interpolation"><span class="token interpolation-punctuation" style="color: rgb(153, 153, 153);">${</span>x<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">permalink_url</span><span class="token interpolation-punctuation" style="color: rgb(153, 153, 153);">}</span></span><span class="token" style="color: rgb(102, 153, 0);">')"></span><span class="token interpolation"><span class="token interpolation-punctuation" style="color: rgb(153, 153, 153);">${</span>x<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">title</span><span class="token interpolation-punctuation" style="color: rgb(153, 153, 153);">}</span></span><span class="token" style="color: rgb(102, 153, 0);"></div></span><span class="token template-punctuation" style="color: rgb(102, 153, 0);">`</span></span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token dom" style="color: rgb(238, 153, 0);">document</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">querySelector</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'#searchOutput'</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">innerHTML</span> <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> items<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">join</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">''</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(153, 153, 153);">}</span> <span class="token" style="color: rgb(0, 119, 170);">catch</span> <span class="token" style="color: rgb(153, 153, 153);">(</span>ex<span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token" style="color: rgb(153, 153, 153);">{</span> <span class="token console" style="color: rgb(221, 74, 104);">console</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">error</span><span class="token" style="color: rgb(153, 153, 153);">(</span>ex<span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(153, 153, 153);">}</span> <span class="token" style="color: rgb(153, 153, 153);">}</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> <span class="token function-variable" style="color: rgb(221, 74, 104);">listTracks</span> <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(0, 119, 170);">async</span> <span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token parameter">url</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token arrow" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=></span> <span class="token" style="color: rgb(153, 153, 153);">{</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> tracks <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(0, 119, 170);">await</span> <span class="token maybe-class-name">RuTracker</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);"><span class="token maybe-class-name">TrackerFiles</span></span><span class="token" style="color: rgb(153, 153, 153);">(</span>url<span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> items <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> tracks<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">map</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token parameter">x</span> <span class="token arrow" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=></span> <span class="token template-string"><span class="token template-punctuation" style="color: rgb(102, 153, 0);">`</span><span class="token" style="color: rgb(102, 153, 0);"><div class="searchItem" onClick="playTrack(`</span><span class="token interpolation"><span class="token interpolation-punctuation" style="color: rgb(153, 153, 153);">${</span>x<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">trackPath</span><span class="token interpolation-punctuation" style="color: rgb(153, 153, 153);">}</span></span><span class="token" style="color: rgb(102, 153, 0);">`, '</span><span class="token interpolation"><span class="token interpolation-punctuation" style="color: rgb(153, 153, 153);">${</span>x<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">magnet</span><span class="token interpolation-punctuation" style="color: rgb(153, 153, 153);">}</span></span><span class="token" style="color: rgb(102, 153, 0);">')"></span><span class="token interpolation"><span class="token interpolation-punctuation" style="color: rgb(153, 153, 153);">${</span>x<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">title</span><span class="token interpolation-punctuation" style="color: rgb(153, 153, 153);">}</span></span><span class="token" style="color: rgb(102, 153, 0);"></div></span><span class="token template-punctuation" style="color: rgb(102, 153, 0);">`</span></span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token dom" style="color: rgb(238, 153, 0);">document</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">querySelector</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'#searchOutput'</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">innerHTML</span> <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> items<span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">join</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">''</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token console" style="color: rgb(221, 74, 104);">console</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">log</span><span class="token" style="color: rgb(153, 153, 153);">(</span>tracks<span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(153, 153, 153);">}</span> <span class="token" style="color: rgb(0, 119, 170);">const</span> <span class="token function-variable" style="color: rgb(221, 74, 104);">playTrack</span> <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token" style="color: rgb(0, 119, 170);">async</span> <span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token parameter">trackPath<span class="token" style="color: rgb(153, 153, 153);">,</span> magnet</span><span class="token" style="color: rgb(153, 153, 153);">)</span> <span class="token arrow" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=></span> <span class="token" style="color: rgb(153, 153, 153);">{</span> <span class="token dom" style="color: rgb(238, 153, 0);">document</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token method property-access" style="color: rgb(221, 74, 104);">querySelector</span><span class="token" style="color: rgb(153, 153, 153);">(</span><span class="token" style="color: rgb(102, 153, 0);">'#audioOutput'</span><span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token" style="color: rgb(153, 153, 153);">.</span><span class="token property-access">src</span> <span class="token" style="color: rgb(154, 110, 58); background: rgba(255, 255, 255, 0.5);">=</span> <span class="token template-string"><span class="token template-punctuation" style="color: rgb(102, 153, 0);">`</span><span class="token" style="color: rgb(102, 153, 0);">http://localhost:</span><span class="token interpolation"><span class="token interpolation-punctuation" style="color: rgb(153, 153, 153);">${</span>port<span class="token interpolation-punctuation" style="color: rgb(153, 153, 153);">}</span></span><span class="token" style="color: rgb(102, 153, 0);">/trackerStream?trackPath=</span><span class="token interpolation"><span class="token interpolation-punctuation" style="color: rgb(153, 153, 153);">${</span>trackPath<span class="token interpolation-punctuation" style="color: rgb(153, 153, 153);">}</span></span><span class="token" style="color: rgb(102, 153, 0);">&magnet=</span><span class="token interpolation"><span class="token interpolation-punctuation" style="color: rgb(153, 153, 153);">${</span><span class="token" style="color: rgb(221, 74, 104);">encodeURIComponent</span><span class="token" style="color: rgb(153, 153, 153);">(</span>magnet<span class="token" style="color: rgb(153, 153, 153);">)</span><span class="token interpolation-punctuation" style="color: rgb(153, 153, 153);">}</span></span><span class="token template-punctuation" style="color: rgb(102, 153, 0);">`</span></span><span class="token" style="color: rgb(153, 153, 153);">;</span> <span class="token" style="color: rgb(153, 153, 153);">}</span> |
This file can be used for a simple search and audio output.
To Wrap Up
I have provided an example of how easy it can be to create a torrent player of some kind. Sure, it has some issues, such as the search sometimes does not work or huge files are opened slowly. Yet, it is just a POC, and most of these problems can be solved.
You can find code here: https://github.com/demogoran/ElectroPlay
Do you have an idea for a project?
If there is something you need assistance with, we will be happy to share our experience or to help you implement the idea!