source: trunk/gsdl/perllib/plugins/MP3Plug.pm@ 10254

Last change on this file since 10254 was 10254, checked in by kjdon, 19 years ago

added 'use strict' to all plugins, and made modifications (mostly adding 'my') to make them compile

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 11.2 KB
Line 
1###########################################################################
2#
3# MP3Plug.pm -- Plugin for MP3 files (MPEG audio layer 3).
4#
5# A component of the Greenstone digital library software from the New
6# Zealand Digital Library Project at the University of Waikato, New
7# Zealand.
8#
9# Copyright (C) 2001 New Zealand Digital Library Project
10#
11# This program is free software; you can redistribute it and/or modify
12# it under the terms of the GNU General Public License as published by
13# the Free Software Foundation; either version 2 of the License, or
14# (at your option) any later version.
15#
16# This program is distributed in the hope that it will be useful, but
17# WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19# General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License
22# along with this program; if not, write to the Free Software
23# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24#
25###########################################################################
26
27
28package MP3Plug;
29
30use UnknownPlug;
31use parsargv;
32
33use strict;
34no strict 'refs'; # allow filehandles to be variables and viceversa
35
36use MP3::Info;
37
38require giget;
39
40sub BEGIN {
41 @MP3Plug::ISA = ('UnknownPlug');
42}
43
44my $arguments =
45 [ { 'name' => "process_exp",
46 'desc' => "{BasPlug.process_exp}",
47 'type' => "string",
48 'deft' => &get_default_process_exp(),
49 'reqd' => "no" },
50 { 'name' => "assoc_images",
51 'desc' => "{MP3Plug.assoc_images}",
52 'type' => "flag",
53 'deft' => "",
54 'reqd' => "no" },
55 { 'name' => "applet_metadata",
56 'desc' => "{MP3Plug.applet_metadata}",
57 'type' => "flag",
58 'deft' => "" },
59 { 'name' => "metadata_fields",
60 'desc' => "{MP3Plug.metadata_fields}",
61 'type' => "string",
62 'deft' => "Title,Artist,Genre" } ];
63
64my $options = { 'name' => "MP3Plug",
65 'desc' => "{MP3Plug.desc}",
66 'abstract' => "no",
67 'inherits' => "yes",
68 'args' => $arguments };
69
70sub new {
71 my ($class) = shift (@_);
72 my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
73 push(@$pluginlist, $class);
74
75 if(defined $arguments){ push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});}
76 if(defined $options) { push(@{$hashArgOptLists->{"OptList"}},$options)};
77
78 my $self = (defined $hashArgOptLists)? new UnknownPlug($pluginlist,$inputargs,$hashArgOptLists): new UnknownPlug($pluginlist,$inputargs);
79
80 return bless $self, $class;
81}
82
83sub get_default_process_exp {
84 return q^(?i)\.mp3$^;
85}
86
87sub gen_mp3applet {
88
89 my ($mp3_filename) = @_;
90
91 my $applet_html = '
92<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
93 WIDTH = "59"
94 HEIGHT = "32"
95 codebase="http://java.sun.com/products/plugin/1.3/jinstall-13-win32.cab#Version=1,3,0,0">
96<PARAM NAME = CODE VALUE = "javazoom.jlGui.TinyPlayer" >
97<PARAM NAME = ARCHIVE VALUE = "_httpcollection_/tinyplayer.jar,_httpcollection_/jl10.jar" >
98<PARAM NAME="type" VALUE="application/x-java-applet;version=1.3">
99<PARAM NAME="scriptable" VALUE="false">
100<PARAM NAME = "skin" VALUE ="_httpcollection_/skins/Digitalized">
101<PARAM NAME = "autoplay" VALUE ="yes">
102<PARAM NAME = "bgcolor" VALUE ="638182">
103<PARAM NAME = "audioURL" VALUE ="MP3FILENAME">
104<COMMENT>
105<EMBED type="application/x-java-applet;version=1.3"
106 CODE = "javazoom.jlGui.TinyPlayer"
107 ARCHIVE = "_httpcollection_/tinyplayer.jar,_httpcollection_/jl10.jar"
108 WIDTH = "59"
109 HEIGHT = "32"
110 skin = "_httpcollection_/skins/Digitalized"
111 autoplay = "yes"
112 bgcolor = "638182"
113 audioURL = "MP3FILENAME"
114 scriptable=false
115 pluginspage="http://java.sun.com/products/plugin/1.3/plugin-install.html">
116<NOEMBED>
117</COMMENT>
118</NOEMBED></EMBED>
119</OBJECT>
120';
121
122 $applet_html =~ s/MP3FILENAME/$mp3_filename/g;
123
124 return $applet_html;
125}
126
127
128
129# Associate the mp3 file with the new document
130
131sub associate_mp3_file {
132 my $self = shift (@_);
133 my $filename = shift (@_); # filename with full path
134 my $file = shift (@_); # filename without path
135 my $doc_obj = shift (@_);
136
137 my $verbosity = $self->{'verbosity'};
138 my $outhandle = $self->{'outhandle'};
139
140 # check the filename is okay
141 return 0 if ($file eq "" || $filename eq "");
142
143 # Add the file metadata
144 my $assoc_url = $file;
145# $assoc_url =~ s/ /%20/g; # probably need to do more escaping than this!!
146 $assoc_url =~ s/ /_/g; # workaround for now
147 my $dst_file = $file;
148 $dst_file =~ s/ /_/g;
149
150 # Add the file as an associated file ...
151 my $section = $doc_obj->get_top_section();
152 my $mime_type = $self->{'mime_type'} || "audio/mp3";
153 my $assoc_field = $self->{'assoc_field'} || "mp3";
154 my $assoc_name = $file;
155 $assoc_name =~ s/\.mp3$//;
156
157 $doc_obj->associate_file($filename, $dst_file, $mime_type, $section);
158 $doc_obj->add_metadata ($section, "Source", $file);
159 $doc_obj->add_metadata ($section, $assoc_field, $assoc_name);
160 $doc_obj->add_metadata ($section, "srcurl", $assoc_url);
161
162 my $mp3_info = get_mp3info($filename);
163 my $mp3_tags = get_mp3tag($filename);
164
165 my $metadata_fields = $self->{'metadata_fields'};
166
167 if ($metadata_fields eq "*") {
168 # Locate all info and tag metadata
169
170 foreach my $ki ( keys %$mp3_info ) {
171 my $mp3_metavalue = $mp3_info->{$ki};
172
173 if ($mp3_metavalue !~ m/^\s*$/s) {
174 my $mp3_metaname = "mp3:".lc($ki);
175 $doc_obj->add_metadata ($section, $mp3_metaname, $mp3_metavalue);
176 }
177 }
178
179 foreach my $kt ( keys %$mp3_tags ) {
180 my $mp3_metavalue = $mp3_tags->{$kt};
181
182 if ($mp3_metavalue !~ m/^\s*$/s) {
183 my $kt_len = length($kt);
184 my $kt_initial_cap = uc(substr($kt,0,1)).lc(substr($kt,1,$kt_len-1));
185 my $mp3_metaname = "mp3:".$kt_initial_cap;
186
187 $doc_obj->add_metadata ($section, $mp3_metaname, $mp3_metavalue);
188 }
189 }
190 }
191 else {
192
193 # Restrict metadata to that specifically given
194 foreach my $field (split /,/, $metadata_fields) {
195
196 # check info
197 if (defined $mp3_info->{$field}) {
198
199 my $mp3i_metavalue = $mp3_info->{$field};
200
201 if ($mp3i_metavalue !~ m/^\s*$/s) {
202 my $mp3i_metaname = "mp3:".lc($field);
203 $doc_obj->add_metadata ($section, $mp3i_metaname, $mp3i_metavalue);
204 }
205 }
206
207 # check tags
208 if (defined $mp3_tags->{uc($field)}) {
209
210 my $mp3t_metavalue = $mp3_tags->{uc($field)};
211
212 if ($mp3t_metavalue !~ m/^\s*$/s) {
213 my $mp3t_metaname = "mp3:".$field;
214
215 $doc_obj->add_metadata ($section, $mp3t_metaname, $mp3t_metavalue);
216 }
217 }
218
219 }
220 }
221
222 $doc_obj->add_metadata ($section, "FileFormat", "MP3");
223
224 $doc_obj->add_metadata ($section, "srclink",
225 "<a href=\"_httpcollection_/index/assoc/[assocfilepath]/[srcurl]\">");
226 $doc_obj->add_metadata ($section, "srcicon", "<img src=\"_httpimg_/mp3icon.gif\">");
227 $doc_obj->add_metadata ($section, "/srclink", "</a>");
228
229 my $applet_metadata = $self->{'applet_metadata'};
230 if (defined $applet_metadata && $applet_metadata ) {
231 my $applet_html
232 = gen_mp3applet("_httpcollection_/index/assoc/[assocfilepath]/[srcurl]");
233 $doc_obj->add_metadata ($section, "mp3applet", $applet_html);
234 }
235
236 my $assoc_images = $self->{'assoc_images'};
237 if (defined $assoc_images && $assoc_images) {
238 my @search_terms = ();
239
240 my $title = $mp3_tags->{'TITLE'};
241 my $artist = $mp3_tags->{'ARTIST'};
242
243 if (defined $title && $title ne "") {
244
245 push(@search_terms,$title);
246
247 if (defined $artist && $artist ne "") {
248 push(@search_terms,$artist);
249 }
250 }
251 else {
252 push(@search_terms,$assoc_name);
253 }
254
255 push(@search_terms,"song");
256
257 my $output_dir = $filename;
258 $output_dir =~ s/\.\w+$//;
259
260 my ($imgref_urls) = giget(\@search_terms,$output_dir);
261
262 my $gi_base = gi_url_base();
263 my $gi_query_url = gi_query_url(\@search_terms);
264
265 $doc_obj->add_metadata ($section, "giquery", "<a href=\"$gi_base$gi_query_url\" target=giwindow>");
266 $doc_obj->add_metadata ($section, "/giquery", "</a>");
267
268 for (my $i=1; $i<=2; $i++) {
269 my $img_filename = "$output_dir/img_$i.jpg";
270 my $dst_file = "img_$i.jpg";
271
272 if (-e $img_filename) {
273 $doc_obj->associate_file($img_filename, $dst_file, "image/jpeg", $section);
274
275 my $srcurl = "src=\"_httpcollection_/index/assoc/[assocfilepath]/$dst_file\"";
276
277 $doc_obj->add_metadata ($section, "img$i",
278 "<img $srcurl>");
279 $doc_obj->add_metadata ($section, "smallimg$i",
280 "<img $srcurl width=100>");
281
282 my $imgref_url = $imgref_urls->[$i-1];
283
284 $doc_obj->add_metadata ($section, "imgref$i", "<a href=\"$imgref_url\" target=giwindow>");
285 $doc_obj->add_metadata ($section, "/imgref$i", "</a>");
286 }
287
288 }
289
290
291 }
292
293 return 1;
294}
295
296
297
298# The MP3Plug read() function is based on UnknownPlug read(). This
299# function does all the right things to make general options work for
300# a given plugin.
301
302my $mp3_doc_count = 0; ## is this used anywhere now !!???
303
304sub read {
305 my $self = shift (@_);
306 my ($pluginfo, $base_dir, $file, $metadata, $processor, $maxdocs, $total_count, $gli) = @_;
307
308 my $outhandle = $self->{'outhandle'};
309
310 # Make sure we're processing the correct file
311 my $filename = &util::filename_cat($base_dir, $file);
312 return 0 if $self->{'block_exp'} ne "" && $filename =~ /$self->{'block_exp'}/;
313 if ($filename !~ /$self->{'process_exp'}/ || !-f $filename) {
314 return undef;
315 }
316 print STDERR "<Processing n='$file' p='MP3Plug'>\n" if ($gli);
317 print $outhandle "MP3Plug processing \"$filename\"\n"
318 if $self->{'verbosity'} > 1;
319
320 #if there's a leading directory name, eat it...
321 $file =~ s/^.*[\/\\]//;
322
323 # create a new document
324 my $doc_obj = new doc ($filename, "indexed_doc");
325 $mp3_doc_count++;
326
327## $doc_obj->set_OIDtype ($processor->{'OIDtype'});
328 $doc_obj->set_OIDtype ("incremental"); # this is done to avoid hashing content of file
329 $doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "Plugin", "$self->{'plugin_type'}");
330 $doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "FileSize", (-s $filename));
331
332 # associate the file with the document
333 if (associate_mp3_file($self, $filename, $file, $doc_obj) != 1)
334 {
335 print "MP3Plug: couldn't process \"$filename\"\n";
336 return 0;
337 }
338
339 #create an empty text string so we don't break downstream plugins
340 my $text = &gsprintf::lookup_string("{BasPlug.dummy_text}");
341 $text .= "[img1]<br>";
342 $text .= "[img2]<br>";
343
344 # include any metadata passed in from previous plugins
345 my $section = $doc_obj->get_top_section();
346 $self->extra_metadata ($doc_obj, $section, $metadata);
347
348 $self->title_fallback($doc_obj,$section,$file);
349
350 # do plugin specific processing of doc_obj
351 return undef unless defined ($self->process (\$text, $pluginfo, $base_dir,
352 $file, $metadata, $doc_obj));
353
354 # do any automatic metadata extraction
355 $self->auto_extract_metadata ($doc_obj);
356
357 # add an OID
358 $doc_obj->set_OID();
359 $doc_obj->add_text($section, $text);
360
361 # process the document
362 $processor->process($doc_obj);
363
364 $self->{'num_processed'} ++;
365 return 1;
366}
367
368
369sub title_fallback
370{
371 my $self = shift (@_);
372 my ($doc_obj,$section,$file) = @_;
373
374 if (!defined $doc_obj->get_metadata_element ($section, "Title")) {
375 my $mp3_title = $doc_obj->get_metadata_element ($section, "mp3:Title");
376 if (defined $mp3_title) {
377 $doc_obj->add_metadata ($section, "Title", $mp3_title);
378 }
379 else {
380 &BasPlug::title_fallback($self, $doc_obj, $section, $file);
381 }
382 }
383}
384
385
3861;
387
388
389
390
391
392
393
394
395
396
397
Note: See TracBrowser for help on using the repository browser.