diff options
author | zakflash <zakflashvideo@gmail.com> | 2013-02-24 11:23:11 -0800 |
---|---|---|
committer | zakflash <zakflashvideo@gmail.com> | 2013-02-24 11:23:11 -0800 |
commit | 9856e41fd340d82aebe104aea131d5398da488d4 (patch) | |
tree | f92023c97684d615d05d122986437fa127f07f35 | |
parent | b9ac7e782b27f13bfa3798b05f99158a8187ef94 (diff) | |
parent | ae97f252e719faf9ac955399b6a875f6bcf1b95e (diff) | |
download | get-flash-videos-9856e41fd340d82aebe104aea131d5398da488d4.tar.gz |
Merge pull request #94 from njtaylor/master
Multiple updates
-rw-r--r-- | Makefile.PL | 3 | ||||
-rwxr-xr-x | get_flash_videos | 11 | ||||
-rw-r--r-- | lib/FlashVideo/Site/Channel4.pm | 55 | ||||
-rw-r--r-- | lib/FlashVideo/Site/Itv.pm | 108 | ||||
-rw-r--r-- | lib/FlashVideo/URLFinder.pm | 4 | ||||
-rw-r--r-- | lib/FlashVideo/Utils.pm | 87 |
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) = @_; |