source: extensions/gsdl-video/trunk/perllib/plugins/MultimediaConverter.pm@ 18556

Last change on this file since 18556 was 18556, checked in by davidb, 15 years ago

Restructing of VideoPlugin to be like ImagePlugin (with its supporting ImageConverter plugin). The pattern was then repeated for Audio, so we now have an AudioPlugin and AudioConverter. Where possible code is shared in a Multimedia base class

File size: 6.7 KB
Line 
1###########################################################################
2#
3# MultimediaConverter - helper plugin that does audio and video conversion using ffmpeg
4#
5# A component of the Greenstone digital library software
6# from the New Zealand Digital Library Project at the
7# University of Waikato, New Zealand.
8#
9# Copyright (C) 2008 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,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU 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###########################################################################
26package MultimediaConverter;
27
28use BaseMediaConverter;
29
30
31use strict;
32no strict 'refs'; # allow filehandles to be variables and viceversa
33
34use gsprintf 'gsprintf';
35
36BEGIN {
37 @MultimediaConverter::ISA = ('BaseMediaConverter');
38}
39
40my $arguments = [
41 { 'name' => "converttotype",
42 'desc' => "{ImageConverter.converttotype}",
43 'type' => "string",
44 'deft' => "",
45 'reqd' => "no" },
46 { 'name' => "minimumsize",
47 'desc' => "{ImageConverter.minimumsize}",
48 'type' => "int",
49 'deft' => "100",
50 'range' => "1,",
51 'reqd' => "no" },
52 ];
53
54my $options = { 'name' => "MultimediaConverter",
55 'desc' => "{MultimediaConverter.desc}",
56 'abstract' => "yes",
57 'inherits' => "yes",
58 'args' => $arguments };
59
60sub new {
61 my ($class) = shift (@_);
62 my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
63 push(@$pluginlist, $class);
64
65 push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
66 push(@{$hashArgOptLists->{"OptList"}},$options);
67
68 my $self = new BaseMediaConverter($pluginlist, $inputargs, $hashArgOptLists, 1);
69
70
71 return bless $self, $class;
72
73}
74
75
76
77# needs to be called after BasePlugin init, so that outhandle is set up.
78sub init {
79 my $self = shift(@_);
80
81 my $outhandle = $self->{'outhandle'};
82
83 $self->{'tmp_file_paths'} = ();
84
85 # Check that ffmpeg is installed and available on the path
86 my $multimedia_conversion_available = 1;
87 my $no_multimedia_conversion_reason = "";
88
89 # None of this works very well on Windows 95/98...
90 if ($ENV{'GSDLOS'} eq "windows" && !Win32::IsWinNT()) {
91 $multimedia_conversion_available = 0;
92 $no_multimedia_conversion_reason = "win95notsupported";
93 } else {
94
95 my $result = `ffmpeg -h 2>&1`;
96
97
98 if (!defined $result || $result !~ m/^FFmpeg version/) {
99 $self->{'ffmpeg_installed'} = 0;
100 print $outhandle $result;
101 $multimedia_conversion_available = 0;
102 $no_multimedia_conversion_reason = "ffmpegnotinstalled";
103 }
104 else {
105 $self->{'ffmpeg_installed'} = 1;
106 }
107 }
108
109 $self->{'multimedia_conversion_available'} = $multimedia_conversion_available;
110 $self->{'no_multimedia_conversion_reason'} = $no_multimedia_conversion_reason;
111
112 if ($self->{'multimedia_conversion_available'} == 0) {
113 &gsprintf($outhandle, "MultimediaConverter: {MultimediaConverter.noconversionavailable} ({MultimediaConverter.".$self->{'no_multimedia_conversion_reason'}."})\n");
114 }
115
116}
117
118
119
120
121sub identify {
122 my ($filename, $outhandle, $verbosity) = @_;
123
124 die "MultimediaConvert::identify() needs to be defined by inheriting plugin";
125}
126
127
128
129sub init_cache_for_file {
130 my $self = shift(@_);
131
132 my ($media_filename) = @_;
133
134 $self->SUPER::init_cache_for_file($media_filename);
135
136
137 # This should probably be replaced with Anu's work that replaced
138 # non-ASCII chars with URL encodings
139
140 my $ascii_only_filenames = $self->{'use_ascii_only_filenams'};
141
142 if (defined $ascii_only_filenames && ($ascii_only_filenames)) {
143 my $file_root = $self->{'cached_file_root'};
144 $self->{'cached_file_root'} = ascii_only_filename($file_root);
145 }
146
147 my @ffmpeg_monitor = ( 'monitor_init' , "MultimediaConverter::ffmpeg_monitor_init",
148 'monitor_line' , "MultimediaConverter::ffmpeg_monitor_line",
149 'monitor_deinit' , "MultimediaConverter::ffmpeg_monitor_deinit" );
150
151
152 $self->{'ffmpeg_monitor'} = \@ffmpeg_monitor;
153
154
155}
156
157
158
159
160sub ascii_only_filename
161{
162 my ($file) = @_;
163
164 my $file_unicode = pack("U0C*", map { ord($_) } split(//,$file)); # force explicitly to unicode
165
166 my @ascii_only_chars
167 = map { $_ >= 128 # if non-ascii
168 ? ""
169 : chr($_) } unpack("U*", $file_unicode); # unpack Unicode characters
170
171 my $ascii_file = join("",@ascii_only_chars);
172
173 if ($ascii_file eq "") {
174 print STDERR "Warning: filename includes no ASCII characters\n";
175 print STDERR " Keeping as original filename\n";
176 $ascii_file = $file;
177 }
178
179 return $ascii_file;
180}
181
182
183sub remove_difficult_chars
184{
185 my $self = shift @_;
186
187 my ($file) = @_;
188
189 # remove problematic characters from filename that make using it in a URL difficult
190
191 my $file_unicode = pack("U0C*", map { ord($_) } split(//,$file)); # force explicitly to unicode
192
193 my $url = $file_unicode;
194 $url =~ s/\x{2018}|\x{2019}|\x{201C}|\x{201D}//g; # remove smart quotes as cause problem in URL for streaming web server
195 $url =~ s/\x{2013}/\-/g; # change en-dash to '-' as again causes problems for streaming web server
196
197 return $url;
198}
199
200
201sub url_safe
202{
203 my $self = shift @_;
204
205 my ($file) = @_;
206
207 my @url_utf8_chars
208 = map { $_ >= 128 # if non-ascii
209 ? "%" . sprintf("%02X", $_)
210 : chr($_) } unpack("U*", $file); # unpack Unicode characters
211
212 my $url = join("",@url_utf8_chars);
213
214
215 return $url;
216}
217
218
219
220sub gsdlhome_independent
221{
222 my $self = shift @_;
223 my ($filename) = @_;
224
225 my $gsdlhome = $ENV{'GSDLHOME'};
226 my $filename_gsdlenv = $filename;
227 $filename_gsdlenv =~ s@^$gsdlhome@\$GSDLHOME@;
228
229 return $filename_gsdlenv;
230}
231
232
233sub ffmpeg_monitor_init
234{
235 my $saved_record_sep = $/;
236 $/ = "\r";
237
238 my $saved_buffer_len = $|;
239 $| = 1;
240
241 my $saved_rec = { 'saved_record_sep' => $saved_record_sep,
242 'saved_buffer_len' => $saved_buffer_len };
243
244 return $saved_rec;
245}
246
247
248
249sub ffmpeg_monitor_deinit
250{
251 my ($saved_rec) = @_;
252
253 my $saved_record_sep = $saved_rec->{'saved_record_sep'};
254 my $saved_buffer_len = $saved_rec->{'saved_buffer_len'};
255
256 $/ = $saved_record_sep;
257 $| = $saved_buffer_len;
258}
259
260
261sub ffmpeg_monitor_line
262{
263 my ($line) = @_;
264
265 my $had_error = 0;
266 my $generate_dot = 0;
267
268 if ($line =~ m/^frame=/)
269 {
270 $generate_dot = 1;
271 }
272
273 return ($had_error,$generate_dot);
274}
275
276
277
278
2791;
Note: See TracBrowser for help on using the repository browser.