This file is indexed.

/usr/share/perl5/FlashVideo/Site/Brightcove.pm is in get-flash-videos 1.25~git2014.03.23-2.

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;