aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzakflash <zakflashvideo@gmail.com>2013-02-24 11:23:11 -0800
committerzakflash <zakflashvideo@gmail.com>2013-02-24 11:23:11 -0800
commit9856e41fd340d82aebe104aea131d5398da488d4 (patch)
treef92023c97684d615d05d122986437fa127f07f35
parentb9ac7e782b27f13bfa3798b05f99158a8187ef94 (diff)
parentae97f252e719faf9ac955399b6a875f6bcf1b95e (diff)
downloadget-flash-videos-9856e41fd340d82aebe104aea131d5398da488d4.tar.gz
Merge pull request #94 from njtaylor/master
Multiple updates
-rw-r--r--Makefile.PL3
-rwxr-xr-xget_flash_videos11
-rw-r--r--lib/FlashVideo/Site/Channel4.pm55
-rw-r--r--lib/FlashVideo/Site/Itv.pm108
-rw-r--r--lib/FlashVideo/URLFinder.pm4
-rw-r--r--lib/FlashVideo/Utils.pm87
6 files changed, 250 insertions, 18 deletions
diff --git a/Makefile.PL b/Makefile.PL
index 90874d9..0a71188 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -22,6 +22,9 @@ my %mm_vars = (
URI => 0,
'LWP::UserAgent' => 0,
'WWW::Mechanize' => 0,
+ 'LWP::Protocol::https' => 0,
+ 'LWP::Protocol::socks' => 0,
+ 'Module::Find' => 0,
},
);
diff --git a/get_flash_videos b/get_flash_videos
index be99515..8a5c7f6 100755
--- a/get_flash_videos
+++ b/get_flash_videos
@@ -47,8 +47,9 @@ use FlashVideo::VideoPreferences;
unshift @INC, \&plugin_loader;
-our $VERSION = "1.25";
-
+# single line for MakeMaker to get version
+use constant CVERSION => "1.25"; our $VERSION = CVERSION;
+
our %opt;
BEGIN {
my $player = "mplayer -really-quiet";
@@ -84,9 +85,9 @@ BEGIN {
);
}
-use constant VER_INFO => <<EOF;
-get_flash_videos version $VERSION (http://code.google.com/p/get-flash-videos/)
-EOF
+# constant evaluated at compile time, can't use runtime variables.
+use constant VER_INFO =>
+ "get_flash_videos version " . CVERSION . " (http://code.google.com/p/get-flash-videos/)\n";
use constant USAGE => VER_INFO . <<EOF;
diff --git a/lib/FlashVideo/Site/Channel4.pm b/lib/FlashVideo/Site/Channel4.pm
index 84c78ea..9f064df 100644
--- a/lib/FlashVideo/Site/Channel4.pm
+++ b/lib/FlashVideo/Site/Channel4.pm
@@ -11,6 +11,9 @@ use MIME::Base64;
use constant TOKEN_DECRYPT_KEY => 'STINGMIMI';
+our $VERSION = '0.01';
+sub Version() { $VERSION;}
+
sub find_video {
my ($self, $browser, $embed_url, $prefs) = @_;
@@ -55,11 +58,53 @@ sub find_video {
die "Couldn't get asset XML: " . $browser->response->status_line;
}
- my $xml = from_xml($raw_xml);
+ my $xml_ref = from_xml($raw_xml);
+ my $xml;
+
+
+ # Check for mp4 if not then try different assetId
+ my $lower_id = 0;
+ my $upper_id = 9999999;
+ if ($xml_ref->{assetInfo}->{uriData}->{streamUri} !~ /mp4$/ ) {
+ for (my $off = 2; $off < 14; $off++) {
+ my $asset_off = $off >> 1;
+ $asset_off = -$asset_off if ($off & 1);
+ $asset_off += $asset_id;
+ if ($asset_off > $lower_id && $asset_off < $upper_id) {
+ $raw_xml = $browser->get("http://ais.channel4.com/asset/$asset_off");
+ if ($browser->success) {
+ my $xml_off = from_xml($raw_xml);
+ # Check Same programme
+ if ( $xml_off->{assetInfo}->{brandTitle} eq $xml_ref->{assetInfo}->{brandTitle} &&
+ $xml_off->{assetInfo}->{episodeTitle} eq $xml_ref->{assetInfo}->{episodeTitle} &&
+ $xml_off->{assetInfo}->{programmeNumber} eq $xml_ref->{assetInfo}->{programmeNumber}) {
+ if ($xml_off->{assetInfo}->{uriData}->{streamUri} =~ /mp4$/ ) {
+ $xml = $xml_off;
+ info "Found mp4 stream asset id $asset_off siteSectionId $xml->{assetInfo}->{adverts}->{siteSectionId}";
+ if ($xml->{assetInfo}->{uriData}->{streamUri} =~ /\.ps3-/ ) {
+ last;
+ }
+ }
+ }
+ else {
+ if ($asset_off > $asset_id ) {
+ $upper_id = $asset_off;
+ }
+ else {
+ $lower_id = $asset_off;
+ }
+ }
+ }
+ }
+ }
+ }
+ else {
+ $xml = $xml_ref;
+ }
- my $stream_url = $xml->{assetInfo}->{uriData}->{streamUri};
- my $token = $xml->{assetInfo}->{uriData}->{token};
- my $cdn = $xml->{assetInfo}->{uriData}->{cdn};
+ my $stream_url = $xml->{assetInfo}->{uriData}->{streamUri};
+ my $token = $xml->{assetInfo}->{uriData}->{token};
+ my $cdn = $xml->{assetInfo}->{uriData}->{cdn};
my $decoded_token = decode_4od_token($token);
@@ -102,7 +147,7 @@ sub find_video {
$title = join " - ", @title_components;
}
- my $filename = title_to_filename($title, "mp4");
+ my $filename = title_to_filename($title, "flv");
# Get subtitles if necessary.
if ($prefs->subtitles) {
diff --git a/lib/FlashVideo/Site/Itv.pm b/lib/FlashVideo/Site/Itv.pm
index 8de93e0..5242302 100644
--- a/lib/FlashVideo/Site/Itv.pm
+++ b/lib/FlashVideo/Site/Itv.pm
@@ -4,18 +4,24 @@ package FlashVideo::Site::Itv;
use strict;
use FlashVideo::Utils;
use HTML::Entities;
+use Encode;
+
+our $VERSION = '0.02';
+sub Version() { $VERSION;}
sub find_video {
my ($self, $browser, $page_url, $prefs) = @_;
my($id) = $browser->uri =~ /Filter=(\d+)/;
- die "No id (filter) found in URL\n" unless $id;
+ my $productionid;
+ if ( $id )
+ {
- $browser->post("http://mercury.itv.com/PlaylistService.svc",
- Content_Type => "text/xml; charset=utf-8",
- Referer => "http://www.itv.com/mercury/Mercury_VideoPlayer.swf?v=1.5.309/[[DYNAMIC]]/2",
- SOAPAction => '"http://tempuri.org/PlaylistService/GetPlaylist"',
- Content => <<EOF);
+ $browser->post("http://mercury.itv.com/PlaylistService.svc",
+ Content_Type => "text/xml; charset=utf-8",
+ Referer => "http://www.itv.com/mercury/Mercury_VideoPlayer.swf?v=1.5.309/[[DYNAMIC]]/2",
+ SOAPAction => '"http://tempuri.org/PlaylistService/GetPlaylist"',
+ Content => <<EOF);
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<tem:GetPlaylist xmlns:tem="http://tempuri.org/" xmlns:itv="http://schemas.datacontract.org/2004/07/Itv.BB.Mercury.Common.Types" xmlns:com="http://schemas.itv.com/2009/05/Common">
@@ -44,6 +50,59 @@ sub find_video {
</SOAP-ENV:Envelope>
EOF
+ }
+ else {
+ ($productionid) = $browser->content =~ /\"productionId\":\"([^\"]+)\"/i;
+ debug "Production ID $productionid\n";
+ die "No id (filter) found in URL or production id\n" unless $productionid;
+ $browser->post("http://mercury.itv.com/PlaylistService.svc",
+ Content_Type => "text/xml; charset=utf-8",
+ Referer => "http://www.itv.com/mercury/Mercury_VideoPlayer.swf?v=1.5.309/[[DYNAMIC]]/2",
+ SOAPAction => '"http://tempuri.org/PlaylistService/GetPlaylist"',
+ Content => <<EOF);
+<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:itv="http://schemas.datacontract.org/2004/07/Itv.BB.Mercury.Common.Types" xmlns:com="http://schemas.itv.com/2009/05/Common">
+ <soapenv:Header/>
+ <soapenv:Body>
+ <tem:GetPlaylist>
+ <tem:request>
+ <itv:ProductionId>$productionid</itv:ProductionId>
+ <itv:RequestGuid>FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF</itv:RequestGuid>
+ <itv:Vodcrid>
+ <com:Id/>
+ <com:Partition>itv.com</com:Partition>
+ </itv:Vodcrid>
+ </tem:request>
+ <tem:userInfo>
+ <itv:Broadcaster>Itv</itv:Broadcaster>
+ <itv:GeoLocationToken>
+ <itv:Token/>
+ </itv:GeoLocationToken>
+ <itv:RevenueScienceValue>ITVPLAYER.12.18.4</itv:RevenueScienceValue>
+ <itv:SessionId/>
+ <itv:SsoToken/>
+ <itv:UserToken/>
+ </tem:userInfo>
+ <tem:siteInfo>
+ <itv:AdvertisingRestriction>None</itv:AdvertisingRestriction>
+ <itv:AdvertisingSite>ITV</itv:AdvertisingSite>
+ <itv:AdvertisingType>Any</itv:AdvertisingType>
+ <itv:Area>ITVPLAYER.VIDEO</itv:Area>
+ <itv:Category/>
+ <itv:Platform>DotCom</itv:Platform>
+ <itv:Site>ItvCom</itv:Site>
+ </tem:siteInfo>
+ <tem:deviceInfo>
+ <itv:ScreenSize>Big</itv:ScreenSize>
+ </tem:deviceInfo>
+ <tem:playerInfo>
+ <itv:Version>2</itv:Version>
+ </tem:playerInfo>
+ </tem:GetPlaylist>
+ </soapenv:Body>
+</soapenv:Envelope>
+EOF
+
+ }
# We want the RTMP url within a <Video timecode=...> </Video> section.
debug $browser->content;
die "Unable to find <Video> in XML" unless $browser->content =~ m{<Video timecode[^>]+>(.*?)</Video>}s;
@@ -100,6 +159,41 @@ EOF
my $rtmp = decode_entities($video =~ /base="(rtmp[^"]+)/);
my($playpath) = $format->{"playpath"};
my($flv) = $playpath =~ m{/([^/]+)$};
+ $flv =~ s/\.mp4$/.flv/;
+
+ # Get subtitles if necessary.
+ if ($prefs->{subtitles}) {
+ info "Subtitle Fetching";
+ if ($video =~ m%<URL><!\[CDATA\[(http://subtitles\.[^\]]*)\]\]></URL>%) {
+ my $subtitles_url = $1;
+ info "Subtitle URL $subtitles_url";
+ $browser->get($subtitles_url);
+
+ if (!$browser->success) {
+ info "Couldn't download Itv subtitles: " . $browser->response->status_line;
+ }
+ my $subtitles_ttml = $flv;
+ my $subtext = $browser->content;
+ my $istart = index $subtext, "<";
+ $subtext = substr($subtext, $istart) unless ($istart < 0);
+ $subtext =~ s/UTF-16/utf8/;
+
+ $subtitles_ttml =~ s/\.flv$/\.ttml/;
+
+ unlink($subtitles_ttml);
+ open my $fh, ">", $subtitles_ttml;
+ binmode $fh;
+ print $fh $subtext;
+ close $fh;
+
+ my $subtitles_file = $flv;
+ $subtitles_file =~ s/\.flv$/\.srt/;
+
+ convert_ttml_subtitles_to_srt($browser->content, $subtitles_file);
+
+ info "Saved subtitles to $subtitles_file";
+ }
+ }
return {
rtmp => $rtmp,
@@ -109,4 +203,6 @@ EOF
};
}
+
+
1;
diff --git a/lib/FlashVideo/URLFinder.pm b/lib/FlashVideo/URLFinder.pm
index 8b4cb12..ecb2928 100644
--- a/lib/FlashVideo/URLFinder.pm
+++ b/lib/FlashVideo/URLFinder.pm
@@ -88,7 +88,9 @@ sub _find_package_url {
sub _found {
my($package, $url) = @_;
- info "Using method '" . lc((split /::/, $package)[-1]) . "' for $url";
+ my $pv = eval "\$".$package."::VERSION";
+ $pv = ' plugin version ' . $pv if $pv;
+ info "Using method '" . lc((split /::/, $package)[-1]) . "'$pv for $url";
return $package, $url;
}
diff --git a/lib/FlashVideo/Utils.pm b/lib/FlashVideo/Utils.pm
index 61dfd18..a519b9b 100644
--- a/lib/FlashVideo/Utils.pm
+++ b/lib/FlashVideo/Utils.pm
@@ -16,7 +16,8 @@ our @EXPORT = qw(debug info error
extract_title extract_info title_to_filename get_video_filename url_exists
swfhash swfhash_data EXTENSIONS get_user_config_dir get_win_codepage
is_program_on_path get_terminal_width json_unescape
- convert_sami_subtitles_to_srt from_xml);
+ convert_sami_subtitles_to_srt from_xml
+ convert_ttml_subtitles_to_srt);
sub debug(@) {
# Remove some sensitive data
@@ -288,6 +289,90 @@ sub json_unescape {
return $s;
}
+sub convert_ttml_subtitles_to_srt {
+ my ($ttml_subtitles, $filename) = @_;
+
+ die "TTML subtitles must be provided\n" unless $ttml_subtitles;
+ die "Output filename must be provided\n" unless $filename;
+ if ( -f $filename ) {
+ info "Subtitles already saved";
+ return;
+ }
+
+ my %ccodes = (
+ 'black', '#000000',
+ 'blue', '#0000ff',
+ 'aqua', '#00ffff',
+ 'lime', '#00ff00',
+ 'fuchsia', '#ff00ff',
+ 'fuscia', '#ff00ff',
+ 'red', '#ff0000',
+ 'yellow', '#ffff00',
+ 'white', '#ffffff',
+ 'navy', '#000080',
+ 'teal', '#008080',
+ 'green', '#008000',
+ 'purple', '#800080',
+ 'maroon', '#800000',
+ 'olive', '#808000',
+ 'gray', '#808080',
+ 'silver', '#c0c0c0');
+
+ unlink($filename);
+ open( my $fh, "> $filename");
+ binmode $fh;
+
+ my $st_count = 1;
+ my @lines = grep /<p\s.*begin=/, split /\n/, $ttml_subtitles;
+ for ( @lines ) {
+ my ( $start_time, $end_time, $st_text );
+ # Remove >1 spaces if not preserved
+ s|\s{2,}| |g unless (m%space\s=\s"preserve"%);
+ ( $start_time, $end_time, $st_text ) = ( $1, $2, $3 ) if m{<p\s+.*begin="(.+?)".+end="(.+?)".*?>(.+?)<\/p>};
+ if ($start_time && $end_time && $st_text ) {
+ # Format numerical field widths
+ $start_time = sprintf( '%02d:%02d:%02d,%02d', split /[:\.,]/, $start_time );
+ $end_time = sprintf( '%02d:%02d:%02d,%02d', split /[:\.,]/, $end_time );
+ # Add trailing zero if ttxt format only uses hundreths of a second
+ $start_time .= '0' if $start_time =~ m{,\d\d$};
+ $end_time .= '0' if $end_time =~ m{,\d\d$};
+ # Separate individual lines based on <span>s
+ my $i = index $st_text, "<span";
+ while ($i >= 0) {
+ my $j = index $st_text, "</span>", $i;
+ if ($j > 0) {
+ my $span = substr($st_text, $i, $j-$i+7);
+ my $k = index $span, ">";
+ my ( $span_ctl, $span_text ) = ($span =~ m|<span ([^>]+)>(.*)</span>|);
+ my ($span_color) = ($span_ctl =~ m|tts:color="(\w+)"|);
+ $span = '<font color="'. $ccodes{$span_color} . '">' . $span_text . "</font>\n";
+ $st_text = substr($st_text, 0, $i) . "\n" . $span . substr($st_text, $j+7) . "\n";
+ }
+ $i = index $st_text, "<span";
+ }
+ $st_text =~ s|<span.*?>(.*?)</span>|\n$1\n|g;
+ $st_text =~ s|<br.*?>|\n|g;
+ if ($st_text =~ m{\n}) {
+ chomp($st_text);
+ $st_text =~ s|^\n?||;
+ $st_text =~ s|\n?$||;
+ $st_text =~ s|\n+|\n|g;
+ }
+ decode_entities($st_text);
+ # Write to file
+ print $fh "$st_count\n";
+ print $fh "$start_time --> $end_time\n";
+ print $fh "$st_text\n\n";
+ $st_count++;
+ }
+ }
+ close $fh;
+
+ return;
+}
+
+
+
sub convert_sami_subtitles_to_srt {
my ($sami_subtitles, $filename, $decrypt_callback) = @_;