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

Last change on this file since 9962 was 9962, checked in by davidb, 19 years ago

MP3Plug updated to make use of newer version of MP3 applet player.

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