1

我正在研究我的项目,该项目是通过 libtorrent 制作流媒体客户端。我正在使用 python 客户端(python 绑定)。我对这些函数set_sequential_download()set_piece_deadline()进行了很多搜索,但我找不到关于如何强制按顺序下载片段的好答案,这意味着首先是 1,然后是 2、3、4 等。

我看到人们在论坛上问这个问题,但没有一个人能很好地回答需要做哪些改变才能成功。

我知道set_sequential_download()只是按顺序要求这些片段,但实际上它们是随机下载的。我尝试使用set_piece_deadline()更改作品的截止日期,增加每件作品,但它对我根本不起作用。

** 更新

我试图实现的目标是一次下载一个,这样我就可以制作一个流式传输种子。

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

4

2 回答 2

2

set_sequential_download()将按顺序要求件。然而:

  • 并非所有同行都拥有所有作品。如果您要下载的下一个片段是 3,而您的一个对等节点没有 3,但下一个是 5,则 libtorrent 将开始从该对等节点请求来自第 5 个片段的块。
  • 对等点提供不同的上传速率,这意味着一些对等点会比其他对等点更快地满足您的请求。

这使得零件可以无序完成。

set_piece_deadline()是一种更灵活的方式来指定件优先级。它支持任意范围请求(如 Jacob Zelek 所述)。不过,它的主要特点是它使用不同的方法来请求块。它不是一次考虑一个对等点,而是询问“我应该从这个对等点请求什么”,而是一次考虑一个块,询问“我应该从哪个对等点请求这个块”。

这使得它故意尝试按照截止日期的顺序完成作品。它仍然是基于对等点的历史下载率的估计,如果下载率的瓶颈是你自己的下载能力,那么对对等点未来的下载率进行预测可能会非常困难。使用 `set_piece_deadline()` API 时要记住的一些重要事项是:

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

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

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

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

更新:

如果您只想保证片段 1 在片段 2 之前完成(不惜一切代价,特别是性能非常差),您可以将所有片段的优先级设置为 0,除了您要下载的片段。完成后,您将收到警报通知,您可以将下一个您想要的优先级设置为 1。依此类推。

这将非常慢,因为你会不断地暂停下载,并处于不断的游戏结束模式(如果一个速度很慢,你可以从多个对等点下载相同的块)。例如,如果您的对等点多于一个块中的块数,您将无法从所有对等点请求下载带宽。

于 2015-11-27T21:30:20.333 回答
1

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

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

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

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

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

于 2015-11-27T11:06:51.420 回答