line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Video::CPL; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
30043
|
use warnings; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
32
|
|
4
|
1
|
|
|
1
|
|
3
|
use strict; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
18
|
|
5
|
1
|
|
|
1
|
|
3
|
use Carp; |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
44
|
|
6
|
1
|
|
|
1
|
|
455
|
use Encode; |
|
1
|
|
|
|
|
7535
|
|
|
1
|
|
|
|
|
65
|
|
7
|
1
|
|
|
1
|
|
6
|
use Data::Dumper; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
33
|
|
8
|
1
|
|
|
1
|
|
3
|
use Fcntl; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
172
|
|
9
|
1
|
|
|
1
|
|
613
|
use File::Temp; |
|
1
|
|
|
|
|
15100
|
|
|
1
|
|
|
|
|
77
|
|
10
|
1
|
|
|
1
|
|
5
|
use File::Path qw(make_path); |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
38
|
|
11
|
1
|
|
|
1
|
|
3
|
use List::Util qw(shuffle); |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
66
|
|
12
|
1
|
|
|
1
|
|
400
|
use LWP::Simple; |
|
1
|
|
|
|
|
42360
|
|
|
1
|
|
|
|
|
11
|
|
13
|
1
|
|
|
1
|
|
278
|
use XML::Simple; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
8
|
|
14
|
1
|
|
|
1
|
|
555
|
use XML::Writer; |
|
1
|
|
|
|
|
6712
|
|
|
1
|
|
|
|
|
28
|
|
15
|
|
|
|
|
|
|
|
16
|
1
|
|
|
1
|
|
510
|
use Video::CPL::Cue; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
25
|
|
17
|
1
|
|
|
1
|
|
6
|
use Video::CPL::Annotation; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
15
|
|
18
|
1
|
|
|
1
|
|
3
|
use Video::CPL::Story; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
15
|
|
19
|
1
|
|
|
1
|
|
359
|
use Video::CPL::Layout; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
5402
|
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
our $VAR1; #useful for evals |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
=head1 NAME |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
Video::CPL - Create and manipulate Coincident TV Programming Language (CPL) files. |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
=head1 VERSION |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
Version 0.09 |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
=cut |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
our $VERSION = '0.09'; |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
=head1 SYNOPSIS |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
Video::CPL provides an object-oriented module for creating CPL files. CPL files control interactive video experiences. |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
A simple example might be displaying a video, e.g. from Youtube, in a player on a webpage. |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
A more complex example might include images, which the user clicks on to jump to other videos. |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
In conjunction with CGI.pm it is straightforward to create fully interactive web pages with dynamically created video experiences. |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
Video::CPL does not create the video file itself; it works with videos on services such as Youtube, or created with tools such as Video::FFmpeg. |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
A tutorial is available at http://metabase.coincident.tv/cpan. |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
Short code sample: create a file using CPL, and then embed a link to the file in your html as shown below. |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
use CPL; |
52
|
|
|
|
|
|
|
my $ctv = new Video::CPL(videoSource=>"http://www.youtube.com/watch?v=0ZexPPDLXRA" |
53
|
|
|
|
|
|
|
html=>$htmlfilelocation); |
54
|
|
|
|
|
|
|
$ctv->programEnd(30); #end after 30 seconds |
55
|
|
|
|
|
|
|
print $ctv->print(); #prints out cpl file |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
#and then, when writing html: |
58
|
|
|
|
|
|
|
print $ctv->embed(); #print out an HTML embed pointing to the temporary file |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
=head1 METHODS |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
=head2 new(videoSource=>$url,[html=>$htmldir,ref=>$url,] [PARMS]); |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
Create a new Video::CPL object. There is one videoSource per Video::CPL object. |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
Attributes are named the same as in CPL. E.g. to set xUniqueID add "xUniqueID=>23" |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
If the CPL for this object will be given in response to a CGI query, there may be no need for a file. Otherwise, in most simple cases, a CPL file will be written out to a local file which is can then be referred to with a URL. |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
To do this CPL needs to be told of a directory which can be seen via HTTP, i.e., one in the document tree of the web server. The directory on the local file system should be speficied either in the CPLDIR environment variable, or in the html parameter. The URL for this same directory should be specified in the CPLURL environment variable, or in the ref parameter. |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
CPL can be used to build up a new CPL, or it can initialize itself with an existing CPL file. |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
If attributes are given which are not in the 0.7 or 0.8 spec, they will generate an error. |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
Other parameters can include: |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
validator=>"CPL_v0.7_validator.xsd" . Sets the XML validator. Advanced users only. |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
xsi=>"http://www.w3.org/2001/XMLSchema-instance" . Set the schema instance. Advanced users only. |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
initfromctv=>"foo.ctv" . Given a string which is either valid XML or a filename, use it to initialize the Video::CPL object. |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
=cut |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
sub new { |
87
|
2
|
|
|
2
|
1
|
70571
|
my $pkg = shift; |
88
|
2
|
|
|
|
|
23
|
my %parms = @_; |
89
|
2
|
|
|
|
|
7
|
my $ret = {}; |
90
|
2
|
|
|
|
|
7
|
bless $ret,$pkg; |
91
|
|
|
|
|
|
|
|
92
|
2
|
|
50
|
|
|
25
|
$ret->{xVersionCPL} = $parms{xVersionCPL} || "0.8.0"; |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
#The directory on the host system which is the top level html directory. |
95
|
|
|
|
|
|
|
#normally used in embed when printing out the html. |
96
|
|
|
|
|
|
|
#If not used, i.e. if you are collecting the ctv and placing it yourself, this can be invalid. |
97
|
2
|
|
33
|
|
|
13
|
$ret->{html} = $parms{html} || $ENV{CPLDIR}; |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
#ref is the base of the URL to be used for intra-ctv references. It should point to the same location as html |
100
|
2
|
|
33
|
|
|
11
|
$ret->{ref} = $parms{ref} || $ENV{CPLURL}; |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
#XML-isms |
103
|
2
|
50
|
33
|
|
|
20
|
$ret->{'xsi:noNamespaceSchemaLocation'} = $parms{'xsi:noNamespaceSchemaLocation'} || ($ret->{xVersionCPL} eq "0.7.0")?"CPL_v0.7_validator.xsd":"CPL_v0.8_validator.xsd"; |
104
|
2
|
|
50
|
|
|
9
|
$ret->{'xmlns:xsi'} = $parms{'xmlns:xsi'} || "http://www.w3.org/2001/XMLSchema-instance"; |
105
|
|
|
|
|
|
|
|
106
|
2
|
100
|
|
|
|
10
|
$ret->parsectv($parms{initfromctv}) if $parms{initfromctv}; |
107
|
|
|
|
|
|
|
#check parameters; confess on typos etc. |
108
|
2
|
|
|
|
|
9
|
foreach my $q (keys %parms){ |
109
|
17
|
50
|
|
|
|
55
|
next if $q =~ /xVersionCPL|videoSource|videoWidth|videoHeight|backgroundHTML|xWebServiceLoc|xUniqueID|xProgLevelDir|loggingService|html|ref|xsi:noNamespaceSchemaLocation|xmlns:xsi|xProgLevelData|skinButtons|webViewLayout|videoViewLayout|frameWidth|frameHeight|videoX|videoY|youtubeID|initfromctv/; |
110
|
0
|
|
|
|
|
0
|
confess("new CPL does not know what to do with parameter($q)\n"); |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
|
113
|
2
|
|
|
|
|
5
|
foreach my $q (qw(xVersionCPL videoSource videoWidth videoHeight backgroundHTML xWebServiceLoc xUniqueID xProgLevelDir loggingService xProgLevelData skinButtons webViewLayout videoViewLayout frameWidth frameHeight videoX videoY youtubeID)){ |
114
|
36
|
100
|
|
|
|
54
|
$ret->{$q} = $parms{$q} if defined($parms{$q}); |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
#Errors: no source file specified |
118
|
|
|
|
|
|
|
#Error: parameter given but not used |
119
|
|
|
|
|
|
|
##Errors: no source file specified |
120
|
|
|
|
|
|
|
#Error: parameter given but not used |
121
|
2
|
100
|
|
|
|
7
|
if (!defined($parms{initfromctv})){ |
122
|
1
|
|
|
|
|
2
|
$ret->{cuePoints} = []; |
123
|
1
|
|
|
|
|
11
|
$ret->{cuePoints}[0] = Video::CPL::Cue->new(name=>"CPLBegin",time=>0,cueType=>"regular",parent=>$ret); |
124
|
|
|
|
|
|
|
} |
125
|
|
|
|
|
|
|
|
126
|
2
|
50
|
|
|
|
8
|
if (exists($parms{htmlurl})){ |
|
|
50
|
|
|
|
|
|
127
|
0
|
|
0
|
|
|
0
|
$ret->{htmlrel} = $parms{htmlrel} || "."; |
128
|
0
|
|
|
|
|
0
|
$ret->{htmlurl} = $parms{htmlurl}; |
129
|
|
|
|
|
|
|
} elsif (defined($ret->{html})){ |
130
|
|
|
|
|
|
|
#open up a temporary file now to avoid race conditions. Might not even be used. |
131
|
0
|
|
|
|
|
0
|
my $fh = File::Temp->new(UNLINK=>0,DIR=>"$ret->{html}",SUFFIX=>".ctv"); |
132
|
0
|
|
|
|
|
0
|
my $filename = $fh->filename; |
133
|
0
|
|
|
|
|
0
|
$ret->{fullfilename} = $filename; |
134
|
0
|
|
|
|
|
0
|
chmod 0644,$filename; |
135
|
0
|
|
|
|
|
0
|
$filename =~ s/.*\///; |
136
|
0
|
|
|
|
|
0
|
$ret->{ctvfilename} = $filename; |
137
|
0
|
|
|
|
|
0
|
$ret->{fh} = $fh; |
138
|
|
|
|
|
|
|
} |
139
|
2
|
|
|
|
|
6
|
return $ret; |
140
|
|
|
|
|
|
|
} |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
sub datepref { |
143
|
0
|
|
|
0
|
0
|
0
|
my $x = shift; |
144
|
0
|
|
|
|
|
0
|
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime($x); |
145
|
0
|
|
|
|
|
0
|
$year+=1900; |
146
|
0
|
|
|
|
|
0
|
$mon++; |
147
|
0
|
0
|
|
|
|
0
|
$mon = "0".$mon if length($mon) == 1; |
148
|
0
|
0
|
|
|
|
0
|
$mday = "0".$mday if length($mday) == 1; |
149
|
0
|
|
|
|
|
0
|
return "$year-$mon-$mday"; |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
sub fixfile { |
153
|
0
|
|
|
0
|
0
|
0
|
my $obj = shift; |
154
|
0
|
0
|
|
|
|
0
|
return if $obj->{filefixed}; |
155
|
0
|
|
|
|
|
0
|
my $dseg = datepref($^T); #convert time of script starting to 2010-01-01 format |
156
|
0
|
0
|
|
|
|
0
|
$obj->{htmlrel} = "." if !exists($obj->{htmlrel}); |
157
|
0
|
|
|
|
|
0
|
my $dir = $obj->{htmlrel}."/".$dseg; |
158
|
0
|
0
|
|
|
|
0
|
make_path($dir) if !-d $dir; |
159
|
0
|
0
|
|
|
|
0
|
confess("$0: Video::CPL Fatal Error. Could not create or access directory ($dir).\n") if !-d $dir; |
160
|
|
|
|
|
|
|
#create file with File::Temp chmod 0644 etc. |
161
|
0
|
|
|
|
|
0
|
my $fh = File::Temp->new(UNLINK=>0,DIR=>$dir,SUFFIX=>".ctv"); |
162
|
0
|
|
|
|
|
0
|
$obj->{fh} = $fh; |
163
|
0
|
|
|
|
|
0
|
my $filename = $fh->filename; |
164
|
0
|
|
|
|
|
0
|
chmod 0644,$filename; |
165
|
0
|
|
|
|
|
0
|
$filename =~ s/.*\///; |
166
|
0
|
|
|
|
|
0
|
$obj->{ctvfilename} = $filename; |
167
|
0
|
|
|
|
|
0
|
$obj->{relfilename} = "$dir/$filename"; |
168
|
0
|
|
|
|
|
0
|
$obj->{relfilename} =~ s/^\.\///; #if we are ./foo.ctv become foo.ctv |
169
|
0
|
|
|
|
|
0
|
$obj->{relfilename} =~ s/\/\//\//g; |
170
|
0
|
|
|
|
|
0
|
$obj->{url} = $obj->{htmlurl}."/$dseg/$filename"; |
171
|
|
|
|
|
|
|
#set full relative pathname and fh |
172
|
0
|
|
|
|
|
0
|
$obj->{filefixed} = 1;; |
173
|
0
|
|
|
|
|
0
|
return; |
174
|
|
|
|
|
|
|
} |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
=head asurl() |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
Returns the URL which will recreate this URL. This will be a file or a reference to this script. |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
Used when creating the media parameter for the CTV player, which requires a full URL. |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
=cut |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
sub asurl { |
185
|
0
|
|
|
0
|
0
|
0
|
my $obj = shift; |
186
|
|
|
|
|
|
|
|
187
|
0
|
0
|
|
|
|
0
|
confess("$0: Fatal Error. URL reference to a Video::CPL object which is marked 'noref'.\n") if $obj->{noref}; |
188
|
|
|
|
|
|
|
|
189
|
0
|
0
|
|
|
|
0
|
if ($obj->{isdyn}){ |
190
|
0
|
|
|
|
|
0
|
confess("NYI"); |
191
|
|
|
|
|
|
|
} else { |
192
|
0
|
0
|
|
|
|
0
|
$obj->fixfile() if !$obj->{filefixed}; |
193
|
0
|
|
|
|
|
0
|
return $obj->{url}; |
194
|
|
|
|
|
|
|
} |
195
|
|
|
|
|
|
|
} |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
=head asrel([$otherCPL]) |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
Returns the URL fragment (e.g. foo/goo.ctv) which will access this file from the current directory. If given |
200
|
|
|
|
|
|
|
a parameter of another Video::CPL object, will return a URL fragment which is valid in that objects context. |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
=cut |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
sub asrel { |
205
|
0
|
|
|
0
|
0
|
0
|
my $obj = shift; |
206
|
|
|
|
|
|
|
#optional second param. Return from the perspective of this cpl. |
207
|
0
|
0
|
|
|
|
0
|
confess("$0: Fatal Error. URL reference to a Video::CPL object which is marked 'noref'.\n") if $obj->{noref}; |
208
|
|
|
|
|
|
|
|
209
|
0
|
0
|
|
|
|
0
|
if ($obj->{isdyn}){ |
210
|
0
|
|
|
|
|
0
|
confess("NYI"); |
211
|
|
|
|
|
|
|
} else { |
212
|
0
|
0
|
|
|
|
0
|
$obj->fixfile() if !$obj->{filefixed}; |
213
|
0
|
|
|
|
|
0
|
return $obj->{relfilename}; |
214
|
|
|
|
|
|
|
} |
215
|
|
|
|
|
|
|
} |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
sub asreldir { |
218
|
0
|
|
|
0
|
0
|
0
|
my $obj = shift; |
219
|
0
|
|
|
|
|
0
|
my $x = $obj->asrel(); |
220
|
0
|
0
|
|
|
|
0
|
return $1 if $x =~ /^(.*)\//; #normal case, foo/goo/hoo.ctv, return foo/goo |
221
|
0
|
|
|
|
|
0
|
return "."; #if there was no slash, current directory |
222
|
|
|
|
|
|
|
} |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
sub asreltail { |
225
|
0
|
|
|
0
|
0
|
0
|
my $obj = shift; |
226
|
0
|
|
|
|
|
0
|
my $x = $obj->asrel(); |
227
|
0
|
0
|
|
|
|
0
|
return $1 if $x =~ /^.*\/(.*)$/; #normal case, foo/goo/hoo.ctv, return hoo.ctv |
228
|
0
|
|
|
|
|
0
|
return "$x"; #if there was no slash, return self |
229
|
|
|
|
|
|
|
} |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
sub reffrom { |
232
|
0
|
|
|
0
|
0
|
0
|
my $obj = shift; |
233
|
0
|
|
|
|
|
0
|
my $from = shift; |
234
|
0
|
0
|
0
|
|
|
0
|
if ($from && ($from != $obj)){ |
235
|
0
|
0
|
|
|
|
0
|
if ($obj->{noref}){ |
236
|
0
|
|
|
|
|
0
|
warn("Video::CPL: this object has noref set, cannot be referenced from other objects, fatal error.\n"); |
237
|
0
|
|
|
|
|
0
|
return undef; |
238
|
|
|
|
|
|
|
} |
239
|
|
|
|
|
|
|
} else { |
240
|
0
|
|
|
|
|
0
|
return $obj->{tail}; |
241
|
|
|
|
|
|
|
} |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
#=head2 tmpfile(ext=>".ctv") |
245
|
|
|
|
|
|
|
# |
246
|
|
|
|
|
|
|
# Create a temporary file. Return the filehandle, and an address usable in the current CTV. |
247
|
|
|
|
|
|
|
# |
248
|
|
|
|
|
|
|
#=cut |
249
|
|
|
|
|
|
|
# |
250
|
|
|
|
|
|
|
#sub tmpfile { |
251
|
|
|
|
|
|
|
# my $obj = shift; |
252
|
|
|
|
|
|
|
# my %p = @_; |
253
|
|
|
|
|
|
|
# confess; #this is a placeholder |
254
|
|
|
|
|
|
|
#} |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
=head2 xVersionCPL([$string]) |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
Accessor routine to set or read xVersionCPL. |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
=cut |
261
|
|
|
|
|
|
|
|
262
|
2
|
50
|
|
2
|
1
|
2
|
sub xVersionCPL { my $obj = shift; $obj->{xVersionCPL} = shift if @_; return $obj->{xVersionCPL};}; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
11
|
|
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
=head2 videoSource([$url]) |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
Accessor routine to set or read videoSource. |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
=cut |
269
|
|
|
|
|
|
|
|
270
|
2
|
50
|
|
2
|
1
|
523
|
sub videoSource { my $obj = shift; $obj->{videoSource} = shift if @_; return $obj->{videoSource};}; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
8
|
|
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
=head2 xWebServiceLoc([$url]) |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
Accessor routine to set or read xWebServiceLoc. |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
=cut |
277
|
|
|
|
|
|
|
|
278
|
2
|
50
|
|
2
|
1
|
3
|
sub xWebServiceLoc { my $obj = shift; $obj->{xWebServiceLoc} = shift if @_; return $obj->{xWebServiceLoc};}; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
7
|
|
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
=head2 loggingService([$url]) |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
Accessor routine to set or read loggingService. |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
=cut |
285
|
|
|
|
|
|
|
|
286
|
2
|
50
|
|
2
|
1
|
2
|
sub loggingService { my $obj = shift; $obj->{loggingService} = shift if @_; return $obj->{loggingService};}; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
6
|
|
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
=head2 skinButtons([$url]) |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
Accessor routine to set or read skinButtons. These are optional, and used to form the control bar. |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
=cut |
293
|
|
|
|
|
|
|
|
294
|
2
|
50
|
|
2
|
1
|
3
|
sub skinButtons { my $obj = shift; $obj->{skinButtons} = shift if @_; return $obj->{skinButtons};}; |
|
2
|
|
|
|
|
7
|
|
|
2
|
|
|
|
|
7
|
|
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
=head2 backgroundHTML([$url]) |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
Accessor routine to set or read backgroundHTML. |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
=cut |
301
|
|
|
|
|
|
|
|
302
|
2
|
50
|
|
2
|
1
|
3
|
sub backgroundHTML { my $obj = shift; $obj->{backgroundHTML} = shift if @_; return $obj->{backgroundHTML};}; |
|
2
|
|
|
|
|
8
|
|
|
2
|
|
|
|
|
7
|
|
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
=head2 videoWidth([$string]) |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
Accessor routine to set or read videoWidth. |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
=cut |
309
|
|
|
|
|
|
|
|
310
|
2
|
50
|
|
2
|
1
|
3
|
sub videoWidth { my $obj = shift; $obj->{videoWidth} = shift if @_; return $obj->{videoWidth};}; |
|
2
|
|
|
|
|
7
|
|
|
2
|
|
|
|
|
7
|
|
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
=head2 videoHeight([$string]) |
313
|
|
|
|
|
|
|
|
314
|
|
|
|
|
|
|
Accessor routine to set or read videoHeight. |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
=cut |
317
|
|
|
|
|
|
|
|
318
|
2
|
50
|
|
2
|
1
|
3
|
sub videoHeight { my $obj = shift; $obj->{videoHeight} = shift if @_; return $obj->{videoHeight};}; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
8
|
|
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
=head2 frameWidth([$string]) |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
Accessor routine to set or read frameWidth. |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
=cut |
325
|
|
|
|
|
|
|
|
326
|
2
|
50
|
|
2
|
1
|
3
|
sub frameWidth { my $obj = shift; $obj->{frameWidth} = shift if @_; return $obj->{frameWidth};}; |
|
2
|
|
|
|
|
9
|
|
|
2
|
|
|
|
|
7
|
|
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
=head2 frameHeight([$string]) |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
Accessor routine to set or read frameHeight. |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
=cut |
333
|
|
|
|
|
|
|
|
334
|
2
|
50
|
|
2
|
1
|
4
|
sub frameHeight { my $obj = shift; $obj->{frameHeight} = shift if @_; return $obj->{frameHeight};}; |
|
2
|
|
|
|
|
5
|
|
|
2
|
|
|
|
|
8
|
|
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
=head2 videoX([$string]) |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
Accessor routine to set or read videoX. |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
=cut |
341
|
|
|
|
|
|
|
|
342
|
2
|
50
|
|
2
|
1
|
7
|
sub videoX { my $obj = shift; $obj->{videoX} = shift if @_; return $obj->{videoX};}; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
13
|
|
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
=head2 videoY([$string]) |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
Accessor routine to set or read videoY. |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
=cut |
349
|
|
|
|
|
|
|
|
350
|
2
|
50
|
|
2
|
1
|
3
|
sub videoY { my $obj = shift; $obj->{videoY} = shift if @_; return $obj->{videoY};}; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
8
|
|
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
=head2 videoViewLayout([$layoutname]) |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
Accessor routine to set or read videoViewLayout. |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
=cut |
357
|
|
|
|
|
|
|
|
358
|
2
|
50
|
|
2
|
1
|
2
|
sub videoViewLayout { my $obj = shift; $obj->{videoViewLayout} = shift if @_; return $obj->{videoViewLayout};}; |
|
2
|
|
|
|
|
7
|
|
|
2
|
|
|
|
|
7
|
|
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
=head2 webViewLayout([$layoutname]) |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
Accessor routine to set or read webViewLayout. |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
=cut |
365
|
|
|
|
|
|
|
|
366
|
2
|
50
|
|
2
|
1
|
2
|
sub webViewLayout { my $obj = shift; $obj->{webViewLayout} = shift if @_; return $obj->{webViewLayout};}; |
|
2
|
|
|
|
|
8
|
|
|
2
|
|
|
|
|
6
|
|
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
=head2 youtubeID([$id]) |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
Accessor routine to set or read youtubeID. |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
=cut |
373
|
|
|
|
|
|
|
|
374
|
2
|
50
|
|
2
|
1
|
4
|
sub youtubeID { my $obj = shift; $obj->{youtubeID} = shift if @_; return $obj->{youtubeID};}; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
8
|
|
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
=head2 xUniqueID([$id]) |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
Accessor routine to set or read xUniqueID. |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
=cut |
381
|
|
|
|
|
|
|
|
382
|
2
|
50
|
|
2
|
1
|
3
|
sub xUniqueID { my $obj = shift; $obj->{xUniqueID} = shift if @_; return $obj->{xUniqueID};}; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
8
|
|
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
=head2 xProgLevelDir([$id]) |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
Accessor routine to set or read xProgLevelDir. |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
=cut |
389
|
|
|
|
|
|
|
|
390
|
2
|
50
|
|
2
|
1
|
2
|
sub xProgLevelDir { my $obj = shift; $obj->{xProgLevelDir} = shift if @_; return $obj->{xProgLevelDir};}; |
|
2
|
|
|
|
|
6
|
|
|
2
|
|
|
|
|
7
|
|
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
=head2 video([$video1,$video2,$video3}]) |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
Accessor routine for the video field, which contains an array of three different video sources which can be used. |
395
|
|
|
|
|
|
|
Returns an array, or undef if it has not been set. |
396
|
|
|
|
|
|
|
Takes an array of 3 urls. |
397
|
|
|
|
|
|
|
There is no way to set an individual URL with this accessor; read and then write to set one. |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
=cut |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
sub video { |
402
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
403
|
0
|
0
|
|
|
|
0
|
if (@_){ |
404
|
0
|
0
|
|
|
|
0
|
if ($obj->{video}){ |
405
|
0
|
|
|
|
|
0
|
my @a = @{$obj->{video}[0]{source}}; |
|
0
|
|
|
|
|
0
|
|
406
|
0
|
|
|
|
|
0
|
my @new = @_; |
407
|
|
|
|
|
|
|
#who knows if the number of video fields will change in the future |
408
|
0
|
0
|
0
|
|
|
0
|
confess("confused on video a $#a new $#new\n") if ($#a != $#new) && (($#a != 2) || ($#new != 2)); |
|
|
|
0
|
|
|
|
|
409
|
0
|
|
|
|
|
0
|
foreach my $ia (0..$#a){ |
410
|
0
|
|
|
|
|
0
|
my %h = %{$a[$ia]}; |
|
0
|
|
|
|
|
0
|
|
411
|
0
|
|
|
|
|
0
|
$h{src} = $new[$ia]; |
412
|
|
|
|
|
|
|
} |
413
|
0
|
|
|
|
|
0
|
return @new; |
414
|
|
|
|
|
|
|
} else { |
415
|
0
|
|
|
|
|
0
|
$obj->{video} = [{source => []}]; |
416
|
0
|
|
|
|
|
0
|
foreach my $s (@_){ |
417
|
0
|
|
|
|
|
0
|
push @{$obj->{video}[0]{source}},{src => $s}; |
|
0
|
|
|
|
|
0
|
|
418
|
|
|
|
|
|
|
} |
419
|
0
|
|
|
|
|
0
|
return @_; |
420
|
|
|
|
|
|
|
} |
421
|
|
|
|
|
|
|
} else { |
422
|
0
|
0
|
|
|
|
0
|
return undef if !$obj->{video}; |
423
|
0
|
|
|
|
|
0
|
my @a = @{$obj->{video}[0]{source}}; |
|
0
|
|
|
|
|
0
|
|
424
|
0
|
|
|
|
|
0
|
my @ret; |
425
|
0
|
|
|
|
|
0
|
foreach my $ia (0..$#a){ |
426
|
0
|
|
|
|
|
0
|
my %h = %{$a[$ia]}; |
|
0
|
|
|
|
|
0
|
|
427
|
0
|
|
|
|
|
0
|
push @ret,$h{src}; |
428
|
|
|
|
|
|
|
} |
429
|
0
|
|
|
|
|
0
|
return @ret; |
430
|
|
|
|
|
|
|
} |
431
|
|
|
|
|
|
|
} |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
=head2 tl($cuepointname) |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
Create a targetList with one element. |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
=cut |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
sub tl { |
440
|
1
|
|
|
1
|
1
|
6
|
my $obj = shift; |
441
|
1
|
|
|
|
|
2
|
my $s = shift; |
442
|
1
|
|
|
|
|
7
|
my $t = new Video::CPL::Target(cuePointRef=>$s); |
443
|
1
|
|
|
|
|
9
|
my $tl = new Video::CPL::TargetList(target=>[$t]); |
444
|
|
|
|
|
|
|
#print "tl returning:\n",Dumper($tl); |
445
|
1
|
|
|
|
|
4
|
return $tl; |
446
|
|
|
|
|
|
|
} |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
=head2 parsectv() |
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
=cut |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
my @FIELDS = qw(backgroundHTML frameHeight frameWidth loggingService skinButtons |
453
|
|
|
|
|
|
|
videoHeight videoSource videoViewLayout videoWidth videoX videoY |
454
|
|
|
|
|
|
|
webViewLayout xProgLevelData xProgLevelDir xUniqueID xVersionCPL |
455
|
|
|
|
|
|
|
xWebServiceLoc xmlns:xsi xsi:noNamespaceSchemaLocation youtubeID); |
456
|
|
|
|
|
|
|
my @MPFIELDS = qw(xmlns:xsi xsi:noNamespaceSchemaLocation); |
457
|
|
|
|
|
|
|
my @PLMFIELDS = qw(backgroundHTML frameHeight frameWidth loggingService skinButtons |
458
|
|
|
|
|
|
|
videoHeight videoSource videoViewLayout videoWidth videoX videoY |
459
|
|
|
|
|
|
|
webViewLayout xProgLevelData xProgLevelDir xUniqueID xVersionCPL |
460
|
|
|
|
|
|
|
xWebServiceLoc youtubeID); |
461
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
sub parsectv { |
463
|
1
|
|
|
1
|
1
|
2
|
my $obj = shift; |
464
|
1
|
|
|
|
|
2
|
my $initfromctv = shift; |
465
|
1
|
|
|
|
|
7
|
my $ref = XMLin($initfromctv,ForceArray=>1,KeyAttr=>{},KeepRoot=>1); |
466
|
1
|
|
|
|
|
17167
|
my %d = %{$ref}; |
|
1
|
|
|
|
|
3
|
|
467
|
1
|
|
|
|
|
4
|
$obj->{'xsi:noNamespaceSchemaLocation'} = $d{"xsi:noNamespaceSchemaLocation"}; |
468
|
1
|
|
|
|
|
3
|
$obj->{'xmlns:xsi'} = $d{"xmlns:xsi"}; |
469
|
1
|
|
|
|
|
3
|
foreach my $q (@MPFIELDS){ |
470
|
2
|
50
|
|
|
|
12
|
$obj->{$q} = $d{MediaProgram}[0]{$q} if defined($d{MediaProgram}[0]{$q}); |
471
|
|
|
|
|
|
|
} |
472
|
1
|
|
|
|
|
3
|
foreach my $q (@PLMFIELDS){ |
473
|
18
|
100
|
|
|
|
61
|
$obj->{$q} = $d{MediaProgram}[0]{progLevelMetadata}[0]{$q} if defined($d{MediaProgram}[0]{progLevelMetadata}[0]{$q}); |
474
|
|
|
|
|
|
|
} |
475
|
1
|
|
|
|
|
2
|
foreach my $q ("video"){ |
476
|
1
|
50
|
|
|
|
25
|
$obj->{$q} = $d{MediaProgram}[0]{progLevelMetadata}[0]{$q} if defined($d{MediaProgram}[0]{progLevelMetadata}[0]{$q}); |
477
|
|
|
|
|
|
|
} |
478
|
|
|
|
|
|
|
#$obj->{video} = $d{MediaProgram}[0]{progLevelMetadata[0]{video} |
479
|
|
|
|
|
|
|
#process annotations |
480
|
1
|
50
|
|
|
|
3
|
if (defined $d{MediaProgram}[0]{annotations}){ |
481
|
1
|
|
|
|
|
1
|
my @a; |
482
|
1
|
|
|
|
|
2
|
foreach my $x (@{$d{MediaProgram}[0]{annotations}[0]{annotation}}){ |
|
1
|
|
|
|
|
5
|
|
483
|
1
|
|
|
|
|
6
|
push @a,Video::CPL::Annotation::fromxml($obj,$x); |
484
|
|
|
|
|
|
|
} |
485
|
1
|
|
|
|
|
4
|
$obj->{annotations} = \@a; |
486
|
|
|
|
|
|
|
} |
487
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
#process layouts |
489
|
1
|
50
|
|
|
|
4
|
if (defined $d{MediaProgram}[0]{layouts}){ |
490
|
1
|
|
|
|
|
2
|
my @l; |
491
|
1
|
|
|
|
|
2
|
foreach my $x (@{$d{MediaProgram}[0]{layouts}[0]{layout}}){ |
|
1
|
|
|
|
|
6
|
|
492
|
2
|
|
|
|
|
16
|
push @l,Video::CPL::Layout::fromxml($x); |
493
|
|
|
|
|
|
|
} |
494
|
1
|
|
|
|
|
3
|
$obj->{layouts} = \@l; |
495
|
|
|
|
|
|
|
} |
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
#process cuePoints |
498
|
1
|
50
|
|
|
|
3
|
if (defined $d{MediaProgram}[0]{cuePoints}){ |
499
|
1
|
|
|
|
|
2
|
foreach my $x (@{$d{MediaProgram}[0]{cuePoints}[0]{cuePt}}){ |
|
1
|
|
|
|
|
4
|
|
500
|
1
|
|
|
|
|
5
|
$obj->addcue(Video::CPL::Cue::fromxml($obj,$x)); |
501
|
|
|
|
|
|
|
} |
502
|
|
|
|
|
|
|
} |
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
#process webPoints |
505
|
1
|
50
|
|
|
|
13
|
if (defined $d{MediaProgram}[0]{webPoints}){ |
506
|
0
|
|
|
|
|
0
|
foreach my $x (@{$d{MediaProgram}[0]{webPoints}[0]{cuePt}}){ |
|
0
|
|
|
|
|
0
|
|
507
|
0
|
|
|
|
|
0
|
$obj->addwp(Video::CPL::Cue::fromxml($obj,$x)); |
508
|
|
|
|
|
|
|
} |
509
|
|
|
|
|
|
|
} |
510
|
|
|
|
|
|
|
#done |
511
|
|
|
|
|
|
|
} |
512
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
=head2 newname("base") |
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
Returns a name of the form "basedddddddd" which is not used by any other cue point or annotation in this CPL object. |
516
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
=cut |
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
sub newname { |
520
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
521
|
0
|
|
0
|
|
|
0
|
my $base = shift || "name"; |
522
|
0
|
|
|
|
|
0
|
my $name; |
523
|
0
|
|
0
|
|
|
0
|
do { |
524
|
0
|
|
|
|
|
0
|
$name = $base.int(rand(100000000)); |
525
|
|
|
|
|
|
|
} until ! defined($obj->cuebyname($name)) && !defined($obj->annobyname($name)); |
526
|
0
|
|
|
|
|
0
|
return $name; |
527
|
|
|
|
|
|
|
} |
528
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
=head2 addcue($cue); |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
Adds the created cue to the CPL object. This is not needed if reading the cue points from the video file itself, e.g. with a local .flv file. |
533
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
=cut |
535
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
sub addcue { |
537
|
1
|
|
|
1
|
1
|
2
|
my $obj = shift; |
538
|
1
|
|
|
|
|
1
|
my $cue = shift; |
539
|
1
|
|
|
|
|
2
|
$cue->parent($obj); |
540
|
1
|
50
|
|
|
|
4
|
confess("addcue needs a time in cuePt\n") if !defined($cue->time()); |
541
|
1
|
|
|
|
|
1
|
push @{$obj->{cuePoints}},$cue; |
|
1
|
|
|
|
|
2
|
|
542
|
1
|
|
|
|
|
1
|
my @a = @{$obj->{cuePoints}}; |
|
1
|
|
|
|
|
3
|
|
543
|
1
|
50
|
|
|
|
2
|
if ($#a > 0){ |
544
|
0
|
|
|
|
|
0
|
my $last = $a[$#a]; |
545
|
0
|
|
|
|
|
0
|
my $nexttolast = $a[$#a-1]; |
546
|
0
|
0
|
|
|
|
0
|
if ($last->time() <= $nexttolast->time()) { |
547
|
0
|
|
|
|
|
0
|
@{$obj->{cuePoints}} = sort {$a->time() <=> $b->time()} @a; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
548
|
|
|
|
|
|
|
} |
549
|
|
|
|
|
|
|
} |
550
|
1
|
|
|
|
|
3
|
return $cue; |
551
|
|
|
|
|
|
|
} |
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
sub getcptimes { |
554
|
0
|
|
|
0
|
0
|
0
|
my $obj = shift; |
555
|
0
|
|
|
|
|
0
|
my @ret; |
556
|
0
|
0
|
|
|
|
0
|
return @ret if !exists($obj->{cuePoints}); |
557
|
0
|
|
|
|
|
0
|
my @a = @{$obj->{cuePoints}}; |
|
0
|
|
|
|
|
0
|
|
558
|
0
|
|
|
|
|
0
|
foreach my $a (@a){ |
559
|
0
|
|
|
|
|
0
|
push @ret, $a->time(); |
560
|
|
|
|
|
|
|
} |
561
|
0
|
|
|
|
|
0
|
return @ret; |
562
|
|
|
|
|
|
|
} |
563
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
sub cuetostring { |
565
|
0
|
|
|
0
|
0
|
0
|
my $obj = shift; |
566
|
0
|
|
|
|
|
0
|
my $cue = shift; |
567
|
0
|
0
|
|
|
|
0
|
if ($cue->parent() == $obj){ |
568
|
0
|
|
|
|
|
0
|
return "#".$cue->name(); |
569
|
|
|
|
|
|
|
} |
570
|
|
|
|
|
|
|
#if same object then #foo |
571
|
|
|
|
|
|
|
#if same directory (think: dynamic, html and ref but no file) then foo.ctv#foo |
572
|
|
|
|
|
|
|
#think. user specified full html and ref or no ref. Only need http if not specified. |
573
|
|
|
|
|
|
|
#else full url |
574
|
0
|
|
|
|
|
0
|
confess; |
575
|
|
|
|
|
|
|
} |
576
|
|
|
|
|
|
|
|
577
|
|
|
|
|
|
|
sub annotostring { |
578
|
0
|
|
|
0
|
0
|
0
|
my $obj = shift; |
579
|
0
|
|
|
|
|
0
|
my $anno = shift; |
580
|
|
|
|
|
|
|
#see comments for cuetostring re local versus same versus remote |
581
|
0
|
|
|
|
|
0
|
confess; |
582
|
|
|
|
|
|
|
} |
583
|
|
|
|
|
|
|
|
584
|
|
|
|
|
|
|
sub converttarget { |
585
|
0
|
|
|
0
|
0
|
0
|
my $obj = shift; |
586
|
0
|
|
|
|
|
0
|
my %p = @_; |
587
|
0
|
0
|
|
|
|
0
|
return %p if !exists $p{target}; |
588
|
0
|
0
|
|
|
|
0
|
confess("converttarget given a null target\n") if !defined $p{target}; |
589
|
0
|
|
|
|
|
0
|
my $t = $p{target}; |
590
|
0
|
|
|
|
|
0
|
my @a; |
591
|
0
|
0
|
|
|
|
0
|
if (ref($t) eq "ARRAY"){ |
592
|
0
|
|
|
|
|
0
|
@a = @{$t} |
|
0
|
|
|
|
|
0
|
|
593
|
|
|
|
|
|
|
} else { |
594
|
0
|
|
|
|
|
0
|
push @a,$t; |
595
|
|
|
|
|
|
|
} |
596
|
0
|
|
|
|
|
0
|
delete $p{target}; |
597
|
0
|
|
|
|
|
0
|
$p{targetList} = new Video::CPL::TargetList(); |
598
|
0
|
0
|
|
|
|
0
|
if (defined $p{backgroundPicLoc}){ |
599
|
0
|
|
|
|
|
0
|
$p{targetList}->backgroundPicLoc($p{backgroundPicLoc}); |
600
|
0
|
|
|
|
|
0
|
delete $p{backgroundPicLoc}; |
601
|
|
|
|
|
|
|
} |
602
|
0
|
0
|
|
|
|
0
|
if (defined $p{headerText}){ |
603
|
0
|
|
|
|
|
0
|
$p{targetList}->headerText($p{headerText}); |
604
|
0
|
|
|
|
|
0
|
delete $p{headerText}; |
605
|
|
|
|
|
|
|
} |
606
|
0
|
0
|
|
|
|
0
|
if (defined $p{operation}){ |
607
|
0
|
|
|
|
|
0
|
$p{targetList}->operation($p{operation}); |
608
|
0
|
|
|
|
|
0
|
delete $p{operation}; |
609
|
|
|
|
|
|
|
} |
610
|
0
|
|
|
|
|
0
|
my @t; |
611
|
0
|
|
|
|
|
0
|
foreach my $q (@a){ |
612
|
0
|
|
|
|
|
0
|
my $s; |
613
|
0
|
0
|
|
|
|
0
|
if (ref($q) eq "Video::CPL::Cue"){ |
|
|
0
|
|
|
|
|
|
614
|
0
|
|
|
|
|
0
|
$s = $q->reffromobj($obj); |
615
|
|
|
|
|
|
|
} elsif (ref($q) eq "Video::CPL::Annotation"){ |
616
|
0
|
|
|
|
|
0
|
$s = $q->reffromobj($obj); |
617
|
|
|
|
|
|
|
} else { |
618
|
|
|
|
|
|
|
#confess if not scalar. |
619
|
0
|
|
|
|
|
0
|
$s = $q; |
620
|
|
|
|
|
|
|
} |
621
|
0
|
|
|
|
|
0
|
push @t,new Video::CPL::Target(cuePointRef=>$s); |
622
|
|
|
|
|
|
|
} |
623
|
0
|
|
|
|
|
0
|
$p{targetList}->target(\@t); |
624
|
0
|
|
|
|
|
0
|
return %p; |
625
|
|
|
|
|
|
|
} |
626
|
|
|
|
|
|
|
|
627
|
|
|
|
|
|
|
sub convertstory { |
628
|
0
|
|
|
0
|
0
|
0
|
my $obj = shift; |
629
|
0
|
|
|
|
|
0
|
our @FIELDS = qw(balloonText forever picLoc picOverLoc); |
630
|
0
|
|
|
|
|
0
|
my %p = @_; |
631
|
|
|
|
|
|
|
return %p if !defined($p{forever}) && !defined($p{balloonText}) && |
632
|
0
|
0
|
0
|
|
|
0
|
!defined($p{picLoc}) && !defined($p{picOverLoc}); |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
633
|
0
|
|
|
|
|
0
|
$p{story} = new Video::CPL::Story(); |
634
|
0
|
0
|
|
|
|
0
|
if (defined($p{forever})){ |
635
|
0
|
|
|
|
|
0
|
$p{story}->forever($p{forever}); |
636
|
0
|
|
|
|
|
0
|
delete $p{forever}; |
637
|
|
|
|
|
|
|
} |
638
|
0
|
0
|
|
|
|
0
|
if (defined($p{balloonText})){ |
639
|
0
|
|
|
|
|
0
|
$p{story}->balloonText($p{balloonText}); |
640
|
0
|
|
|
|
|
0
|
delete $p{balloonText}; |
641
|
|
|
|
|
|
|
} |
642
|
0
|
0
|
|
|
|
0
|
if (defined($p{picLoc})){ |
643
|
0
|
|
|
|
|
0
|
$p{story}->picLoc($p{picLoc}); |
644
|
0
|
|
|
|
|
0
|
delete $p{picLoc}; |
645
|
|
|
|
|
|
|
} |
646
|
0
|
0
|
|
|
|
0
|
if (defined($p{picOverLoc})){ |
647
|
0
|
|
|
|
|
0
|
$p{story}->picOverLoc($p{picOverLoc}); |
648
|
0
|
|
|
|
|
0
|
delete $p{picLoc}; |
649
|
|
|
|
|
|
|
} |
650
|
0
|
|
|
|
|
0
|
return %p; |
651
|
|
|
|
|
|
|
} |
652
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
=head2 newcue(%cueparms) |
654
|
|
|
|
|
|
|
|
655
|
|
|
|
|
|
|
Create a new Cue point with the given parameters, and set the parent to this CPL object. |
656
|
|
|
|
|
|
|
|
657
|
|
|
|
|
|
|
=cut |
658
|
|
|
|
|
|
|
|
659
|
|
|
|
|
|
|
sub newcue { |
660
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
661
|
0
|
|
|
|
|
0
|
my %parms = @_; |
662
|
0
|
0
|
|
|
|
0
|
confess("newcue needs a time in cuePt\n") if !defined($parms{'time'}); |
663
|
0
|
0
|
|
|
|
0
|
$parms{name} = $obj->newname("cue") if !defined($parms{name}); |
664
|
|
|
|
|
|
|
#convert target to a targetlist with one entry. If there are other Targetlist |
665
|
0
|
0
|
|
|
|
0
|
%parms = $obj->converttarget(%parms) if defined $parms{target}; |
666
|
0
|
0
|
0
|
|
|
0
|
%parms = $obj->convertstory(%parms) if defined($parms{picLoc}) || defined($parms{picOverLoc}) || defined($parms{balloonText}); |
|
|
|
0
|
|
|
|
|
667
|
0
|
|
|
|
|
0
|
my $ret = new Video::CPL::Cue(%parms); |
668
|
0
|
|
|
|
|
0
|
return $obj->addcue($ret); |
669
|
|
|
|
|
|
|
} |
670
|
|
|
|
|
|
|
|
671
|
|
|
|
|
|
|
=head2 story(text=>"some text",pic=>"foo.jpg") |
672
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
Shorthand to create a Video::CPL::Story object. |
674
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
=cut |
676
|
|
|
|
|
|
|
|
677
|
|
|
|
|
|
|
sub story { |
678
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
679
|
0
|
|
|
|
|
0
|
my %parms = @_; |
680
|
0
|
|
|
|
|
0
|
my $ret = Video::CPL::Story->new(%parms); |
681
|
|
|
|
|
|
|
# my $text = $parms{balloonText}; |
682
|
|
|
|
|
|
|
# my $pic = $parms{picLoc}; |
683
|
|
|
|
|
|
|
# my $ret; |
684
|
|
|
|
|
|
|
# if ($pic){ |
685
|
|
|
|
|
|
|
# if ($text){ |
686
|
|
|
|
|
|
|
# } else { |
687
|
|
|
|
|
|
|
# $ret = Video::CPL::Story->new(picLoc=>$pic); |
688
|
|
|
|
|
|
|
# } |
689
|
|
|
|
|
|
|
# } else { |
690
|
|
|
|
|
|
|
# $ret = Video::CPL::Story->new(balloonText=>$text); |
691
|
|
|
|
|
|
|
# } |
692
|
0
|
|
|
|
|
0
|
return $ret; |
693
|
|
|
|
|
|
|
} |
694
|
|
|
|
|
|
|
|
695
|
|
|
|
|
|
|
=head2 layout(%parms) |
696
|
|
|
|
|
|
|
|
697
|
|
|
|
|
|
|
Create a new layout and install it in this CPL. Pass the parameters on to Video::CPL::Layout::new. |
698
|
|
|
|
|
|
|
|
699
|
|
|
|
|
|
|
=cut |
700
|
|
|
|
|
|
|
|
701
|
|
|
|
|
|
|
sub layout { |
702
|
2
|
|
|
2
|
1
|
440
|
my $obj = shift; |
703
|
2
|
|
|
|
|
11
|
my %parms = @_; |
704
|
2
|
|
|
|
|
14
|
my $ret = new Video::CPL::Layout(%parms); |
705
|
2
|
|
|
|
|
3
|
push @{$obj->{layouts}},$ret; |
|
2
|
|
|
|
|
4
|
|
706
|
2
|
|
|
|
|
4
|
return $ret; |
707
|
|
|
|
|
|
|
} |
708
|
|
|
|
|
|
|
|
709
|
|
|
|
|
|
|
=head2 layoutbyname($name) |
710
|
|
|
|
|
|
|
|
711
|
|
|
|
|
|
|
Return the layout with the given name. |
712
|
|
|
|
|
|
|
|
713
|
|
|
|
|
|
|
=cut |
714
|
|
|
|
|
|
|
|
715
|
|
|
|
|
|
|
sub layoutbyname { |
716
|
64
|
|
|
64
|
1
|
94
|
my $obj = shift; |
717
|
64
|
|
|
|
|
57
|
my $name = shift; |
718
|
64
|
50
|
|
|
|
101
|
return undef if !defined($obj->{layouts}); |
719
|
64
|
|
|
|
|
41
|
my @l = @{$obj->{layouts}}; |
|
64
|
|
|
|
|
95
|
|
720
|
64
|
|
|
|
|
67
|
foreach my $l (@l){ |
721
|
64
|
50
|
|
|
|
111
|
return $l if $l->name() eq $name; |
722
|
|
|
|
|
|
|
} |
723
|
0
|
|
|
|
|
0
|
return undef; |
724
|
|
|
|
|
|
|
} |
725
|
|
|
|
|
|
|
|
726
|
|
|
|
|
|
|
=head2 allstories() |
727
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
Return an array with all of the Annotation based Story objects in this CPL. |
729
|
|
|
|
|
|
|
|
730
|
|
|
|
|
|
|
=cut |
731
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
sub allstories { |
733
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
734
|
0
|
|
|
|
|
0
|
my @ret = (); |
735
|
0
|
|
|
|
|
0
|
my @a = $obj->annotations(); |
736
|
0
|
|
|
|
|
0
|
foreach my $a (@a){ |
737
|
0
|
0
|
|
|
|
0
|
push @ret,$a->story() if $a->story(); |
738
|
|
|
|
|
|
|
} |
739
|
0
|
|
|
|
|
0
|
return @ret; |
740
|
|
|
|
|
|
|
} |
741
|
|
|
|
|
|
|
|
742
|
|
|
|
|
|
|
=head2 numcue($k) |
743
|
|
|
|
|
|
|
|
744
|
|
|
|
|
|
|
Returns the k-th cuePoint Cue object. Note that a normally created CPL object will always create a cue point a the beginning, easily obtained with firstcue(), below. |
745
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
=cut |
747
|
|
|
|
|
|
|
|
748
|
|
|
|
|
|
|
sub numcue { |
749
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
750
|
0
|
|
|
|
|
0
|
my $num = shift; |
751
|
0
|
0
|
|
|
|
0
|
if (defined($obj->{cuePoints}[$num])){ |
752
|
0
|
|
|
|
|
0
|
return $obj->{cuePoints}[$num]; |
753
|
|
|
|
|
|
|
} |
754
|
0
|
|
|
|
|
0
|
return undef; |
755
|
|
|
|
|
|
|
} |
756
|
|
|
|
|
|
|
|
757
|
|
|
|
|
|
|
=head2 numwebcue(4) |
758
|
|
|
|
|
|
|
|
759
|
|
|
|
|
|
|
Returns the 4th webPoint object. |
760
|
|
|
|
|
|
|
|
761
|
|
|
|
|
|
|
=cut |
762
|
|
|
|
|
|
|
|
763
|
|
|
|
|
|
|
sub numwebcue { |
764
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
765
|
0
|
|
|
|
|
0
|
my $num = shift; |
766
|
0
|
0
|
|
|
|
0
|
if (defined($obj->{webPoints}[$num])){ |
767
|
0
|
|
|
|
|
0
|
return $obj->{webPoints}[$num]; |
768
|
|
|
|
|
|
|
} |
769
|
0
|
|
|
|
|
0
|
die "Error: There is no web cue numbered $num for ($obj->{videoSource}). Does it not have any web cue points?\n"; |
770
|
0
|
|
|
|
|
0
|
return undef; |
771
|
|
|
|
|
|
|
} |
772
|
|
|
|
|
|
|
|
773
|
|
|
|
|
|
|
=head2 maxweb() |
774
|
|
|
|
|
|
|
|
775
|
|
|
|
|
|
|
=cut |
776
|
|
|
|
|
|
|
|
777
|
|
|
|
|
|
|
sub maxweb { |
778
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
779
|
0
|
|
|
|
|
0
|
my @a = @{$obj->{webPoints}}; |
|
0
|
|
|
|
|
0
|
|
780
|
0
|
|
|
|
|
0
|
return $#a; |
781
|
|
|
|
|
|
|
} |
782
|
|
|
|
|
|
|
|
783
|
|
|
|
|
|
|
=head2 max() |
784
|
|
|
|
|
|
|
|
785
|
|
|
|
|
|
|
=cut |
786
|
|
|
|
|
|
|
|
787
|
|
|
|
|
|
|
sub max { |
788
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
789
|
0
|
|
|
|
|
0
|
my @a = @{$obj->{cuePoints}}; |
|
0
|
|
|
|
|
0
|
|
790
|
0
|
|
|
|
|
0
|
return $#a; |
791
|
|
|
|
|
|
|
} |
792
|
|
|
|
|
|
|
|
793
|
|
|
|
|
|
|
=head2 firstcue() |
794
|
|
|
|
|
|
|
|
795
|
|
|
|
|
|
|
Returns the first cuePoint Cue object. |
796
|
|
|
|
|
|
|
|
797
|
|
|
|
|
|
|
=cut |
798
|
|
|
|
|
|
|
|
799
|
|
|
|
|
|
|
sub firstcue { |
800
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
801
|
0
|
0
|
|
|
|
0
|
if (defined($obj->{cuePoints}[0])){ |
802
|
0
|
|
|
|
|
0
|
return $obj->{cuePoints}[0]; |
803
|
|
|
|
|
|
|
} |
804
|
0
|
|
|
|
|
0
|
die "Error: There is no first cue for ($obj->{videoSource}). Does it not have any cue points?\n"; |
805
|
0
|
|
|
|
|
0
|
return undef; |
806
|
|
|
|
|
|
|
} |
807
|
|
|
|
|
|
|
|
808
|
|
|
|
|
|
|
=head2 lastcue() |
809
|
|
|
|
|
|
|
|
810
|
|
|
|
|
|
|
=cut |
811
|
|
|
|
|
|
|
|
812
|
|
|
|
|
|
|
sub lastcue { |
813
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
814
|
0
|
|
|
|
|
0
|
my @a = @{$obj->{cuePoints}}; |
|
0
|
|
|
|
|
0
|
|
815
|
0
|
0
|
|
|
|
0
|
return $a[$#a] if $#a > -1; |
816
|
0
|
|
|
|
|
0
|
die "Error: There is no last cue (last is $#a) for ($obj->{videoSource}). Does it not have any cue points?\n"; |
817
|
0
|
|
|
|
|
0
|
return undef; |
818
|
|
|
|
|
|
|
} |
819
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
=head2 add() |
821
|
|
|
|
|
|
|
Adds a cue point to the end of the cue point list. The parent of the cue point should either |
822
|
|
|
|
|
|
|
not be set, or be correctly set. Cue points may only have one parent, and can therefore not be used |
823
|
|
|
|
|
|
|
in multiple CPL objects. |
824
|
|
|
|
|
|
|
|
825
|
|
|
|
|
|
|
=cut |
826
|
|
|
|
|
|
|
|
827
|
|
|
|
|
|
|
sub add { |
828
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
829
|
0
|
|
|
|
|
0
|
my $cue = shift; |
830
|
0
|
0
|
0
|
|
|
0
|
confess("adding a cue that belongs to someone else\n") if $cue->{parent} && ($cue->{parent} ne $obj); |
831
|
0
|
|
|
|
|
0
|
$cue->{parent} = $obj; |
832
|
0
|
|
|
|
|
0
|
push @{$obj->{cuePoints}},$cue; |
|
0
|
|
|
|
|
0
|
|
833
|
|
|
|
|
|
|
} |
834
|
|
|
|
|
|
|
|
835
|
|
|
|
|
|
|
=head2 webPoints() return all webPoints for the current Video::CPL as an array |
836
|
|
|
|
|
|
|
|
837
|
|
|
|
|
|
|
=cut |
838
|
|
|
|
|
|
|
|
839
|
|
|
|
|
|
|
sub webPoints { |
840
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
841
|
0
|
0
|
|
|
|
0
|
return () if !exists($obj->{webPoints}); |
842
|
0
|
|
|
|
|
0
|
return @{$obj->{webPoints}}; |
|
0
|
|
|
|
|
0
|
|
843
|
|
|
|
|
|
|
} |
844
|
|
|
|
|
|
|
|
845
|
|
|
|
|
|
|
=head2 addwp() |
846
|
|
|
|
|
|
|
|
847
|
|
|
|
|
|
|
=cut |
848
|
|
|
|
|
|
|
|
849
|
|
|
|
|
|
|
sub addwp { |
850
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
851
|
0
|
|
|
|
|
0
|
my $cue = shift; |
852
|
0
|
|
|
|
|
0
|
$cue->{parent} = $obj; |
853
|
0
|
|
|
|
|
0
|
push @{$obj->{webPoints}},$cue; |
|
0
|
|
|
|
|
0
|
|
854
|
|
|
|
|
|
|
} |
855
|
|
|
|
|
|
|
|
856
|
|
|
|
|
|
|
=head2 addanno() |
857
|
|
|
|
|
|
|
|
858
|
|
|
|
|
|
|
=cut |
859
|
|
|
|
|
|
|
|
860
|
|
|
|
|
|
|
sub addanno { |
861
|
1
|
|
|
1
|
1
|
1
|
my $obj = shift; |
862
|
1
|
|
|
|
|
7
|
my $anno = shift; |
863
|
1
|
|
|
|
|
2
|
push @{$obj->{annotations}},$anno; |
|
1
|
|
|
|
|
5
|
|
864
|
1
|
|
|
|
|
2
|
return $anno; |
865
|
|
|
|
|
|
|
} |
866
|
|
|
|
|
|
|
|
867
|
|
|
|
|
|
|
=head2 annotations() |
868
|
|
|
|
|
|
|
|
869
|
|
|
|
|
|
|
=cut |
870
|
|
|
|
|
|
|
|
871
|
|
|
|
|
|
|
sub annotations { |
872
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
873
|
0
|
0
|
|
|
|
0
|
return @{$obj->{annotations}} if defined($obj->{annotations}); |
|
0
|
|
|
|
|
0
|
|
874
|
0
|
|
|
|
|
0
|
return (); |
875
|
|
|
|
|
|
|
} |
876
|
|
|
|
|
|
|
|
877
|
|
|
|
|
|
|
=head2 webPoint(name=>"aname",interestURL=>"http://somewhere.com/foo.jpg",story=>{picLoc=>"foo.jpg"},tl=>[$target]}); |
878
|
|
|
|
|
|
|
|
879
|
|
|
|
|
|
|
Create and add a new webPoint object. |
880
|
|
|
|
|
|
|
|
881
|
|
|
|
|
|
|
Target can be created with something like Video::CPL::Cue->new("Lost A"); |
882
|
|
|
|
|
|
|
|
883
|
|
|
|
|
|
|
Story is currently just an anonymous hash. It may become an object in a future release. |
884
|
|
|
|
|
|
|
|
885
|
|
|
|
|
|
|
=cut |
886
|
|
|
|
|
|
|
|
887
|
|
|
|
|
|
|
sub webPoint { |
888
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
889
|
0
|
|
|
|
|
0
|
my %parms = @_; |
890
|
0
|
0
|
|
|
|
0
|
$parms{name} = $obj->newname("webcue") if !defined($parms{name}); |
891
|
0
|
0
|
0
|
|
|
0
|
%parms = $obj->convertstory(%parms) if defined($parms{picLoc}) || defined($parms{picOverLoc}) || defined($parms{balloonText}); |
|
|
|
0
|
|
|
|
|
892
|
0
|
|
|
|
|
0
|
my $cue = Video::CPL::Cue->new(cueType=>'webPoint',%parms); |
893
|
0
|
|
|
|
|
0
|
$obj->addwp($cue); |
894
|
0
|
|
|
|
|
0
|
return $cue; |
895
|
|
|
|
|
|
|
} |
896
|
|
|
|
|
|
|
|
897
|
|
|
|
|
|
|
=head2 goto(name=>"aname",tl=>[$target]}); |
898
|
|
|
|
|
|
|
|
899
|
|
|
|
|
|
|
Create and add a new goto object. |
900
|
|
|
|
|
|
|
|
901
|
|
|
|
|
|
|
Target can be created with something like Video::CPL::Cue->new("Lost A"); |
902
|
|
|
|
|
|
|
|
903
|
|
|
|
|
|
|
=cut |
904
|
|
|
|
|
|
|
|
905
|
|
|
|
|
|
|
sub goto { |
906
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
907
|
0
|
|
|
|
|
0
|
my %parms = @_; |
908
|
|
|
|
|
|
|
#support old code for a while |
909
|
0
|
0
|
0
|
|
|
0
|
if (defined($parms{dest}) && !defined($parms{target})){ |
910
|
0
|
|
|
|
|
0
|
$parms{target} = $parms{dest}; |
911
|
0
|
|
|
|
|
0
|
undef($parms{dest}); |
912
|
|
|
|
|
|
|
} |
913
|
0
|
0
|
0
|
|
|
0
|
if (defined($parms{tl}) && !defined($parms{target})){ |
914
|
0
|
|
|
|
|
0
|
$parms{target} = shift @{$parms{tl}}; |
|
0
|
|
|
|
|
0
|
|
915
|
0
|
|
|
|
|
0
|
undef($parms{tl}); |
916
|
|
|
|
|
|
|
} |
917
|
0
|
0
|
|
|
|
0
|
$parms{zeroLen} = "true" if !defined $parms{zeroLen}; |
918
|
0
|
|
|
|
|
0
|
return $obj->newcue(cueType=>'goto',%parms); |
919
|
|
|
|
|
|
|
} |
920
|
|
|
|
|
|
|
|
921
|
|
|
|
|
|
|
=head2 regular(name=>"cuename",time=>1.0,interestURL=>"http://somewhere.com/foo.html"); |
922
|
|
|
|
|
|
|
|
923
|
|
|
|
|
|
|
Create and add a new regular object. |
924
|
|
|
|
|
|
|
|
925
|
|
|
|
|
|
|
=cut |
926
|
|
|
|
|
|
|
|
927
|
|
|
|
|
|
|
sub regular { |
928
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
929
|
0
|
|
|
|
|
0
|
my %parms = @_; |
930
|
0
|
|
|
|
|
0
|
return $obj->newcue(cueType=>'regular',%parms); |
931
|
|
|
|
|
|
|
} |
932
|
|
|
|
|
|
|
|
933
|
|
|
|
|
|
|
=head2 insertPt(name=>"cuename",time=>1.0); |
934
|
|
|
|
|
|
|
|
935
|
|
|
|
|
|
|
Create and add a new regular object. |
936
|
|
|
|
|
|
|
|
937
|
|
|
|
|
|
|
=cut |
938
|
|
|
|
|
|
|
|
939
|
|
|
|
|
|
|
sub insertPt { |
940
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
941
|
0
|
|
|
|
|
0
|
my %parms = @_; |
942
|
0
|
|
|
|
|
0
|
return $obj->newcue(cueType=>'insertPt',%parms); |
943
|
|
|
|
|
|
|
} |
944
|
|
|
|
|
|
|
|
945
|
|
|
|
|
|
|
=head2 cuebyname($name) |
946
|
|
|
|
|
|
|
|
947
|
|
|
|
|
|
|
Return the first cue with the given name. |
948
|
|
|
|
|
|
|
|
949
|
|
|
|
|
|
|
=cut |
950
|
|
|
|
|
|
|
|
951
|
|
|
|
|
|
|
sub cuebyname { |
952
|
56
|
|
|
56
|
1
|
75
|
my $obj = shift; |
953
|
56
|
|
|
|
|
49
|
my $name = shift; |
954
|
56
|
|
33
|
|
|
72
|
return $obj->cuePointbyname($name) || $obj->webPointbyname($name); |
955
|
|
|
|
|
|
|
} |
956
|
|
|
|
|
|
|
|
957
|
|
|
|
|
|
|
=head2 cuePointbyname($name) |
958
|
|
|
|
|
|
|
|
959
|
|
|
|
|
|
|
Return the first cuePoint with the given name. |
960
|
|
|
|
|
|
|
|
961
|
|
|
|
|
|
|
=cut |
962
|
|
|
|
|
|
|
|
963
|
|
|
|
|
|
|
sub cuePointbyname { |
964
|
56
|
|
|
56
|
1
|
45
|
my $obj = shift; |
965
|
56
|
|
|
|
|
27
|
my $name = shift; |
966
|
56
|
50
|
|
|
|
80
|
confess "cuePointbyname no name\n" if !$name; |
967
|
56
|
50
|
|
|
|
77
|
if (defined($obj->{cuePoints})){ |
968
|
56
|
|
|
|
|
40
|
my @cuePoints = @{$obj->{cuePoints}}; |
|
56
|
|
|
|
|
66
|
|
969
|
56
|
|
|
|
|
53
|
foreach my $q (@cuePoints){ |
970
|
56
|
50
|
|
|
|
100
|
return $q if $q->name() eq $name; |
971
|
|
|
|
|
|
|
} |
972
|
|
|
|
|
|
|
} |
973
|
0
|
|
|
|
|
0
|
return undef; |
974
|
|
|
|
|
|
|
} |
975
|
|
|
|
|
|
|
|
976
|
|
|
|
|
|
|
=head2 webPointbyname($name) |
977
|
|
|
|
|
|
|
|
978
|
|
|
|
|
|
|
Return the first webPoint with the given name. |
979
|
|
|
|
|
|
|
|
980
|
|
|
|
|
|
|
=cut |
981
|
|
|
|
|
|
|
|
982
|
|
|
|
|
|
|
sub webPointbyname { |
983
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
984
|
0
|
|
|
|
|
0
|
my $name = shift; |
985
|
0
|
0
|
|
|
|
0
|
if (defined($obj->{webPoints})){ |
986
|
0
|
|
|
|
|
0
|
my @webPoints = @{$obj->{webPoints}}; |
|
0
|
|
|
|
|
0
|
|
987
|
0
|
|
|
|
|
0
|
foreach my $q (@webPoints){ |
988
|
0
|
0
|
|
|
|
0
|
return $q if $q->name() eq $name; |
989
|
|
|
|
|
|
|
} |
990
|
|
|
|
|
|
|
} |
991
|
0
|
|
|
|
|
0
|
return undef; |
992
|
|
|
|
|
|
|
} |
993
|
|
|
|
|
|
|
|
994
|
|
|
|
|
|
|
=head2 cuebytime($time) |
995
|
|
|
|
|
|
|
|
996
|
|
|
|
|
|
|
Return the cuePt with the given time, or undef. |
997
|
|
|
|
|
|
|
|
998
|
|
|
|
|
|
|
=cut |
999
|
|
|
|
|
|
|
|
1000
|
|
|
|
|
|
|
sub cuebytime { |
1001
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
1002
|
0
|
|
|
|
|
0
|
my $time = shift; |
1003
|
0
|
0
|
|
|
|
0
|
return undef if !defined($obj->{cuePoints}); |
1004
|
0
|
|
|
|
|
0
|
my @cuePoints = @{$obj->{cuePoints}}; |
|
0
|
|
|
|
|
0
|
|
1005
|
0
|
|
|
|
|
0
|
foreach my $q (@cuePoints){ |
1006
|
0
|
0
|
|
|
|
0
|
return $q if $q->time() eq $time; |
1007
|
|
|
|
|
|
|
} |
1008
|
0
|
|
|
|
|
0
|
return undef; |
1009
|
|
|
|
|
|
|
} |
1010
|
|
|
|
|
|
|
|
1011
|
|
|
|
|
|
|
|
1012
|
|
|
|
|
|
|
=head2 annobyname("name") |
1013
|
|
|
|
|
|
|
|
1014
|
|
|
|
|
|
|
Return the first annotation with the given name. |
1015
|
|
|
|
|
|
|
|
1016
|
|
|
|
|
|
|
=cut |
1017
|
|
|
|
|
|
|
|
1018
|
|
|
|
|
|
|
sub annobyname { |
1019
|
44
|
|
|
44
|
1
|
74
|
my $obj = shift; |
1020
|
44
|
|
|
|
|
35
|
my $name = shift; |
1021
|
44
|
50
|
|
|
|
63
|
return undef if !defined $obj->{annotations}; |
1022
|
44
|
|
|
|
|
26
|
my @annos = @{$obj->{annotations}}; |
|
44
|
|
|
|
|
58
|
|
1023
|
|
|
|
|
|
|
#print STDERR "in annobyanme annos is ",Dumper(\@annos),"\n"; |
1024
|
44
|
|
|
|
|
49
|
foreach my $q (@annos){ |
1025
|
44
|
50
|
|
|
|
107
|
return $q if $q->name() eq $name; |
1026
|
|
|
|
|
|
|
} |
1027
|
0
|
|
|
|
|
0
|
return undef; |
1028
|
|
|
|
|
|
|
} |
1029
|
|
|
|
|
|
|
|
1030
|
|
|
|
|
|
|
=head2 programEnd() |
1031
|
|
|
|
|
|
|
|
1032
|
|
|
|
|
|
|
=cut |
1033
|
|
|
|
|
|
|
|
1034
|
|
|
|
|
|
|
sub programEnd { |
1035
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
1036
|
0
|
|
|
|
|
0
|
my %parms = @_; |
1037
|
0
|
0
|
|
|
|
0
|
$parms{zeroLen} = "true" if !defined $parms{zeroLen}; |
1038
|
0
|
|
|
|
|
0
|
return $obj->newcue(cueType=>'programEnd',%parms); |
1039
|
|
|
|
|
|
|
} |
1040
|
|
|
|
|
|
|
|
1041
|
|
|
|
|
|
|
=head2 returnEnd() |
1042
|
|
|
|
|
|
|
|
1043
|
|
|
|
|
|
|
=cut |
1044
|
|
|
|
|
|
|
|
1045
|
|
|
|
|
|
|
sub returnEnd { |
1046
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
1047
|
0
|
|
|
|
|
0
|
my %parms = @_; |
1048
|
0
|
0
|
|
|
|
0
|
$parms{zeroLen} = "true" if !defined $parms{zeroLen}; |
1049
|
0
|
|
|
|
|
0
|
return $obj->newcue(cueType=>'returnEnd',%parms); |
1050
|
|
|
|
|
|
|
} |
1051
|
|
|
|
|
|
|
|
1052
|
|
|
|
|
|
|
=head2 annotation() |
1053
|
|
|
|
|
|
|
|
1054
|
|
|
|
|
|
|
Create an annotation and add it to the object. |
1055
|
|
|
|
|
|
|
|
1056
|
|
|
|
|
|
|
=cut |
1057
|
|
|
|
|
|
|
|
1058
|
|
|
|
|
|
|
sub annotation { |
1059
|
1
|
|
|
1
|
1
|
3
|
my $obj = shift; |
1060
|
1
|
|
|
|
|
7
|
my %parms = @_; |
1061
|
1
|
50
|
|
|
|
3
|
$parms{parent} = $obj if !defined($parms{parent}); |
1062
|
1
|
|
|
|
|
8
|
my $anno = Video::CPL::Annotation->new(%parms); |
1063
|
1
|
|
|
|
|
5
|
$obj->addanno($anno); |
1064
|
1
|
|
|
|
|
2
|
return $anno; |
1065
|
|
|
|
|
|
|
} |
1066
|
|
|
|
|
|
|
|
1067
|
|
|
|
|
|
|
=head2 adecoration([annotation parameters]) |
1068
|
|
|
|
|
|
|
|
1069
|
|
|
|
|
|
|
=cut |
1070
|
|
|
|
|
|
|
|
1071
|
|
|
|
|
|
|
sub adecoration { |
1072
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
1073
|
0
|
|
|
|
|
0
|
my %parms = @_; |
1074
|
0
|
|
|
|
|
0
|
$parms{clickBehavior} = "javascript"; |
1075
|
0
|
0
|
|
|
|
0
|
$parms{parent} = $obj if !defined($parms{parent}); |
1076
|
0
|
|
|
|
|
0
|
my $anno = Video::CPL::Annotation->new(%parms); |
1077
|
0
|
|
|
|
|
0
|
$obj->addanno($anno); |
1078
|
0
|
|
|
|
|
0
|
return $anno; |
1079
|
|
|
|
|
|
|
} |
1080
|
|
|
|
|
|
|
|
1081
|
|
|
|
|
|
|
=head2 agoto([annotation parameters]) |
1082
|
|
|
|
|
|
|
|
1083
|
|
|
|
|
|
|
adecoration,agoto,ajavascript, and areturnend are shorthand notations to create an annotation and add it |
1084
|
|
|
|
|
|
|
to the current Video::CPL object, setting the parent correctly. Generally they are recommended if the annotation |
1085
|
|
|
|
|
|
|
will be used more than once. |
1086
|
|
|
|
|
|
|
|
1087
|
|
|
|
|
|
|
$anno = $cpl->agoto(balloonText=>"go somewhere",x=>10,y=>10,target=>$somecue); |
1088
|
|
|
|
|
|
|
$cpl->numcue(1)->addanno($anno); |
1089
|
|
|
|
|
|
|
|
1090
|
|
|
|
|
|
|
For a single-use annotation, Annotation::goto may be more convenient. |
1091
|
|
|
|
|
|
|
|
1092
|
|
|
|
|
|
|
$cpl->regular(time=>10)->goto(balloontext=>"go somewhere",x=>10,y=>10); |
1093
|
|
|
|
|
|
|
|
1094
|
|
|
|
|
|
|
This would create a Cue and add an annotation in one statement. |
1095
|
|
|
|
|
|
|
|
1096
|
|
|
|
|
|
|
The annotation parameters are used with normal Annotation constructor; therefore Story parameters such as |
1097
|
|
|
|
|
|
|
picLoc will cause a Story to be automatically generated. |
1098
|
|
|
|
|
|
|
|
1099
|
|
|
|
|
|
|
=cut |
1100
|
|
|
|
|
|
|
|
1101
|
|
|
|
|
|
|
sub agoto { |
1102
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
1103
|
0
|
|
|
|
|
0
|
my %parms = @_; |
1104
|
0
|
|
|
|
|
0
|
$parms{clickBehavior} = "goto"; |
1105
|
0
|
0
|
|
|
|
0
|
$parms{tl} = [$parms{dest}] if defined($parms{dest}); |
1106
|
0
|
|
|
|
|
0
|
undef($parms{dest}); |
1107
|
0
|
0
|
|
|
|
0
|
$parms{parent} = $obj if !defined($parms{parent}); |
1108
|
0
|
|
|
|
|
0
|
my $anno = Video::CPL::Annotation->new(%parms); |
1109
|
0
|
|
|
|
|
0
|
$obj->addanno($anno); |
1110
|
0
|
|
|
|
|
0
|
return $anno; |
1111
|
|
|
|
|
|
|
} |
1112
|
|
|
|
|
|
|
|
1113
|
|
|
|
|
|
|
=head2 ajavascript([annotation paramters]) |
1114
|
|
|
|
|
|
|
|
1115
|
|
|
|
|
|
|
=cut |
1116
|
|
|
|
|
|
|
|
1117
|
|
|
|
|
|
|
sub ajavascript { |
1118
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
1119
|
0
|
|
|
|
|
0
|
my %parms = @_; |
1120
|
0
|
|
|
|
|
0
|
$parms{clickBehavior} = "javascript"; |
1121
|
0
|
0
|
|
|
|
0
|
$parms{parent} = $obj if !defined($parms{parent}); |
1122
|
0
|
|
|
|
|
0
|
my $anno = Video::CPL::Annotation->new(%parms); |
1123
|
0
|
|
|
|
|
0
|
$obj->addanno($anno); |
1124
|
0
|
|
|
|
|
0
|
return $anno; |
1125
|
|
|
|
|
|
|
} |
1126
|
|
|
|
|
|
|
|
1127
|
|
|
|
|
|
|
=head2 areturnend() |
1128
|
|
|
|
|
|
|
|
1129
|
|
|
|
|
|
|
my $anno = $cpl->areturnend(balloonText=>"Return please",x=>10,y=>10); |
1130
|
|
|
|
|
|
|
$cpl->numcue(0)->addanno($anno); |
1131
|
|
|
|
|
|
|
|
1132
|
|
|
|
|
|
|
=cut |
1133
|
|
|
|
|
|
|
|
1134
|
|
|
|
|
|
|
sub areturnend { |
1135
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
1136
|
0
|
|
|
|
|
0
|
my %parms = @_; |
1137
|
0
|
|
|
|
|
0
|
$parms{clickBehavior} = "returnEnd"; |
1138
|
0
|
0
|
|
|
|
0
|
$parms{parent} = $obj if !defined($parms{parent}); |
1139
|
0
|
|
|
|
|
0
|
my $anno = Video::CPL::Annotation->new(%parms); |
1140
|
0
|
|
|
|
|
0
|
$obj->addanno($anno); |
1141
|
0
|
|
|
|
|
0
|
return $anno; |
1142
|
|
|
|
|
|
|
} |
1143
|
|
|
|
|
|
|
|
1144
|
|
|
|
|
|
|
=head2 userChoice() |
1145
|
|
|
|
|
|
|
|
1146
|
|
|
|
|
|
|
=cut |
1147
|
|
|
|
|
|
|
|
1148
|
|
|
|
|
|
|
sub userChoice { |
1149
|
0
|
|
|
0
|
1
|
0
|
my $obj = shift; |
1150
|
0
|
|
|
|
|
0
|
my %parms = @_; |
1151
|
0
|
|
|
|
|
0
|
return $obj->newcue(cueType=>'userChoice',%parms); |
1152
|
|
|
|
|
|
|
} |
1153
|
|
|
|
|
|
|
|
1154
|
|
|
|
|
|
|
=head2 xmlo($xo) |
1155
|
|
|
|
|
|
|
|
1156
|
|
|
|
|
|
|
Add the XML to output this object to the existing XML::Writer object xo. Creation and printing is done outside this routine. |
1157
|
|
|
|
|
|
|
|
1158
|
|
|
|
|
|
|
=cut |
1159
|
|
|
|
|
|
|
|
1160
|
|
|
|
|
|
|
sub xmlo { |
1161
|
1
|
|
|
1
|
1
|
2
|
my $obj = shift; |
1162
|
1
|
|
|
|
|
1
|
my $xo = shift; |
1163
|
|
|
|
|
|
|
|
1164
|
1
|
|
|
|
|
2
|
my %p; |
1165
|
1
|
|
|
|
|
3
|
foreach my $q (@MPFIELDS){ |
1166
|
2
|
50
|
|
|
|
10
|
$p{$q} = $obj->{$q} if defined $obj->{$q}; |
1167
|
|
|
|
|
|
|
} |
1168
|
|
|
|
|
|
|
|
1169
|
1
|
|
|
|
|
5
|
$xo->startTag("MediaProgram",%p); |
1170
|
1
|
|
|
|
|
107
|
%p = (); |
1171
|
|
|
|
|
|
|
#the qw defines the order of the attributes, if some order is preferred. |
1172
|
1
|
|
|
|
|
3
|
foreach my $q (@PLMFIELDS){ |
1173
|
18
|
100
|
|
|
|
42
|
$p{$q} = $obj->{$q} if defined($obj->{$q}); |
1174
|
|
|
|
|
|
|
} |
1175
|
1
|
50
|
|
|
|
3
|
if (exists($obj->{video})){ |
1176
|
0
|
|
|
|
|
0
|
$xo->startTag("progLevelMetadata",%p); |
1177
|
0
|
|
|
|
|
0
|
$xo->startTag("video"); |
1178
|
0
|
|
|
|
|
0
|
my @a = @{$obj->{video}[0]{source}}; |
|
0
|
|
|
|
|
0
|
|
1179
|
0
|
|
|
|
|
0
|
foreach my $ia (0..$#a){ |
1180
|
0
|
|
|
|
|
0
|
my %h = %{$a[$ia]}; |
|
0
|
|
|
|
|
0
|
|
1181
|
0
|
|
|
|
|
0
|
$xo->emptyTag("source",%h); |
1182
|
|
|
|
|
|
|
} |
1183
|
0
|
|
|
|
|
0
|
$xo->endTag("video"); |
1184
|
0
|
|
|
|
|
0
|
$xo->endTag("progLevelMetadata"); |
1185
|
|
|
|
|
|
|
} else { |
1186
|
1
|
|
|
|
|
6
|
$xo->emptyTag("progLevelMetadata",%p); |
1187
|
|
|
|
|
|
|
} |
1188
|
|
|
|
|
|
|
|
1189
|
1
|
|
|
|
|
236
|
foreach my $a (qw(cuePoints webPoints annotations layouts)){ |
1190
|
4
|
100
|
|
|
|
27
|
if ($obj->{$a}){ |
1191
|
3
|
|
|
|
|
5
|
$xo->startTag($a); |
1192
|
3
|
|
|
|
|
55
|
foreach my $c (@{$obj->{$a}}){ |
|
3
|
|
|
|
|
4
|
|
1193
|
4
|
|
|
|
|
194
|
$c->xmlo($xo); |
1194
|
|
|
|
|
|
|
} |
1195
|
3
|
|
|
|
|
41
|
$xo->endTag($a); |
1196
|
|
|
|
|
|
|
} |
1197
|
|
|
|
|
|
|
} |
1198
|
1
|
|
|
|
|
13
|
$xo->endTag("MediaProgram"); |
1199
|
|
|
|
|
|
|
} |
1200
|
|
|
|
|
|
|
|
1201
|
|
|
|
|
|
|
=head2 xml() |
1202
|
|
|
|
|
|
|
|
1203
|
|
|
|
|
|
|
Return the xml format of the current CPL object. This is normally called from print, but can |
1204
|
|
|
|
|
|
|
be called directly. |
1205
|
|
|
|
|
|
|
|
1206
|
|
|
|
|
|
|
=cut |
1207
|
|
|
|
|
|
|
|
1208
|
|
|
|
|
|
|
sub xml { |
1209
|
1
|
|
|
1
|
1
|
2
|
my $obj = shift; |
1210
|
1
|
|
|
|
|
2
|
my $a = ""; |
1211
|
1
|
|
|
|
|
12
|
my $xo = new XML::Writer(OUTPUT=>\$a,NEWLINES=>1); |
1212
|
1
|
|
|
|
|
201
|
$obj->xmlo($xo); |
1213
|
1
|
|
|
|
|
13
|
$xo->end(); |
1214
|
1
|
|
|
|
|
103
|
return $a; |
1215
|
|
|
|
|
|
|
} |
1216
|
|
|
|
|
|
|
|
1217
|
|
|
|
|
|
|
=head2 print() |
1218
|
|
|
|
|
|
|
|
1219
|
|
|
|
|
|
|
Print out the current xml in the automatically created temporary file within the web-viewable file hiearchy. Use before calling embed. |
1220
|
|
|
|
|
|
|
|
1221
|
|
|
|
|
|
|
=cut |
1222
|
|
|
|
|
|
|
|
1223
|
|
|
|
|
|
|
sub print { |
1224
|
0
|
|
|
0
|
1
|
|
my $obj = shift; |
1225
|
0
|
0
|
|
|
|
|
$obj->fixfile() if !$obj->{filefixed}; |
1226
|
0
|
|
|
|
|
|
my $fh = $obj->{fh}; |
1227
|
0
|
|
|
|
|
|
print $fh $obj->xml(); |
1228
|
0
|
|
|
|
|
|
close $fh; |
1229
|
|
|
|
|
|
|
} |
1230
|
|
|
|
|
|
|
|
1231
|
|
|
|
|
|
|
=head2 embed([height=>yyy,width=>xxx]) |
1232
|
|
|
|
|
|
|
|
1233
|
|
|
|
|
|
|
Return the html code used to embed a CPL screen within an html file. |
1234
|
|
|
|
|
|
|
|
1235
|
|
|
|
|
|
|
The height and width parameters are optional, and may be specified as percent or pixels. If not specified, height will be set to 392 pixels and width to 680 pixels. |
1236
|
|
|
|
|
|
|
|
1237
|
|
|
|
|
|
|
CPL parameters that can be specified: |
1238
|
|
|
|
|
|
|
height: Height in pixels or percent. Defaults to frameHeight else videoHeight else 680 pixels. |
1239
|
|
|
|
|
|
|
width: Width in pixels or percent. Defaults to frameWidth else videoWidth else 415 pixels. |
1240
|
|
|
|
|
|
|
player: a URL that reaches the desired Flash player. If not specified, will default to a player |
1241
|
|
|
|
|
|
|
at Coincident TV. This will not be able to access images etc. from a different server unless |
1242
|
|
|
|
|
|
|
there is a file "crossdomain.xml" at the top level of that server. This file should look like |
1243
|
|
|
|
|
|
|
|
1244
|
|
|
|
|
|
|
|
1245
|
|
|
|
|
|
|
|
1246
|
|
|
|
|
|
|
|
1247
|
|
|
|
|
|
|
|
1248
|
|
|
|
|
|
|
|
1249
|
|
|
|
|
|
|
|
1250
|
|
|
|
|
|
|
|
1251
|
|
|
|
|
|
|
media: the URL of the media CTV. If a partial URL, it will be relative to the player. |
1252
|
|
|
|
|
|
|
mergedstyle: if true, include the media as a CGI parameter to the player. This is the norm when using the full CPL experience. |
1253
|
|
|
|
|
|
|
|
1254
|
|
|
|
|
|
|
Additional Adobe parameters: |
1255
|
|
|
|
|
|
|
align: defaults to "middle". |
1256
|
|
|
|
|
|
|
play: defaults to "true". |
1257
|
|
|
|
|
|
|
quality: defaults to "autohigh". |
1258
|
|
|
|
|
|
|
allowfullscreen: defaults to "true". |
1259
|
|
|
|
|
|
|
allowScriptAccess: defaults to "always". In this mode, a webPoint reached from "embed"-ed player |
1260
|
|
|
|
|
|
|
will overwrite the window. |
1261
|
|
|
|
|
|
|
type: defaults to "application/x-shockwave-flash". |
1262
|
|
|
|
|
|
|
pluginspage: defaults to "http://www.adobecom/go/getflashplayer". |
1263
|
|
|
|
|
|
|
bgcolor: Hex value,defaults to "#869ca7". |
1264
|
|
|
|
|
|
|
|
1265
|
|
|
|
|
|
|
=cut |
1266
|
|
|
|
|
|
|
|
1267
|
|
|
|
|
|
|
sub embed { |
1268
|
0
|
|
|
0
|
1
|
|
my $obj = shift; |
1269
|
0
|
|
|
|
|
|
my %parms = @_; |
1270
|
0
|
|
|
|
|
|
my $ret; |
1271
|
0
|
|
0
|
|
|
|
my $media = $parms{media} || $obj->{ctvfilename}; |
1272
|
0
|
|
0
|
|
|
|
my $player = $parms{flexplayer} || "http://metabase.coincident.tv/cpan/player/CTVWebPlayerS.swf"; |
1273
|
0
|
|
|
|
|
|
my $mergedstyle = $parms{mergedstyle}; |
1274
|
|
|
|
|
|
|
|
1275
|
0
|
|
|
|
|
|
my %pr; |
1276
|
|
|
|
|
|
|
#my %pr = $obj->print(%parms); |
1277
|
0
|
0
|
|
|
|
|
$media = $pr{url} if !$parms{media}; |
1278
|
|
|
|
|
|
|
|
1279
|
|
|
|
|
|
|
#good values are 680x415 435x276 314x208 or 1000x595 |
1280
|
|
|
|
|
|
|
#use parameter else frameWidth else videoWidth else 680 (415) |
1281
|
0
|
|
|
|
|
|
my $width = 680; |
1282
|
0
|
0
|
|
|
|
|
$width = $obj->{videoWidth} if exists($obj->{videoWidth}); |
1283
|
0
|
0
|
|
|
|
|
$width = $obj->{frameWidth} if exists($obj->{frameWidth}); |
1284
|
0
|
0
|
|
|
|
|
$width = $parms{width} if exists($parms{width}); |
1285
|
0
|
|
|
|
|
|
my $height = 415; |
1286
|
0
|
0
|
|
|
|
|
$height = $obj->{videoHeight} if exists($obj->{videoHeight}); |
1287
|
0
|
0
|
|
|
|
|
$height = $obj->{frameHeight} if exists($obj->{frameHeight}); |
1288
|
0
|
0
|
|
|
|
|
$height = $parms{height} if exists($parms{height}); |
1289
|
|
|
|
|
|
|
|
1290
|
0
|
0
|
0
|
|
|
|
$media = $obj->{ctvfilename} if !$media && exists($obj->{ctvfilename}); |
1291
|
0
|
0
|
|
|
|
|
confess("No media in embed\n") if !$media; |
1292
|
|
|
|
|
|
|
#print ' |
1293
|
0
|
|
|
|
|
|
my %ret; |
1294
|
0
|
0
|
|
|
|
|
$ret{src} = $mergedstyle?"$player?media=$media":$player; |
1295
|
0
|
0
|
|
|
|
|
$ret{flashvars} = "media=".$media if !$mergedstyle; |
1296
|
0
|
|
|
|
|
|
$ret{width} = $width; |
1297
|
0
|
|
|
|
|
|
$ret{height} = $height; |
1298
|
0
|
0
|
|
|
|
|
$ret{align} = exists($parms{align})?$parms{align}:"middle"; |
1299
|
0
|
0
|
|
|
|
|
$ret{play} = exists($parms{play})?$parms{play}:"true"; |
1300
|
0
|
0
|
|
|
|
|
$ret{quality} = exists($parms{quality})?$parms{quality}:"autohigh"; |
1301
|
0
|
0
|
|
|
|
|
$ret{allowfullscreen} = exists($parms{allowfullscreen})?$parms{allowfullscreen}:"true"; |
1302
|
0
|
0
|
|
|
|
|
$ret{allowScriptAccess} = exists($parms{allowScriptAccess})?$parms{allowScriptAccess}:"always"; |
1303
|
0
|
0
|
|
|
|
|
$ret{type} = exists($parms{type})?$parms{type}:"application/x-shockwave-flash"; |
1304
|
0
|
0
|
|
|
|
|
$ret{pluginspage} = exists($parms{pluginspage})?$parms{pluginspage}:"http://www.adobe.com/go/getflashplayer"; |
1305
|
0
|
0
|
|
|
|
|
$ret{bgcolor} = exists($parms{bgcolor})?$parms{bgcolor}:"#869ca7"; |
1306
|
0
|
|
|
|
|
|
my @ret; |
1307
|
0
|
|
|
|
|
|
foreach my $k (keys %ret){ |
1308
|
0
|
|
|
|
|
|
push @ret, "$k=\"$ret{$k}\""; |
1309
|
|
|
|
|
|
|
} |
1310
|
0
|
|
|
|
|
|
return " |
1311
|
|
|
|
|
|
|
} |
1312
|
|
|
|
|
|
|
|
1313
|
|
|
|
|
|
|
=head2 Video::CPL::checkready(local=>$file) |
1314
|
|
|
|
|
|
|
|
1315
|
|
|
|
|
|
|
This is a function, and not a method. Typically it is called before creating a CPL object |
1316
|
|
|
|
|
|
|
|
1317
|
|
|
|
|
|
|
=cut |
1318
|
|
|
|
|
|
|
|
1319
|
|
|
|
|
|
|
sub checkready { |
1320
|
0
|
|
|
0
|
1
|
|
my %p = @_; |
1321
|
0
|
|
|
|
|
|
my $SRC = "http://metabase.coincident.tv/cpan/player/"; |
1322
|
|
|
|
|
|
|
#if local, just get the player |
1323
|
|
|
|
|
|
|
#if dir, get everything into said directory |
1324
|
0
|
0
|
|
|
|
|
if ($p{local}){ |
|
|
0
|
|
|
|
|
|
1325
|
0
|
0
|
0
|
|
|
|
return 1 if -r $p{local} && (-s $p{local} > 200000); |
1326
|
0
|
0
|
|
|
|
|
return 1 if getfile("$SRC/CTVWebPlayerS.swf",$p{local},200000); |
1327
|
0
|
|
|
|
|
|
return 0; |
1328
|
|
|
|
|
|
|
} elsif ($p{dir}){ |
1329
|
0
|
|
|
|
|
|
my %files = ("CTVWebPlayerS.swf"=>400000, |
1330
|
|
|
|
|
|
|
"defaultSkin.html"=>100, |
1331
|
|
|
|
|
|
|
"index.html"=>2000, |
1332
|
|
|
|
|
|
|
"styles.css"=>500, |
1333
|
|
|
|
|
|
|
"preLoader/CTVPreLoader.swf"=>2000, |
1334
|
|
|
|
|
|
|
"scripts/CTVLayoutFunc.js"=>5000, |
1335
|
|
|
|
|
|
|
"scripts/expressInstall.swf"=>100, |
1336
|
|
|
|
|
|
|
"scripts/jquery-1.3.2.min.js"=>10000, |
1337
|
|
|
|
|
|
|
"scripts/swfobject.js"=>3000, |
1338
|
|
|
|
|
|
|
"ui/CTVCloseButton-over.png"=>100, |
1339
|
|
|
|
|
|
|
"ui/CTVCloseButton.png"=>100); |
1340
|
0
|
0
|
|
|
|
|
make_path($p{dir}) if !-d $p{dir}; |
1341
|
0
|
|
|
|
|
|
foreach my $x (keys %files){ |
1342
|
0
|
0
|
|
|
|
|
if ($x =~ /(.*)\//){ |
1343
|
0
|
|
|
|
|
|
my $prefix = $1; |
1344
|
0
|
0
|
|
|
|
|
make_path("$p{dir}/$prefix") if !-d "$p{dir}/$prefix"; |
1345
|
|
|
|
|
|
|
} |
1346
|
0
|
|
|
|
|
|
getfile("$SRC$x","$p{dir}/$x",$files{$x}); |
1347
|
|
|
|
|
|
|
} |
1348
|
|
|
|
|
|
|
} |
1349
|
|
|
|
|
|
|
} |
1350
|
|
|
|
|
|
|
|
1351
|
|
|
|
|
|
|
sub getfile { |
1352
|
0
|
|
|
0
|
0
|
|
my $url = shift; |
1353
|
0
|
|
|
|
|
|
my $file = shift; |
1354
|
0
|
|
|
|
|
|
my $minsize = shift; |
1355
|
0
|
|
|
|
|
|
my $fil = get($url); |
1356
|
0
|
0
|
|
|
|
|
if (length($fil) < $minsize){ |
1357
|
0
|
|
|
|
|
|
warn("Video::CPL checkready/getfile: tried to fetch ($file) from ($url) but it was shorter than expected ($minsize), failing.\n"); |
1358
|
0
|
|
|
|
|
|
return 0; |
1359
|
|
|
|
|
|
|
} |
1360
|
0
|
0
|
|
|
|
|
if (open(FSWF,">$file")){ |
1361
|
0
|
|
|
|
|
|
print FSWF $fil; |
1362
|
0
|
|
|
|
|
|
close FSWF; |
1363
|
0
|
|
|
|
|
|
my $actual = -s $file; |
1364
|
0
|
0
|
|
|
|
|
if ($actual != length($fil)){ |
1365
|
0
|
|
|
|
|
|
warn("Video::CPL checkready/getfile: fetched ($file) from ($url) of length ".length($fil)." but only wrote $actual bytes, failing.\n"); |
1366
|
0
|
|
|
|
|
|
return 0; |
1367
|
|
|
|
|
|
|
} |
1368
|
0
|
|
|
|
|
|
return 1; |
1369
|
|
|
|
|
|
|
} else { |
1370
|
0
|
|
|
|
|
|
warn("Video::CPL checkready/getfile: fetched from ($url), could not write to ($file), failing.\n"); |
1371
|
0
|
|
|
|
|
|
return 0; |
1372
|
|
|
|
|
|
|
} |
1373
|
|
|
|
|
|
|
} |
1374
|
|
|
|
|
|
|
|
1375
|
|
|
|
|
|
|
=head2 isyoutube($url) |
1376
|
|
|
|
|
|
|
|
1377
|
|
|
|
|
|
|
Return true if this URL appears to be a Youtube video. |
1378
|
|
|
|
|
|
|
|
1379
|
|
|
|
|
|
|
=cut |
1380
|
|
|
|
|
|
|
|
1381
|
|
|
|
|
|
|
sub isyoutube { |
1382
|
|
|
|
|
|
|
#utility routine, not an object method |
1383
|
0
|
|
|
0
|
1
|
|
my $x = shift; |
1384
|
0
|
0
|
|
|
|
|
return undef if $x !~ /http:\/\/www.youtube.com\/watch\?v=([A-Za-z0-9\-\_]{11})/; |
1385
|
0
|
|
|
|
|
|
my $code = $1; |
1386
|
0
|
|
|
|
|
|
return youtubefromcode($code); |
1387
|
|
|
|
|
|
|
} |
1388
|
|
|
|
|
|
|
|
1389
|
|
|
|
|
|
|
=head1 AUTHOR |
1390
|
|
|
|
|
|
|
|
1391
|
|
|
|
|
|
|
Carl Rosenberg, C<< >> |
1392
|
|
|
|
|
|
|
|
1393
|
|
|
|
|
|
|
=head1 BUGS |
1394
|
|
|
|
|
|
|
|
1395
|
|
|
|
|
|
|
Please report any bugs to Coincident TV. |
1396
|
|
|
|
|
|
|
|
1397
|
|
|
|
|
|
|
=head1 SUPPORT |
1398
|
|
|
|
|
|
|
|
1399
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
1400
|
|
|
|
|
|
|
|
1401
|
|
|
|
|
|
|
perldoc CPL |
1402
|
|
|
|
|
|
|
|
1403
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
1404
|
|
|
|
|
|
|
|
1405
|
|
|
|
|
|
|
This is actually just a straightforward interface to the work done by the rest of the Coincident team. |
1406
|
|
|
|
|
|
|
|
1407
|
|
|
|
|
|
|
=head1 LICENSE AND COPYRIGHT |
1408
|
|
|
|
|
|
|
|
1409
|
|
|
|
|
|
|
Copyright 2010 Coincident TV |
1410
|
|
|
|
|
|
|
|
1411
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License"); |
1412
|
|
|
|
|
|
|
you may not use this file except in compliance with the License. |
1413
|
|
|
|
|
|
|
You may obtain a copy of the License at |
1414
|
|
|
|
|
|
|
|
1415
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0 |
1416
|
|
|
|
|
|
|
|
1417
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software |
1418
|
|
|
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS, |
1419
|
|
|
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
1420
|
|
|
|
|
|
|
See the License for the specific language governing permissions and |
1421
|
|
|
|
|
|
|
limitations under the License. |
1422
|
|
|
|
|
|
|
|
1423
|
|
|
|
|
|
|
=cut |
1424
|
|
|
|
|
|
|
|
1425
|
|
|
|
|
|
|
1; # End of CPL |