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

Last change on this file was 31492, checked in by kjdon, 7 years ago

renamed EncodingUtil to CommonUtil, BasePlugin to BaseImporter. The idea is that only top level plugins that you can specify in your collection get to have plugin in their name. Modified all other plugins to reflect these name changes

  • 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 BaseImporter;
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 = ('BaseImporter');
42}
43
44my $arguments =
45 [ { 'name' => "process_exp",
46 'desc' => "{BaseImporter.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' => "{BaseImporter.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' => $BaseImporter::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 BaseImporter($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("{BaseImporter.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,0,2);
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 = "ex.id3.".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 = "ex.id3.".$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 = "ex.id3.".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 = "ex.id3.".$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, "srcicon", "_iconmp3_");
269 # srclink_file is now deprecated because of the "_" in the metadataname. Use srclinkFile
270 $doc_obj->add_metadata ($section, "srclink_file", $assoc_url);
271 $doc_obj->add_metadata ($section, "srclinkFile", $assoc_url);
272 my $applet_metadata = $self->{'applet_metadata'};
273 if (defined $applet_metadata && $applet_metadata ) {
274 my $applet_html
275 = gen_mp3applet("_httpprefix_/collect/[collection]/index/assoc/[assocfilepath]/[srcurl]");
276 $doc_obj->add_metadata ($section, "mp3applet", $applet_html);
277 }
278
279 my $assoc_images = $self->{'assoc_images'};
280 if (defined $assoc_images && $assoc_images) {
281 my @search_terms = ();
282
283 my $title = $mp3_tags->{'TITLE'};
284 my $artist = $mp3_tags->{'ARTIST'};
285
286 if (defined $title && $title ne "") {
287
288 push(@search_terms,$title);
289
290 if (defined $artist && $artist ne "") {
291 push(@search_terms,$artist);
292 }
293 }
294 else {
295 push(@search_terms,$assoc_name);
296 }
297
298 push(@search_terms,"song");
299
300 my $output_dir = $filename;
301 $output_dir =~ s/\.\w+$//;
302
303 my ($imgref_urls) = giget(\@search_terms,$output_dir);
304
305 my $gi_base = gi_url_base();
306 my $gi_query_url = gi_query_url(\@search_terms);
307
308 $doc_obj->add_metadata ($section, "giquery", "<a href=\"$gi_base$gi_query_url\" target=giwindow>");
309 $doc_obj->add_metadata ($section, "/giquery", "</a>");
310
311 for (my $i=1; $i<=2; $i++) {
312 my $img_filename = "$output_dir/img_$i.jpg";
313 my $dst_file = "img_$i.jpg";
314
315 if (-e $img_filename) {
316 $doc_obj->associate_file($img_filename, $dst_file, "image/jpeg", $section);
317
318 my $srcurl = "src=\"_httpprefix_/collect/[collection]/index/assoc/[assocfilepath]/$dst_file\"";
319
320 $doc_obj->add_metadata ($section, "img$i",
321 "<img $srcurl>");
322 $doc_obj->add_metadata ($section, "smallimg$i",
323 "<img $srcurl width=100>");
324
325 my $imgref_url = $imgref_urls->[$i-1];
326
327 $doc_obj->add_metadata ($section, "imgref$i", "<a href=\"$imgref_url\" target=giwindow>");
328 $doc_obj->add_metadata ($section, "/imgref$i", "</a>");
329 }
330
331 }
332
333
334 }
335
336 return 1;
337}
338
339
340# we want to use ex.id3.Title if its there, otherwise we'll use BaseImporter method
341sub title_fallback
342{
343 my $self = shift (@_);
344 my ($doc_obj,$section,$file) = @_;
345
346 if (!defined $doc_obj->get_metadata_element ($section, "Title")) {
347 my $mp3_title = $doc_obj->get_metadata_element ($section, "ex.id3.Title");
348 if (defined $mp3_title) {
349 $doc_obj->add_metadata ($section, "Title", $mp3_title);
350 }
351 else {
352 $self->BaseImporter::title_fallback($doc_obj, $section, $file);
353 }
354 }
355}
356
357
3581;
359
360
361
362
363
364
365
366
367
368
369
Note: See TracBrowser for help on using the repository browser.