Example of usage - RazielXT/mtTorrent GitHub Wiki
- Initialization
- Torrent instances
- Torrent info
- File progress
- Downloading
- Magnet
- Peers
- Alerts
- Configuration
Repository includes SdkExample project showing usage of mtTorrent C++ API. Shortest downloading code can look like this:
#include "mtTorrent/Api/Core.h"
#include <thread>
#include <chrono>
#include <iostream>
int main()
{
auto core = mttApi::Core::create();
auto[status, torrent] = core->addFile("path/to/torrent/file.torrent");
if (torrent)
{
torrent->start();
while (!torrent->finished())
{
std::cout << torrent->name() << " progress: " << torrent->progress() * 100 << "%%\n";
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
else
std::cout << "Adding torrent failed with error " << (int)status;
}
Whole API interface is available here. As first step, you need to initialize library internals by creating mttApi::Core
object. Core object provides interface for accessing torrents and registering event alerts. Library is deinitialized in Core destructor. Library automatically saves and loads current state during these steps.
auto core = mttApi::Core::create();
You can add new instance of torrent by either Core::addFile
or Core::addMagnet
calls. Calls return pair of Status and if possible (success or torrent already exists) Torrent object instance. In case of torrent file, instance is ready for start. In case of magnet link, metadata download is automatically started.
auto[status, torrent] = core->addFile("path/to/torrent/file.torrent");
auto[status2, torrent2] = core->addMagnet("magnetlink");
Full list of current torrents can be received with call Core::getTorrents
.
auto torrents = core->getTorrents();
for (auto t : torrents)
std::cout << torrent->name() << std::endl;
You can remove torrent, and optionally downloaded files, by calling Core::removeTorrent
with torrent/hash.
core->removeTorrent(torrent, true);
// or
core->removeTorrent(torrent->hash(), true);
Using torrent object, you can access and control its current state. To start downloading call Torrent::start
, to stop downloading or any other active task (as metadata download or file checks) call Torrent::stop
. To find out if torrent was started you can call Torrent::started
. To get information about currently running state use Torrent::getState
.
auto state = torrent->getState();
switch (state)
{
case mttApi::Torrent::State::Active:
break;
case mttApi::Torrent::State::Stopping:
break;
case mttApi::Torrent::State::Stopped:
break;
case mttApi::Torrent::State::CheckingFiles:
break;
case mttApi::Torrent::State::DownloadingMetadata:
default:
break;
}
If torrent fails to continue (file errors e.g.) it automatically switches to state Stopped. To get error code call Torrent::getLastError
.
Torrent files (.torrent) contain all metadata information needed to start downloading. This includes list of files, pieces (segments to be downloaded individually) or creation info. To get parsed torrent file info call Torrent::getMetadata
.
auto& torrentFile = torrent->getMetadata();
if (!torrentFile.about.createdBy.empty())
std::cout << "Torrent created by " << torrentFile.about.createdBy << std::endl;
for (auto& file : torrentFile.info.files)
{
std::cout << "File: " << file.name << std::endl;
std::cout << "File size: " << file.size << std::endl;
//subdirectory
if (!file.path.empty())
{
std::string fileDirectory;
for (auto& p : file.path)
{
fileDirectory += p;
fileDirectory += '/';
}
std::cout << "Directory: " << fileDirectory << std::endl;
}
}
std::cout << "Torrent divided into " << torrentFile.info.pieces.size() << " pieces, with piece size " << torrentFile.info.pieceSize << std::endl;
To get general information about current state of progress you can call methods such as:
-
Torrent::finished
,Torrent::selectionFinished
- all (selected) files in torrent were downloaded -
Torrent::progress
,Torrent::selectionProgress
- progress of downloading in range of 0-1 -
Torrent::finishedBytes
,Torrent::finishedSelectedBytes
- finished sum in bytes -
Files::getProgress
- progress in range of 0-1 for each file separately and count of finished pieces
Use Files object Torrent::getFiles
for detailed files control. By default all torrent files are selected for download. You can get current selection by calling Files::getSelection
and set all by Files::select
or specific file by index Files::select
. Additionally you can select download priority (order) by calling Files::setPriority
.
All files are saved to default download location in mtt::config
. If you want to change this location, call Files::setLocationPath
. If files already exist, they can be moved to new path.
auto& files = torrent->getFiles();
auto selection = files.getSelection();
std::vector<bool> newSelection;
for (const auto& s : selection)
newSelection.push_back(!s.selected);
files.select(newSelection);
//select by index
files.select(5, true);
files.setPriority(4, mtt::PriorityHigh);
files.setLocationPath("path/to/new/download/path", true);
if (!torrent->selectionFinished())
std::cout << "Selection progress: " << torrent->selectionProgress() * 100 << "%%\n";
If there is any detected change to saved files outside of the library, they will need to be checked before torrent can start. You can get current check progress with Files::checkingProgress
. Check can be also forced by calling Files::startCheck
.
You can check current downloading state information with mttApi::FileTransfer
object, which is accessible through Torrent::getFileTransfer
. It contains information about current transfer speeds, connected peers and active requests.
auto& transfer = torrent->getFileTransfer();
std::cout << "Current download speed: " << transfer.downloadSpeed() << " bytes per second" << std::endl;
std::cout << "Currently downloading " << transfer.getCurrentRequests().size() << " pieces" << std::endl;
In case torrent is added using magnet link, torrent file metadata needs to be downloaded from other peers before download can start. You can access metadata download progress information using mttApi::MetadataDownload
from Torrent::getMetadataDownload
. If there is no magnet information, this object is nullptr. You can check current state using MetadataDownload::getState
. Object also offers readable logs using MetadataDownload::getDownloadLog
.
if (auto magnet = torrent->getMetadataDownload())
{
mtt::MetadataDownloadState state = magnet->getState();
if (!state.finished && state.partsCount)
std::cout << "Metadata progress " << state.receivedParts << "/" << state.partsCount << std::endl;
std::vector<std::string> logs;
if (auto count = magnet->getDownloadLog(logs))
{
for (auto& log : logs)
std::cout << "Metadata log: " << log << std::endl;
}
}
Information about finding peers can be accessed using mttApi::Peers
from Torrent::getPeers
. To get information about all peer sources call Peers::getSourcesInfo
. This includes trackers, DHT, PEX (peers exchange) and remotely connected peers.
auto& peers = torrent->getPeers();
std::cout << "Found peers " << peers.receivedCount() << std::endl;
std::cout << "Connected peers " << peers.connectedCount() << std::endl;
auto peersInfo = peers.getConnectedPeersInfo();
for (const auto& peer : peersInfo)
std::cout << "Address " << peer.address << ", speed " << peer.stats.downloadSpeed << ", torrent client " << peer.client << std::endl;
auto sources = peers.getSourcesInfo();
for (const auto& source : sources)
{
if (source.state >= mtt::TrackerState::Connected)
std::cout << source.hostname << " has " << source.peers << " peers" << std::endl;
}
//force refresh
peers.refreshSource(sources.front().hostname);
//connect locally running client
peers.connect("127.0.0.1:55555");
Peers can provide information about peer country based on its address. To use this feature, library needs compiled file with ip country list in application Data folder (see mtt::config::Internal::programFolderPath
).
You can register to be notified about some events. To register to Alerts about events call Core::registerAlerts
with flags where you logical OR all wanted mtt::AlertId
alert types. To check for occurred alerts, you need to periodically call Core::popAlerts
. Based on alert id, mtt::AlertMessage
can be cast to specific message subtype.
core->registerAlerts(mtt::Alerts::Id::MetadataInitialized | mtt::Alerts::Category::Torrent);
//...
auto alerts = core->popAlerts();
for (auto& alert : alerts)
{
if (alert->id == mtt::Alerts::Id::MetadataInitialized)
{
std::cout << alert->getAs<mtt::MetadataAlert>()->torrent->name() << " metadata loaded" << std::endl;
}
else if (alert->id == mtt::Alerts::Id::TorrentAdded)
{
std::cout << alert->getAs<mtt::TorrentAlert>()->torrent->name() << " added" << std::endl;
}
}
To configure library parameters, configuration is accessible through mtt::config
namespace. There are 2 types of configurations, Internal and External. They can be configured by calling mtt::config::setValues
. Settings are saved/loaded automatically. Besides client identification (hashId), Internal settings are not saved and if needed should be configured before Core
creation.
auto internalSetting = mtt::config::getInternal();
internalSetting.stateFolder = "./State/";
mtt::config::setInternalValues(internalSetting);
auto core = mttApi::Core::create();
...
auto settings = mtt::config::getExternal();
settings.files.defaultDirectory = "./";
mtt::config::setValues(settings.files);
settings.dht.enabled = true;
mtt::config::setValues(settings.dht);