【问题标题】:set_sequential_download() and set_piece_deadline() in libtorrentlibtorrent 中的 set_sequential_download() 和 set_piece_deadline()
【发布时间】:2015-11-26 16:49:55
【问题描述】:

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

我看到人们在论坛上提出这个问题,但他们都没有很好地回答需要进行哪些更改才能成功。

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

** 更新

我要实现的目标是一次下载一个,这样我就可以通过种子进行流式传输。

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

【问题讨论】:

    标签: python p2p libtorrent libtorrent-rasterbar


    【解决方案1】:

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

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

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

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

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

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

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

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

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

    更新:

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

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

    【讨论】:

    • 嘿 Arvid,首先感谢您的帮助。第二,恐怕我不太明白你的意思。我不想通过 HTTP 流式传输,(libtorrent 是这样做的吗?)我只想操作代码,以便 libtorrent 按顺序下载片段,这意味着在第 1 部分完成下载之前,第 2 部分不会完全下载.
    • 您必须了解 (1) 请求数据和 (2) 接收您请求的某些数据块的最后一个字节之间的区别。 libtorrent 只能控制 (1),但它可以巧妙地选择对等节点,以使 (2) 可能按顺序发生。但是没有办法保证。同行越多,费率和波动越多,完成的有序件就越少。为了解决您的实际问题,您可能需要考虑真正重要的是什么以及如何最大限度地提高成功的可能性。 (请更新您的问题以包括您要完成的任务)
    【解决方案2】:

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

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

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

    Peerflix 背后的天才在于它尝试通过自己的 Web 服务器提供视频文件,因此知道 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 中收到该片段的原始二进制数据。

    【讨论】:

      猜你喜欢
      • 2021-02-01
      • 2014-04-27
      • 2020-04-07
      • 1970-01-01
      • 2019-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多