【问题标题】:Unable to recombine chunked download of MP3 data无法重新组合 MP3 数据的分块下载
【发布时间】:2014-10-28 17:43:20
【问题描述】:

我正在使用 Perl 和 WWW::Mechanize 下载一个 MP3 文件,该文件以 400KB 的块(大约 20 秒)提供。

当我在文件句柄上使用binmode 保存数据时,在每个块到达时附加它,只有第一个块被正确播放;其余的不是。

当我不使用binmode 时,我无法播放整个文件——它可以播放但听起来很有趣!

这是我的程序

use WWW::Mechanize;

$agent = WWW::Mechanize->new( cookie_jar => {} );

@links = ("http://thehost.com/chunk1","http://thehost.com/chunk2","http://thehost.com/chunk3");

foreach (@links){
    $agent->get($_);

    my $filename = 'test.mp3';
    open(my $fh, '>>', $filename) or die "Could not open file '$filename' $!";
    binmode $fh;
    print $fh $agent->content;
    close $fh;
}

我做错了什么?

更新

这些是返回的 HTTP 标头。

Cache-Control: public
Connection: close
Date: Tue, 28 Oct 2014 18:38:37 GMT
Pragma:
Server: Apache
Content-Length: 409600
Content-Type: application/octet-stream
Expires: Sat, 24 Oct 2015 12:08:00 GMT
Access-Control-Allow-Origin: *
Client-Date: Tue, 28 Oct 2014 18:38:28 GMT
Client-Peer: **.**.***.***:80
Client-Response-Num: 1

【问题讨论】:

  • 我试图理解你的问题并理解到底发生了什么,但你的英语不清楚。问题在于 “当我不使用 binmode 时,我无法播放整个文件” - 您似乎是在说,无论有没有 binmode,只有第一个块可以正确播放.对吗?
  • 第一个文件只用binmode播放

标签: perl file download mp3 binmode


【解决方案1】:

我怀疑提供的内容带有不正确的标头,并且当您使用自动解码的 API 时,这会破坏八位字节流。

请改用mirror 方法,并在下载后连接文件。

【讨论】:

  • 块 2+ 没有标题,我认为文件只是拆分。最后一个块包含像每个 mp3 一样结尾的文件(ªªªªªªªª 等)
  • 那又怎样?你的评论不符合我的回答。
  • 如何连接文件?
  • 使用cat 或在Perl 中使用IO::File
  • @communications:我想你是在评论上面@Steffen Ullrich的解决方案。
【解决方案2】:

我怀疑单个 mp3 文件只是在一定数量的字节后被拆分,然后这些块作为单独的下载提供。相反,我假设这些都是单独的 mp3 文件,其中包含 20 秒的原始文件,并且每个 URL 都包含正确的 mp3 文件。因为 mp3 不是数据,而是标题和数据,所以您不能通过将它们连接在一起来简单地合并这些 mp3 文件。相反,您必须使用 ffmpeg 之类的程序从多个 mp3 文件创建单个 mp3 文件,请参阅https://superuser.com/questions/314239/how-to-join-merge-many-mp3-files

【讨论】:

  • 块 2+ 没有标题,我认为文件只是拆分。最后一个块包含像每个 mp3 一样结尾的文件(ªªªªªªªª 等)
  • 在这种情况下,服务器真正返回的内容会很有趣。尤其是标头中的任何内容编码。您是否尝试使用 wget 获取数据,然后使用 cat 加入它们 - 因为这就是您的 Perl 程序本质上在做的事情。也许数据已损坏?
  • Gibt es eine Möglichkeit sie dierekt zu kontaktieren? Ich möchte hier keine Dateien verteilen, da ich keine eventuellen Urheberechtsprobleme am Hals haben möchte! Ich habe auf ihrer Website leider keine Email-Adresse gefunden...
  • 对于不会讲德语的人,这意味着 “有没有办法直接联系他们?我想分发文件,因为我不希望有任何可能的版权问题!不幸的是我在他们的网站上没有找到电子邮件地址。” @communications:恐怕我们真的无法在不知道真实 URL 的情况下为您提供任何进一步的帮助。请问这样可以吗?
  • 您可以通过 sullr AT cpan DOT org 联系我。
【解决方案3】:

我无法解释你得到的行为,但WWW::Mechanize 用于处理 HTML 文本页面,而不是二进制数据。直接使用LWP::UserAgent 模块一点也不难。

我建议你改用这样的东西。

use strict;
use warnings;
use 5.010;
use autodie;

use LWP;

my @links = qw(
  http://thehost.com/chunk1
  http://thehost.com/chunk2
  http://thehost.com/chunk3
);

my $agent = LWP::UserAgent->new;

my $filename = 'test.mp3';
open my $fh, '>:raw', $filename;

for my $link (@links) {
    my $resp = $agent->get($link);
    die $resp->status_line unless $resp->is_success;
    print $fh $resp->decoded_content;
}

close $fh;

如果还有问题,请添加这样的一行

print $resp->headers_as_string, "\n\n";

get 通话后立即报告您获得的结果。

您也可以通过使用content 方法而不是decoded_content 来获得一些结果。

当然,如果您能提供真实的 URL,它可能对我们有很大帮助,但我知道您可能无法做到这一点。

【讨论】:

  • 你的想法都没有奏效...这是 headers_as_string 结果:pastebin.com/T6K6H04j 这有帮助吗?
  • 三个 URL 的标题是否相同? (显然,除了日期时间。)另外,请您将循环的最后一行更改为 my $content = $resp->decoded_content; print length($content), "\n"; print $fh $content; 并说出您得到的结果。
  • @communications:那里一切都很好。我可以知道 form 或 URL 吗?也许删除了主机名的整个 URL?至于你正在下载的文件,我建议你把它们放在MediaFire 或类似的地方,让我有一个链接。看起来越来越像是您使用的 URL 是错误的,或者数据不是您期望的那样。最好知道第二个和后续的块是否可以自己正确播放?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多