#!/usr/local/bin/perl
use strict;
use warnings;
use utf8;
use Encode;
use FindBin;
use LWP::UserAgent;
use XML::Simple;
use Data::Dumper;
## NHKゴガク https://www2.nhk.or.jp/gogaku/english/
my $MUSIC_OUT_DIR = $FindBin::Bin;
my $MUSIC_LIST_ROOT = 'https://www2.nhk.or.jp/gogaku/st/xml';
my $MUSIC_LIST_CHANNELS =
{english=>[
'enjoy', #エンジョイ・シンプル・イングリッシュ
'basic1', #基礎英語1
'basic2', #基礎英語2
'basic3', #基礎英語3
'kaiwa', #ラジオ英会話
'timetrial', #英会話タイムトライアル
'kouryaku', #攻略!英語リスニング
'business1', #入門ビジネス英語
'business2', #実践ビジネス英語
],
};
# There are some paramaters
# in https://www2.nhk.or.jp/gogaku/st/flash/sound/ggk_str_pc3.swf , below.
# You can extract from swf file
# by Flare ( http://www.nowrap.de/flare.html ).
my $MUSIC_FILE_ROOT = 'rtmpe://flvs.nhk.or.jp:1935/ondemand';
my $MUSCI_FILE_SUB_PATH = 'mp4:flv/gogaku-stream/mp4';
my $RTMPDUMP_CMD = '/usr/local/bin/rtmpdump';
my $FFMPEG_CMD = '/usr/bin/ffmpeg';
main(@ARGV);
sub main {
my (@cmd_args) = @_;
for my $lang (sort keys %$MUSIC_LIST_CHANNELS ){
for my $channel (@{$MUSIC_LIST_CHANNELS->{$lang}}){
## DOWNLOAD CHANNEL INFOS
my $channel_infos = get_music_list($lang,$channel);
next if(ref($channel_infos) ne 'ARRAY' or
scalar(@$channel_infos) ==0 );
my $out_dir = get_output_dir($lang,$channel);
for my $channel_info ( @$channel_infos ){
## DOWNLOAD MUSIC FILE by rtmpdump
my $music_file = get_music_file($channel_info, $out_dir);
next unless $music_file;
## CORRECT by ffmpeg
my $mp4_file = conv_to_mp4($music_file);
print Encode::encode('utf8',"DONE $mp4_file"),"\n";
unlink $music_file or die "$music_file$!";
}
}
}
}
sub conv_to_mp4 {
my($org_file) = @_;
my $new_file = "$org_file.mp4";
my $cmd = "$FFMPEG_CMD -loglevel error -y -i $org_file $new_file";
my $fh;
unless( open $fh, '-|', $cmd ){
print STDERR Encode::encode('utf8',"fail open $cmd"),"\n";
return;
}
unless( close($fh) ){
print STDERR Encode::encode('utf8',"fail close $cmd"),"\n";
return;
}
return $new_file;
}
sub get_output_dir {
my($lang,$channel) = @_;
my $out_dir_0 = join('/',$MUSIC_OUT_DIR,$lang);
if(not -d $out_dir_0){
mkdir $out_dir_0 or die "fail mkdir $out_dir_0 $!";
}
return $out_dir_0;
# my $out_dir = join('/',$MUSIC_OUT_DIR,$lang,$channel);
# if(not -d $out_dir ){
# mkdir $out_dir or die "fail mkdir $out_dir $!";
# }
# return $out_dir;
}
sub get_music_file {
my ($channel_info, $out_dir) = @_;
my $url = join('/',
$MUSIC_FILE_ROOT,
$MUSCI_FILE_SUB_PATH,
$channel_info->{file});
my $out_file = join('/',
$out_dir,
"$channel_info->{title}_$channel_info->{hdate}");
my $cmd = "$RTMPDUMP_CMD --quiet -r $url -o $out_file";
my $fh;
unless( open $fh, '-|', $cmd ){
print STDERR Encode::encode('utf8',"fail open $cmd"),"\n";
return;
}
unless( close($fh) ){
print STDERR Encode::encode('utf8',"fail close $cmd"),"\n";
return;
}
return $out_file;
}
sub get_music_list {
my ($lang, $channel) = @_;
my $url = join('/',$MUSIC_LIST_ROOT,$lang, $channel,'listdataflv.xml');
my $ua = LWP::UserAgent->new;
my $res = $ua->get($url);
if(not $res->is_success ) {
print STDERR $res->status_line , " $url\n";
return [];
}
my $xml_content = $res->content;
$xml_content = Encode::decode('utf8',$xml_content);
my $ret = XML::Simple::XMLin($xml_content);
return $ret->{music};
}