libtorrent中的set_sequential_download()和set_piece_deadline()

时间:2015-11-26 16:49:55

标签: python p2p libtorrent libtorrent-rasterbar

我正在制作我的项目,即通过libtorrent制作流媒体客户端。 我正在使用python客户端(python绑定)。 我搜索了很多关于这些函数的信息 set_sequential_download() set_piece_deadline(),我找不到如何按顺序强制下载文件的好答案,这意味着第一部分1然后2,3,4等。

我看到有人在论坛上提出这个问题,但他们都没有得到关于需要做出改变才能成功的好答案。

我知道 set_sequential_download()只是按顺序询问这些部分,但事实上它们是随机下载的。我试图使用 set_piece_deadline()更改各个部分的截止日期,增加每个部分,但它根本不适合我。

**更新

我试图完成的目标是,它一次下载一件作品,这样我就可以制作流媒体的throgh种子。

我希望你们中的一些人可以帮助我, 谢谢Ben。

2 个答案:

答案 0 :(得分:1)

set_sequential_download()将按顺序请求件。但是:

  • 所有同行可能没有所有作品。如果你要下载的下一篇文章是3,而你的一个同行没有3,但是下一篇文章是5,那么libtorrent将开始从该对等方的第5篇请求块。
  • peer提供不同的上传速率,这意味着某些同伴会比其他人更快地满足您的请求。

这使得碎片可以无序完成。

set_piece_deadline()是一种更灵活的方式来指定作品优先级。它支持任意范围请求(如Jacob Zelek所述)。但它的主要特点是它使用不同的方法来请求块。它不是一次考虑一个对等体,而是要求我应该从这个对等体那里请求什么,它一次只考虑一块,要求"我应该从哪个对等体请求这个块#34;

这使得它故意尝试按照截止日期的顺序完成作品。它仍然是基于同行的历史下载速率的估计,如果下载速率的瓶颈是您自己的下载容量,则可能很难预测同行的未来下载速率。使用`set_piece_deadline()``API时要记住的一些重要事项是:

  • 截止日期是将来的重要性并不重要。如果在当前下载或上传容量的情况下无法满足截止日期,则会按照要求完成的顺序对这些部分进行优先排序。
  • 如果未来的截止日期很长,libtorrent可能会等待它的优先顺序,直到它认为需要请求截止日期为止。如果您正在流式传输大型文件,并且您知道比特率,则可以设置每个部分的截止日期,如果您的容量高于比特率,您仍然会要求最新的部分 - 第一个订单。提高群体质量。
  • 在传输数据时,预读绝对至关重要。如果您没有设定截止日期,直到您想要这件作品,您将永远落后。在请求一件作品并完成它之间通常需要相当长的往返时间。如果您没有将请求管道保留在截止日期之内,libtorrent将再次开始请求其他部分,并且您将获得与您的高优先级部分交错的非优先级部分。你应该保持几秒钟,至少几件作为预读。对于视频,我认为数十兆字节是合适的(但实验和测量是调整它的最佳方式)。

如果您实际上希望通过HTTP将视频流式传输到播放器或网络浏览器,您可能需要查看(或使用并提交拉取请求):

https://github.com/arvidn/libtorrent-webui/blob/master/src/file_downloader.cpp

这是一个适合该存储库中简单http框架的文件下载程序提供程序。

<强>更新

如果您想要的是保证第1部分在第2部分之前完成(不惜任何代价,特别是非常差的性能),您可以将所有部分的优先级设置为0,除了您要下载的部分。一旦完成,您将收到警报通知,您可以设置下一件作品的优先级1.依此类推。

这将非常慢,因为您将不断地暂停下载,并处于持续的最终游戏模式(如果速度很慢,您可以从多个对等点下载相同的块)。例如,如果您有多个对等体而不是一个块中的块,则由于无法向所有对等体请求,您将不使用下载带宽。

答案 1 :(得分:0)

我遇到了和你一样的问题。将torrent设置为顺序下载意味着将以有些有序的方式下载这些片段。这可能是流媒体的直观解决方案。但是,流媒体视频比按顺序下载所有部分要复杂得多。

视频文件有不同的容器(例如mkv,mp4,avi)和不同的代码(h264,theora等)。某些编解码器/容器将元数据/标头存储在文件中的不同位置。我不记得我的头脑,但某个容器/编解码器将所有标题信息存储在文件的末尾。如果顺序下载,这样的文件可能无法正常流式传输。

除非您编写用于确定开始流式传输需要哪些部分的代码,否则您将不得不依赖现有机制。以Peerflix为例,它生成了Mplayer的浏览器视频播放器VLC。这些应用程序很好地了解了各种容器/编解码器所需的字节范围。当Peerflix启动VLC播放时,比方说,AVI文件,VLC将尝试读取前几个字节并持续几个字节(标题)。

Peerflix背后的天才是它试图通过它自己的网络服务器提供视频文件,因此知道VLC正在寻找的文件的字节范围。然后,它确定字节范围落入哪些部分并对这些部分进行优先级排序。 Peerflix使用了一些Node.js BitTorrent库,其确切的片段优先级排序机制对我来说是未知的。但是,对于libtorrent-rasterbar,set_piece_deadline()函数允许您向库发信号通知您需要哪些部分。根据我的经验,一旦我确定了所需的部分,我会在短期限(50ms左右)内调用set_piece_deadline()并等待到达。请注意,使用set_piece_dealine()与顺序下载不兼容(只需将它们设置为false)。

有一点需要注意,libtorrent-rasterbar一旦获得它就不会将该部分写入硬盘。这是我陷入的陷阱,因为我试图在文件到达时从文件中读取该字节范围。为此,您需要运行一个线程来捕获libtorrent-rasterbar传递给您的应用程序的警报。更具体地说,您将在read_piece_alert中收到该片段的原始二进制数据。