source: main/trunk/greenstone2/perllib/plugins/MP3Plugin.pm@ 21760

Last change on this file since 21760 was 21760, checked in by kjdon, 14 years ago

srclink now generated dynamically at runtime. instead of storing srclink metadata, we store srclink_file metadata, which can be a value (doc.doc) or a metadata format element (eg [SourceFile]).

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 10.6 KB
Line 
1###########################################################################
2#
3# MP3Plugin.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 MP3Plugin;
29
30use BasePlugin;
31
32use strict;
33no strict 'refs'; # allow filehandles to be variables and viceversa
34no strict 'subs';
35
36use MP3::Info;
37
38require giget;
39
40sub BEGIN {
41 @MP3Plugin::ISA = ('BasePlugin');
42}
43
44my $arguments =
45 [ { 'name' => "process_exp",
46 'desc' => "{BasePlugin.process_exp}",
47 'type' => "regexp",
48 'deft' => &get_default_process_exp(),
49 'reqd' => "no" },
50 { 'name' => "assoc_images",
51 'desc' => "{MP3Plugin.assoc_images}",
52 'type' => "flag",
53 'deft' => "",
54 'reqd' => "no" },
55 { 'name' => "applet_metadata",
56 'desc' => "{MP3Plugin.applet_metadata}",
57 'type' => "flag",
58 'deft' => "" },
59 { 'name' => "metadata_fields",
60 'desc' => "{MP3Plugin.metadata_fields}",
61 'type' => "string",
62 'deft' => "Title,Artist,Genre" },
63 { 'name' => "file_rename_method",
64 'desc' => "{BasePlugin.file_rename_method}",
65 'type' => "enum",
66 'deft' => &get_default_file_rename_method(), # by default rename imported files and assoc files using this encoding
67 'list' => $BasePlugin::file_rename_method_list,
68 'reqd' => "no"
69 } ];
70
71my $options = { 'name' => "MP3Plugin",
72 'desc' => "{MP3Plugin.desc}",
73 'abstract' => "no",
74 'inherits' => "yes",
75 'args' => $arguments };
76
77sub new {
78 my ($class) = shift (@_);
79 my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
80 push(@$pluginlist, $class);
81
82 push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
83 push(@{$hashArgOptLists->{"OptList"}},$options);
84
85 my $self = new BasePlugin($pluginlist, $inputargs, $hashArgOptLists);
86
87 return bless $self, $class;
88}
89
90sub get_default_process_exp {
91 return q^(?i)\.mp3$^;
92}
93
94# rename imported files and assoc files using base64 encoding by default
95# so that the urls generated will always work with media files even when
96# opened in external applications (when wmv file names contain spaces in
97# them and they get url-encoded, wmv player fails to open the doubly url-
98# encoded url reference to the url-encoded filename).
99sub get_default_file_rename_method() {
100 return "base64";
101}
102
103# we don't want to hash on the file
104sub get_oid_hash_type {
105 my $self = shift (@_);
106 return "hash_on_ga_xml";
107}
108
109sub process {
110 my $self = shift (@_);
111 my ($pluginfo, $base_dir, $file, $metadata, $doc_obj, $gli) = @_;
112
113 my ($filename_full_path, $filename_no_path) = &util::get_full_filenames($base_dir, $file);
114
115 # associate the file with the document
116 if ($self->associate_mp3_file($filename_full_path, $filename_no_path, $doc_obj) != 1)
117 {
118 print "MP3Plugin: couldn't process \"$filename_full_path\"\n";
119 return 0;
120 }
121
122 my $text = &gsprintf::lookup_string("{BasePlugin.dummy_text}",1);
123 if ($self->{'assoc_images'}) {
124 $text .= "[img1]<br>";
125 $text .= "[img2]<br>";
126 }
127 $doc_obj->add_utf8_text($doc_obj->get_top_section(), $text);
128 $doc_obj->add_metadata ($doc_obj->get_top_section(), "NoText", "1");
129
130}
131
132sub gen_mp3applet {
133
134 my ($mp3_filename) = @_;
135
136 my $applet_html = '
137<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
138 WIDTH = "59"
139 HEIGHT = "32"
140 codebase="http://java.sun.com/products/plugin/1.3/jinstall-13-win32.cab#Version=1,3,0,0">
141<PARAM NAME = CODE VALUE = "javazoom.jlGui.TinyPlayer" >
142<PARAM NAME = ARCHIVE VALUE = "_httpcollection_/tinyplayer.jar,_httpcollection_/jl10.jar" >
143<PARAM NAME="type" VALUE="application/x-java-applet;version=1.3">
144<PARAM NAME="scriptable" VALUE="false">
145<PARAM NAME = "skin" VALUE ="_httpcollection_/skins/Digitalized">
146<PARAM NAME = "autoplay" VALUE ="yes">
147<PARAM NAME = "bgcolor" VALUE ="638182">
148<PARAM NAME = "audioURL" VALUE ="MP3FILENAME">
149<COMMENT>
150<EMBED type="application/x-java-applet;version=1.3"
151 CODE = "javazoom.jlGui.TinyPlayer"
152 ARCHIVE = "_httpcollection_/tinyplayer.jar,_httpcollection_/jl10.jar"
153 WIDTH = "59"
154 HEIGHT = "32"
155 skin = "_httpcollection_/skins/Digitalized"
156 autoplay = "yes"
157 bgcolor = "638182"
158 audioURL = "MP3FILENAME"
159 scriptable=false
160 pluginspage="http://java.sun.com/products/plugin/1.3/plugin-install.html">
161<NOEMBED>
162</COMMENT>
163</NOEMBED></EMBED>
164</OBJECT>
165';
166
167 $applet_html =~ s/MP3FILENAME/$mp3_filename/g;
168
169 return $applet_html;
170}
171
172
173
174# Associate the mp3 file with the new document
175
176sub associate_mp3_file {
177 my $self = shift (@_);
178 my $filename = shift (@_); # filename with full path
179 my $file = shift (@_); # filename without path
180 my $doc_obj = shift (@_);
181
182 my $verbosity = $self->{'verbosity'};
183 my $outhandle = $self->{'outhandle'};
184
185 # check the filename is okay
186 return 0 if ($file eq "" || $filename eq "");
187
188 # Add the file metadata.
189 # $assoc_url will be the srcurl. Since it is URL encoded here, it will be
190 # able to cope with special characters--including spaces--in mp3 filenames.
191 # the assocfilename generated will be a URL encoded version of the utf8 filename
192 my $assoc_url = $doc_obj->get_sourcefile();
193 my $dst_file = $doc_obj->get_assocfile_from_sourcefile();
194
195 # Add the file as an associated file ...
196 my $section = $doc_obj->get_top_section();
197 my $mime_type = $self->{'mime_type'} || "audio/mp3";
198 my $assoc_field = $self->{'assoc_field'} || "mp3";
199 my $assoc_name = $file;
200 $assoc_name =~ s/\.mp3$//;
201
202 $doc_obj->associate_file($filename, $dst_file, $mime_type, $section);
203 $doc_obj->add_metadata ($section, $assoc_field, $assoc_name);
204 $doc_obj->add_metadata ($section, "srcurl", $assoc_url);
205
206 my $mp3_info = get_mp3info($filename);
207 my $mp3_tags = get_mp3tag($filename);
208
209 my $metadata_fields = $self->{'metadata_fields'};
210
211 if ($metadata_fields eq "*") {
212 # Locate all info and tag metadata
213
214 foreach my $ki ( keys %$mp3_info ) {
215 my $mp3_metavalue = $mp3_info->{$ki};
216
217 if ($mp3_metavalue !~ m/^\s*$/s) {
218 my $mp3_metaname = "mp3:".lc($ki);
219 $doc_obj->add_metadata ($section, $mp3_metaname, $mp3_metavalue);
220 }
221 }
222
223 foreach my $kt ( keys %$mp3_tags ) {
224 my $mp3_metavalue = $mp3_tags->{$kt};
225
226 if ($mp3_metavalue !~ m/^\s*$/s) {
227 my $kt_len = length($kt);
228 my $kt_initial_cap = uc(substr($kt,0,1)).lc(substr($kt,1,$kt_len-1));
229 my $mp3_metaname = "mp3:".$kt_initial_cap;
230
231 $doc_obj->add_metadata ($section, $mp3_metaname, $mp3_metavalue);
232 }
233 }
234 }
235 else {
236
237 # Restrict metadata to that specifically given
238 foreach my $field (split /,/, $metadata_fields) {
239
240 # check info
241 if (defined $mp3_info->{$field}) {
242
243 my $mp3i_metavalue = $mp3_info->{$field};
244
245 if ($mp3i_metavalue !~ m/^\s*$/s) {
246 my $mp3i_metaname = "mp3:".lc($field);
247 $doc_obj->add_metadata ($section, $mp3i_metaname, $mp3i_metavalue);
248 }
249 }
250
251 # check tags
252 if (defined $mp3_tags->{uc($field)}) {
253
254 my $mp3t_metavalue = $mp3_tags->{uc($field)};
255
256 if ($mp3t_metavalue !~ m/^\s*$/s) {
257 my $mp3t_metaname = "mp3:".$field;
258
259 $doc_obj->add_metadata ($section, $mp3t_metaname, $mp3t_metavalue);
260 }
261 }
262
263 }
264 }
265
266 $doc_obj->add_metadata ($section, "FileFormat", "MP3");
267
268 #$doc_obj->add_metadata ($section, "srclink",
269# "<a href=\"_httpprefix_/collect/[collection]/index/assoc/[assocfilepath]/[srcurl]\">");
270 $doc_obj->add_metadata ($section, "srcicon", "_iconmp3_");
271 #$doc_obj->add_metadata ($section, "/srclink", "</a>");
272 $doc_obj->add_metadata ($section, "srclink_file", "[srcurl]");
273 my $applet_metadata = $self->{'applet_metadata'};
274 if (defined $applet_metadata && $applet_metadata ) {
275 my $applet_html
276 = gen_mp3applet("_httpprefix_/collect/[collection]/index/assoc/[assocfilepath]/[srcurl]");
277 $doc_obj->add_metadata ($section, "mp3applet", $applet_html);
278 }
279
280 my $assoc_images = $self->{'assoc_images'};
281 if (defined $assoc_images && $assoc_images) {
282 my @search_terms = ();
283
284 my $title = $mp3_tags->{'TITLE'};
285 my $artist = $mp3_tags->{'ARTIST'};
286
287 if (defined $title && $title ne "") {
288
289 push(@search_terms,$title);
290
291 if (defined $artist && $artist ne "") {
292 push(@search_terms,$artist);
293 }
294 }
295 else {
296 push(@search_terms,$assoc_name);
297 }
298
299 push(@search_terms,"song");
300
301 my $output_dir = $filename;
302 $output_dir =~ s/\.\w+$//;
303
304 my ($imgref_urls) = giget(\@search_terms,$output_dir);
305
306 my $gi_base = gi_url_base();
307 my $gi_query_url = gi_query_url(\@search_terms);
308
309 $doc_obj->add_metadata ($section, "giquery", "<a href=\"$gi_base$gi_query_url\" target=giwindow>");
310 $doc_obj->add_metadata ($section, "/giquery", "</a>");
311
312 for (my $i=1; $i<=2; $i++) {
313 my $img_filename = "$output_dir/img_$i.jpg";
314 my $dst_file = "img_$i.jpg";
315
316 if (-e $img_filename) {
317 $doc_obj->associate_file($img_filename, $dst_file, "image/jpeg", $section);
318
319 my $srcurl = "src=\"_httpprefix_/collect/[collection]/index/assoc/[assocfilepath]/$dst_file\"";
320
321 $doc_obj->add_metadata ($section, "img$i",
322 "<img $srcurl>");
323 $doc_obj->add_metadata ($section, "smallimg$i",
324 "<img $srcurl width=100>");
325
326 my $imgref_url = $imgref_urls->[$i-1];
327
328 $doc_obj->add_metadata ($section, "imgref$i", "<a href=\"$imgref_url\" target=giwindow>");
329 $doc_obj->add_metadata ($section, "/imgref$i", "</a>");
330 }
331
332 }
333
334
335 }
336
337 return 1;
338}
339
340
341# we want to use mp3:Title if its there, otherwise we'll use BasePlugin method
342sub title_fallback
343{
344 my $self = shift (@_);
345 my ($doc_obj,$section,$file) = @_;
346
347 if (!defined $doc_obj->get_metadata_element ($section, "Title")) {
348 my $mp3_title = $doc_obj->get_metadata_element ($section, "mp3:Title");
349 if (defined $mp3_title) {
350 $doc_obj->add_metadata ($section, "Title", $mp3_title);
351 }
352 else {
353 $self->BasePlugin::title_fallback($doc_obj, $section, $file);
354 }
355 }
356}
357
358
3591;
360
361
362
363
364
365
366
367
368
369
370
Note: See TracBrowser for help on using the repository browser.