libtorrent icon indicating copy to clipboard operation
libtorrent copied to clipboard

libtorrent coupled with libVLC for video streaming

Open 3unjee opened this issue 10 months ago • 3 comments

Greetings,

I'm using libtorrent 2.x in conjunction with libVLC to achieve peer to peer streaming. I'm starting a local http server that feeds the pieces data to a libVLC instance while prioritizing them depending on the seeking point.

I'm aware that's not necessarily the default mode for the library. I was wondering if I could get recommendations on how to configure libtorrent in order to achieve the following:

  • Quick magnet opening
  • Boosted torrent startup times
  • Efficient linear downloading / streaming

At the moment I'm using the following:

pack.set_bool(settings_pack::enable_dht, true);
pack.set_bool(settings_pack::enable_lsd, true);

pack.set_bool(settings_pack::enable_upnp,   true);
pack.set_bool(settings_pack::enable_natpmp, true);

pack.set_bool(settings_pack::smooth_connects, false);

// NOTE: We want to connect really fast to stream the content early.
pack.set_int(settings_pack::connection_speed,      200);
pack.set_int(settings_pack::torrent_connect_boost, 100);

pack.set_int(settings_pack::min_reconnect_time,   1);
pack.set_int(settings_pack::peer_connect_timeout, 3);

pack.set_int(settings_pack::piece_timeout,   10);
pack.set_int(settings_pack::request_timeout, 10);

pack.set_int(settings_pack::peer_timeout,    10);
pack.set_int(settings_pack::urlseed_timeout, 10);

// NOTE: These are important to avoid issues when redirecting data to a third party, like
//       avoiding glitchy frames on a video player.
pack.set_int(settings_pack::cache_size,   0);
pack.set_int(settings_pack::cache_expiry, 0);

I have multiplatform constraints and things should work well on broadband on a PC and 4G on a cellphone.

Thank you.

3unjee avatar Apr 29 '24 17:04 3unjee

Greetings,

I'm using libtorrent 2.x in conjunction with libVLC to achieve peer to peer streaming. I'm starting a local http server that feeds the pieces data to a libVLC instance while prioritizing them depending on the seeking point.

I'm aware that's not necessarily the default mode for the library.

Don't worry this is actually a popular use case!

I was wondering if I could get recommendations on how to configure libtorrent in order to achieve the following:

  • Quick magnet opening
  • Boosted torrent startup times
  • Efficient linear downloading / streaming

At the moment I'm using the following:

pack.set_bool(settings_pack::enable_dht, true);
pack.set_bool(settings_pack::enable_lsd, true);

pack.set_bool(settings_pack::enable_upnp,   true);
pack.set_bool(settings_pack::enable_natpmp, true);

pack.set_bool(settings_pack::smooth_connects, false);

// NOTE: We want to connect really fast to stream the content early.
pack.set_int(settings_pack::connection_speed,      200);
pack.set_int(settings_pack::torrent_connect_boost, 100);

pack.set_int(settings_pack::min_reconnect_time,   1);
pack.set_int(settings_pack::peer_connect_timeout, 3);

pack.set_int(settings_pack::piece_timeout,   10);
pack.set_int(settings_pack::request_timeout, 10);

pack.set_int(settings_pack::peer_timeout,    10);
pack.set_int(settings_pack::urlseed_timeout, 10);

// NOTE: These are important to avoid issues when redirecting data to a third party, like
//       avoiding glitchy frames on a video player.
pack.set_int(settings_pack::cache_size,   0);
pack.set_int(settings_pack::cache_expiry, 0);

I have multiplatform constraints and things should work well on broadband on a PC and 4G on a cellphone.

Thank you.

These micro optimizations are fine but you're missing the big picture.

A good start would be reading the documentation on streaming. But then you'd run into problems with set_piece_deadline due to its performance issues. Current best practice, as established by the master programmer Oleg, is to set the torrent to sequential download mode and use set_piece_deadline sparingly, as in the first 1 to 5 pieces after seeking.

(There is more background on this if you have the time: #6272 #6293 #4408 #6273 #7337)

Though I'm thinking now, since your use case is streaming, are you sure about using libtorrent? As you can tell by these issues and the special incantations you have to go through, libtorrent is not ideal for the streaming use case (plus it is not really actively maintained anymore. And the 2.x releases have their own long running problems.)

Have you tried anacrolix/torrent? Streaming is actually one of its documented use cases that it is optimized for, and though it is not as scalable as libtorrent 1.2 in terms of the number of torrents it can handle at a time, this doesn't matter for your use case of a streaming p2p video player. Plus it has a DLNA server written for it by the author, as well as many HTTP streaming servers using it, some by the author as well.

SemiAccurate avatar Apr 30 '24 04:04 SemiAccurate

@SemiAccurate Thank you for this post with interesting resources and references, I appreciate it.

At this point I find it a bummer that there's no maintained C++ boiler plate on how to achieve streaming with libtorrent. I've been using the library for a while, it's quite fantastic, but implementing a video streamer has been a fairly empircal / mysterious process. Although, wen it works - and the peering is decent - the experience is substantial. Often felt like VLC resilient streaming approach and peer to peer were meant to be.

Regarding your anacrolix torrent project, it seems written in go and too high level for what I'm trying to do.

3unjee avatar May 01 '24 09:05 3unjee

@3unjee Don't know if that would help you, but there are at least few OSS examples of streaming apps, that use libtorrent:

  • https://github.com/ElementumOrg/lt2http
  • https://github.com/i96751414/torrest-cpp

You can easily start a webserver on a random port, that would proxy to a streaming, then point VLC to that port/endpoint to run the stream.

elgatito avatar May 10 '24 08:05 elgatito