/usr/share/perl5/FlashVideo/Site/Brightcove.pm is in get-flash-videos 1.25.98-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | # Part of get-flash-videos. See get_flash_videos for copyright.
package FlashVideo::Site::Brightcove;
use strict;
use FlashVideo::Utils;
use MIME::Base64;
sub find_video {
my ($self, $browser, $embed_url) = @_;
my $metadata = { };
my ($video_id, $player_id);
# URL params, JSON, etc..
$video_id = ($browser->content =~ /(?:clip|video)Id["'\] ]*[:=]["' ]*(\d+)/i)[0];
$player_id = ($browser->content =~ /playerId["'\] ]*[:=]["' ]*(\d+)/i)[0];
# <object> params
$player_id ||= ($browser->content =~ /<param name=["']?playerID["']? value=["'](\d+) ?["']/i)[0];
$video_id ||= ($browser->content =~ /<param name=["']?\@?video(?:Player|id)["']? value=["'](\d+)["']/i)[0];
# flashVar params (e.g. <embed>)
$player_id ||= ($browser->content =~ /flashVars.*playerID=(\d+)/i)[0];
$video_id ||= ($browser->content =~ /flashVars.*video(?:Player|ID)=(\d+)/i)[0];
# Brightcove JavaScript API
if(!$player_id && $browser->content =~ /brightcove.player.create\(['"]?(\d+)['"]?,\s*['"]?(\d+)/) {
$video_id = $1;
$player_id = $2;
}
# Support direct links to videos
for my $url($browser->uri->as_string, $embed_url) {
if($url =~ /(?:videoID|bctid)=?(\d+)/i) {
$video_id ||= $1;
}
if($url =~ /(?:playerID|bcpid)=?(\d+)/i) {
$player_id ||= $1;
}
if($url =~ /(?:lineupID|bclid)=?(\d+)/i) {
$metadata->{lineupId} ||= $1;
}
}
debug "Extracted playerId: $player_id, videoId: $video_id, lineupID: $metadata->{lineupId}"
if $player_id or $video_id;
die "Unable to extract Brightcove IDs from page" unless $player_id;
$metadata->{videoId} = $video_id;
return $self->amfgateway($browser, $player_id, $metadata);
}
sub amfgateway {
my($self, $browser, $player_id, $metadata) = @_;
my $has_amf_packet = eval { require Data::AMF::Packet };
if (!$has_amf_packet) {
die "Must have Data::AMF::Packet installed to download Brightcove videos";
}
my $page_url = $browser->uri;
my $packet = Data::AMF::Packet->deserialize(decode_base64(<<EOF));
AAAAAAABAEhjb20uYnJpZ2h0Y292ZS50ZW1wbGF0aW5nLlRlbXBsYXRpbmdGYWNhZGUuZ2V0Q29u
dGVudEZvclRlbXBsYXRlSW5zdGFuY2UAAi8yAAACNQoAAAACAEH4tP+1EAAAEAA1Y29tLmJyaWdo
dGNvdmUudGVtcGxhdGluZy5Db250ZW50UmVxdWVzdENvbmZpZ3VyYXRpb24ACnZpZGVvUmVmSWQG
AAd2aWRlb0lkBgAIbGluZXVwSWQGAAtsaW5ldXBSZWZJZAYAF29wdGltaXplRmVhdHVyZWRDb250
ZW50AQEAF2ZlYXR1cmVkTGluZXVwRmV0Y2hJbmZvEAAkY29tLmJyaWdodGNvdmUucGVyc2lzdGVu
Y2UuRmV0Y2hJbmZvAApjaGlsZExpbWl0AEBZAAAAAAAAAA5mZXRjaExldmVsRW51bQBAEAAAAAAA
AAALY29udGVudFR5cGUCAAtWaWRlb0xpbmV1cAAACQAKZmV0Y2hJbmZvcwoAAAACEAAkY29tLmJy
aWdodGNvdmUucGVyc2lzdGVuY2UuRmV0Y2hJbmZvAApjaGlsZExpbWl0AEBZAAAAAAAAAA5mZXRj
aExldmVsRW51bQA/8AAAAAAAAAALY29udGVudFR5cGUCAAtWaWRlb0xpbmV1cAAACRAAJGNvbS5i
cmlnaHRjb3ZlLnBlcnNpc3RlbmNlLkZldGNoSW5mbwAKY2hpbGRMaW1pdABAWQAAAAAAAAAPZ3Jh
bmRjaGlsZExpbWl0AEBZAAAAAAAAAA5mZXRjaExldmVsRW51bQBACAAAAAAAAAALY29udGVudFR5
cGUCAA9WaWRlb0xpbmV1cExpc3QAAAkAAAk=
EOF
if (defined $player_id) {
$packet->messages->[0]->{value}->[0] = "$player_id";
}
if (ref $metadata) {
for(keys %$metadata) {
$packet->messages->[0]->{value}->[1]->{$_} = "$metadata->{$_}";
}
}
my $data = $packet->serialize;
$browser->post(
"http://c.brightcove.com/services/amfgateway",
Content_Type => "application/x-amf",
Content => $data
);
die "Failed to post to Brightcove AMF gateway"
unless $browser->response->is_success;
$packet = Data::AMF::Packet->deserialize($browser->content);
if($self->debug) {
require Data::Dumper;
debug Data::Dumper::Dumper($packet);
}
if(ref $packet->messages->[0]->{value} ne 'ARRAY') {
die "Unexpected data from AMF gateway";
}
my @found;
for (@{$packet->messages->[0]->{value}}) {
if ($_->{data}->{videoDTO}) {
push @found, $_->{data}->{videoDTO};
}
if ($_->{data}->{videoDTOs}) {
push @found, @{$_->{data}->{videoDTOs}};
}
}
my @rtmpdump_commands;
for my $d (@found) {
next if $metadata->{videoId} && $d->{id} != $metadata->{videoId};
# There might be different versions (aka "renditions") of this video -
# if so, choose the highest quality.
#
# TODO: support quality settings
my $rtmp_url = $d->{FLVFullLengthURL};
if ($d->{renditions} and ref($d->{renditions}) eq 'ARRAY') {
my @renditions = sort { $a->{encodingRate} <=> $b->{encodingRate} }
@{ $d->{renditions} };
$rtmp_url = $renditions[-1]->{defaultURL};
}
my $host = ($rtmp_url =~ m!rtmp://(.*?)/!)[0];
my $file = ($rtmp_url =~ m!&([a-z0-9:]+/.*?)(?:&|$)!)[0];
my $app = ($rtmp_url =~ m!//.*?/(.*?)/&!)[0];
my $filename = ($rtmp_url =~ m!&.*?/([^/&]+)(?:&|$)!)[0];
$app .= "?videoId=$d->{id}&lineUpId=$d->{lineupId}&pubId=$d->{publisherId}&playerId=$player_id&playerTag=&affiliateId=";
my $args = {
app => $app,
pageUrl => $page_url,
swfUrl => "http://admin.brightcove.com/viewer/federated/f_012.swf?bn=590&pubId=$d->{publisherId}",
tcUrl => "rtmp://$host:1935/$app",
auth => ($rtmp_url =~ /^[^&]+&(.*)$/)[0],
rtmp => "rtmp://$host/$app",
playpath => $file,
flv => "$filename.flv",
};
# Use sane filename
if ($d->{publisherName} and $d->{displayName}) {
$args->{flv} = title_to_filename("$d->{publisherName} - $d->{displayName}");
}
# In some cases, Brightcove doesn't use RTMP streaming - the file is
# downloaded via HTTP.
if (!$d->{FLVFullLengthStreamed}) {
info "Brightcove HTTP download detected";
return ($d->{FLVFullLengthURL}, $args->{flv});
}
push @rtmpdump_commands, $args;
}
if (@rtmpdump_commands > 1) {
return \@rtmpdump_commands;
}
else {
return $rtmpdump_commands[-1];
}
}
sub can_handle {
my($self, $browser, $url) = @_;
return 1 if $url && URI->new($url)->host =~ /\.brightcove\.com$/;
return $browser->content =~ /(playerI[dD]|brightcove.player.create)/
&& $browser->content =~ /brightcove/i;
}
1;
|