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

Last change on this file since 7528 was 7528, checked in by davidb, 20 years ago

Plugin was setting title twice (derived from filename and extracted from
ID3 tags). Now set only once. Preference given to ID3 tag.

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 10.9 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' => "assoc_images",
43 'desc' => "{MP3Plug.assoc_images}",
44 'type' => "flag",
45 'deft' => "",
46 'reqd' => "no" },
47 { 'name' => "applet_metadata",
48 'desc' => "{MP3Plug.applet_metadata}",
49 'type' => "flag",
50 'deft' => "" },
51 { 'name' => "metadata_fields",
52 'desc' => "{MP3Plug.metadata_fields}",
53 'type' => "string",
54 'deft' => "Title,Artist,Genre" } ];
55
56my $options = { 'name' => "MP3Plug",
57 'desc' => "{MP3Plug.desc}",
58 'abstract' => "no",
59 'inherits' => "yes",
60 'args' => $arguments };
61
62sub new {
63 my ($class) = @_;
64 my $self = new UnknownPlug ($class, @_);
65 $self->{'plugin_type'} = "MP3Plug";
66 # 14-05-02 To allow for proper inheritance of arguments - John Thompson
67 my $option_list = $self->{'option_list'};
68 push( @{$option_list}, $options );
69
70 if (!parsargv::parse(\@_,
71 q^assoc_images^, \$self->{'assoc_images'},
72 q^applet_metadata^, \$self->{'applet_metadata'},
73 q^metadata_fields/.*/Title,Artist,Genre^, \$self->{'metadata_fields'},
74 "allow_extra_options")) {
75 print STDERR "\nIncorrect options passed to MP3Plug, check your collect.cfg configuration file\n";
76 $self->print_txt_usage(""); # Use default resource bundle
77 die "\n";
78 }
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_/jl020.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_/jl020.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 $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 if ($mp3_metaname eq "mp3:Title") {
189 $doc_obj->add_metadata ($section, "Title", $mp3_metavalue);
190 }
191 }
192 }
193 }
194 else {
195
196 # Restrict metadata to that specifically given
197 foreach my $field (split /,/, $metadata_fields) {
198
199 # check info
200 if (defined $mp3_info->{$field}) {
201
202 my $mp3i_metavalue = $mp3_info->{$field};
203
204 if ($mp3i_metavalue !~ m/^\s*$/s) {
205 my $mp3i_metaname = "mp3:".lc($field);
206 $doc_obj->add_metadata ($section, $mp3i_metaname, $mp3i_metavalue);
207 }
208 }
209
210 # check tags
211 if (defined $mp3_tags->{uc($field)}) {
212
213 my $mp3t_metavalue = $mp3_tags->{uc($field)};
214
215 if ($mp3t_metavalue !~ m/^\s*$/s) {
216 my $mp3t_metaname = "mp3:".$field;
217
218 $doc_obj->add_metadata ($section, $mp3t_metaname, $mp3t_metavalue);
219 if ($mp3t_metaname eq "mp3:Title") {
220 $doc_obj->add_metadata ($section, "Title", $mp3t_metavalue);
221 }
222 }
223 }
224
225 }
226 }
227
228 $self->title_fallback($doc_obj,$section,$file);
229 $doc_obj->add_metadata ($section, "FileFormat", "MP3");
230
231 $doc_obj->add_metadata ($section, "srclink",
232 "<a href=_httpcollection_/index/assoc/[assocfilepath]/[srcurl]>");
233 $doc_obj->add_metadata ($section, "srcicon", "<img src=_httpimg_/mp3icon.gif>");
234 $doc_obj->add_metadata ($section, "/srclink", "</a>");
235
236 my $applet_metadata = $self->{'applet_metadata'};
237 if (defined $applet_metadata && $applet_metadata ) {
238 my $applet_html
239 = gen_mp3applet("_httpcollection_/index/assoc/[assocfilepath]/[srcurl]");
240 $doc_obj->add_metadata ($section, "mp3applet", $applet_html);
241 }
242
243 my $assoc_images = $self->{'assoc_images'};
244 if (defined $assoc_images && $assoc_images) {
245 my @search_terms = ();
246
247 my $title = $mp3_tags->{'TITLE'};
248 my $artist = $mp3_tags->{'ARTIST'};
249
250 if (defined $title && $title ne "") {
251
252
253 push(@search_terms,$title);
254
255 if (defined $artist && $artist ne "") {
256 push(@search_terms,$artist);
257 }
258 }
259 else {
260 push(@search_terms,$assoc_name);
261 }
262
263 my $output_dir = $filename;
264 $output_dir =~ s/\.\w+$//;
265
266 my ($imgref_urls) = giget(\@search_terms,$output_dir);
267
268 my $gi_base = gi_url_base();
269 my $gi_query_url = gi_query_url(\@search_terms);
270
271 $doc_obj->add_metadata ($section, "giquery", "<a href=$gi_base$gi_query_url target=giwindow>");
272 $doc_obj->add_metadata ($section, "/giquery", "</a>");
273
274 for (my $i=1; $i<=2; $i++) {
275 my $img_filename = "$output_dir/img_$i.jpg";
276 my $dst_file = "img_$i.jpg";
277
278 if (-e $img_filename) {
279 $doc_obj->associate_file($img_filename, $dst_file, "image/jpeg", $section);
280
281 my $srcurl = "src=\"_httpcollection_/index/assoc/[assocfilepath]/$dst_file\"";
282
283 $doc_obj->add_metadata ($section, "img$i",
284 "<img $srcurl>");
285 $doc_obj->add_metadata ($section, "smallimg$i",
286 "<img $srcurl width=100>");
287
288 my $imgref_url = $imgref_urls->[$i-1];
289
290 $doc_obj->add_metadata ($section, "imgref$i", "<a href=$imgref_url target=giwindow>");
291 $doc_obj->add_metadata ($section, "/imgref$i", "</a>");
292 }
293
294 }
295
296
297 }
298
299 return 1;
300}
301
302
303
304# The MP3Plug read() function is based on UnknownPlug read(). This
305# function does all the right things to make general options work for
306# a given plugin.
307
308my $mp3_doc_count = 0; ## is this used anywhere now !!???
309
310sub read {
311 my $self = shift (@_);
312 my ($pluginfo, $base_dir, $file, $metadata, $processor, $maxdocs, $gli) = @_;
313
314 my $outhandle = $self->{'outhandle'};
315
316 # Make sure we're processing the correct file
317 my $filename = &util::filename_cat($base_dir, $file);
318 return 0 if $self->{'block_exp'} ne "" && $filename =~ /$self->{'block_exp'}/;
319 if ($filename !~ /$self->{'process_exp'}/ || !-f $filename) {
320 return undef;
321 }
322 print STDERR "<Processing n='$file' p='MP3Plug'>\n" if ($gli);
323 print $outhandle "MP3Plug processing \"$filename\"\n"
324 if $self->{'verbosity'} > 1;
325
326 #if there's a leading directory name, eat it...
327 $file =~ s/^.*[\/\\]//;
328
329 # create a new document
330 my $doc_obj = new doc ($filename, "indexed_doc");
331 $mp3_doc_count++;
332
333## $doc_obj->set_OIDtype ($processor->{'OIDtype'});
334 $doc_obj->set_OIDtype ("incremental"); # this is done to avoid hashing content of file
335 $doc_obj->add_utf8_metadata($doc_obj->get_top_section(), "Plugin", "$self->{'plugin_type'}");
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 # do plugin specific processing of doc_obj
354 return undef unless defined ($self->process (\$text, $pluginfo, $base_dir,
355 $file, $metadata, $doc_obj));
356
357 # do any automatic metadata extraction
358 $self->auto_extract_metadata ($doc_obj);
359
360 # add an OID
361 $doc_obj->set_OID();
362 $doc_obj->add_text($section, $text);
363
364 # process the document
365 $processor->process($doc_obj);
366
367 $self->{'num_processed'} ++;
368 return 1;
369}
370
371
372
3731;
374
375
376
377
378
379
380
381
382
383
384
Note: See TracBrowser for help on using the repository browser.