Magnet URIs are a convenient way to share torrents without having to host a .torrent file. However, sometimes you might need to inspect the contents of a torrent before you start downloading it, or you might want to save the .torrent file for later use.
In this post, we'll explore how to use Node.js and the webtorrent library to convert a magnet URI into a .torrent file and traverse the list of files it contains.
Prerequisites
Before we start, make sure you have Node.js and npm installed on your system.
Setting up the Project
First, let's set up a new Node.js project. Open your terminal and run the following commands:
mkdir magnet-converter
cd magnet-converter
npm init -y
npm install webtorrent
This will create a new directory, initialize a Node.js project, and install the webtorrent library.
The Code
Now, create a file named index.js and add the following code:
const WebTorrent = require('webtorrent');
const fs = require('fs');
const path = require('path');
const client = new WebTorrent();
/**
* Converts a magnet URI to a .torrent file and traverses its files.
* @param {string} magnetURI The magnet URI to process.
* @param {string} [outputDir='./torrents'] The directory to save the .torrent file.
*/
async function processMagnetURI(magnetURI, outputDir = './torrents') {
if (!magnetURI) {
console.error('Error: No magnet URI provided.');
console.log('Usage: node index.js "magnet:?xt=urn:btih:..." [output_directory]');
client.destroy();
return;
}
// Ensure output directory exists
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
console.log(`Adding magnet URI: ${magnetURI}`);
client.add(magnetURI, (torrent) => {
console.log(`Torrent "${torrent.name}" added.`);
torrent.on('metadata', () => {
console.log('Metadata received.');
// Save the .torrent file
const torrentFilePath = path.join(outputDir, `${torrent.name}.torrent`);
fs.writeFile(torrentFilePath, torrent.toTorrentFile(), (err) => {
if (err) {
console.error(`Error saving .torrent file: ${err.message}`);
} else {
console.log(`Saved .torrent file to: ${torrentFilePath}`);
}
});
console.log('\n--- Files in Torrent ---');
if (torrent.files.length === 0) {
console.log('No files found in this torrent.');
} else {
torrent.files.forEach((file, index) => {
console.log(`File ${index + 1}:`);
console.log(` Name: ${file.name}`);
console.log(` Path: ${file.path}`);
console.log(` Size: ${file.length} bytes`);
});
}
client.destroy(() => {
console.log('WebTorrent client destroyed.');
});
});
torrent.on('error', (err) => {
console.error(`Torrent error: ${err.message}`);
client.destroy();
});
});
}
// Get magnet URI and optional output directory from command line arguments
const magnet = process.argv[2];
const output = process.argv[3];
processMagnetURI(magnet, output);
How it Works
The script uses the webtorrent library to fetch the torrent metadata from the BitTorrent network. Here's a breakdown of what the code does:
- Initialization: It initializes the
webtorrentclient. processMagnetURIfunction: This function takes a magnet URI and an optional output directory as input.client.add: This is the core function that starts the process. It takes the magnet URI and a callback function.metadataevent: Thewebtorrentclient emits ametadataevent when it has fetched the torrent's metadata. This is the point where we have all the information we need.- Saving the
.torrentfile: Inside themetadataevent handler, we usetorrent.toTorrentFile()to get the torrent file data and then save it to a file usingfs.writeFile(). - Traversing files: The
torrent.filesarray contains a list of all the files in the torrent. We can iterate over this array to get information about each file, such as its name, path, and size. - Cleanup: Finally,
client.destroy()is called to close the client and release resources.
Running the Script
To run the script, use the following command in your terminal, replacing "YOUR_MAGNET_URI_HERE" with a valid magnet URI:
node index.js "YOUR_MAGNET_URI_HERE"
For example:
node index.js "magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10&dn=Sintel&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fsintel.torrent"
You can also specify an output directory for the .torrent file:
node index.js "YOUR_MAGNET_URI_HERE" "./my_torrents"
After running the script, you will see the list of files in the torrent printed to the console, and a new .torrent file will be saved in the specified output directory.