我使用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
答案 0 :(得分:1)
我怀疑内容是使用不正确的标头提供的,当您使用自动解码的API时,这会破坏八位字节流。
使用mirror
方法代替并在下载后连接文件。
答案 1 :(得分:1)
我怀疑单个mp3文件是在一定数量的字节之后拆分的,然后这些块作为单独的下载提供。相反,我假设这些是每个单独的mp3文件,其中包含20秒的原始文件,每个URL包含一个正确的mp3文件。因为mp3不是数据而是标题和数据,你不能通过将它们连接在一起来简单地合并这些mp3文件。相反,您必须使用像ffmpeg这样的程序从多个mp3文件创建单个mp3文件,请参阅https://superuser.com/questions/314239/how-to-join-merge-many-mp3-files
答案 2 :(得分:1)
我无法解释您所获得的行为,但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
获得一些结果。
当然,如果您可以提供真实的网址,它可能会对我们提供很多帮助,但我知道您可能无法做到这一点。