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

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

Minor mods to VideoPlugin support for Windows

File size: 6.8 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 if (!defined $result || $result !~ m/^FFmpeg version/m) {
98 $self->{'ffmpeg_installed'} = 0;
99 print $outhandle $result;
100 $multimedia_conversion_available = 0;
101 $no_multimedia_conversion_reason = "ffmpegnotinstalled";
102 }
103 else {
104 $self->{'ffmpeg_installed'} = 1;
105 }
106 }
107
108 $self->{'multimedia_conversion_available'} = $multimedia_conversion_available;
109 $self->{'no_multimedia_conversion_reason'} = $no_multimedia_conversion_reason;
110
111 if ($self->{'multimedia_conversion_available'} == 0) {
112 &gsprintf($outhandle, "MultimediaConverter: {MultimediaConverter.noconversionavailable} ({MultimediaConverter.".$self->{'no_multimedia_conversion_reason'}."})\n");
113 }
114
115}
116
117
118
119
120sub identify {
121 my ($filename, $outhandle, $verbosity) = @_;
122
123 die "MultimediaConvert::identify() needs to be defined by inheriting plugin";
124}
125
126
127
128sub init_cache_for_file {
129 my $self = shift(@_);
130
131 my ($media_filename) = @_;
132
133 $self->SUPER::init_cache_for_file($media_filename);
134
135
136 # This should probably be replaced with Anu's work that replaced
137 # non-ASCII chars with URL encodings
138
139 my $ascii_only_filenames = $self->{'use_ascii_only_filenams'};
140
141 if (defined $ascii_only_filenames && ($ascii_only_filenames)) {
142 my $file_root = $self->{'cached_file_root'};
143 $self->{'cached_file_root'} = ascii_only_filename($file_root);
144 }
145
146 my @ffmpeg_monitor = ( 'monitor_init' , "MultimediaConverter::ffmpeg_monitor_init",
147 'monitor_line' , "MultimediaConverter::ffmpeg_monitor_line",
148 'monitor_deinit' , "MultimediaConverter::ffmpeg_monitor_deinit" );
149
150
151 $self->{'ffmpeg_monitor'} = \@ffmpeg_monitor;
152
153
154}
155
156
157
158
159sub ascii_only_filename
160{
161 my ($file) = @_;
162
163 my $file_unicode = pack("U0C*", map { ord($_) } split(//,$file)); # force explicitly to unicode
164
165 my @ascii_only_chars
166 = map { $_ >= 128 # if non-ascii
167 ? ""
168 : chr($_) } unpack("U*", $file_unicode); # unpack Unicode characters
169
170 my $ascii_file = join("",@ascii_only_chars);
171
172 if ($ascii_file eq "") {
173 print STDERR "Warning: filename includes no ASCII characters\n";
174 print STDERR " Keeping as original filename\n";
175 $ascii_file = $file;
176 }
177
178 return $ascii_file;
179}
180
181
182sub remove_difficult_chars
183{
184 my $self = shift @_;
185
186 my ($file) = @_;
187
188 # remove problematic characters from filename that make using it in a URL difficult
189
190 my $file_unicode = pack("U0C*", map { ord($_) } split(//,$file)); # force explicitly to unicode
191
192 my $url = $file_unicode;
193 $url =~ s/\x{2018}|\x{2019}|\x{201C}|\x{201D}//g; # remove smart quotes as cause problem in URL for streaming web server
194 $url =~ s/\x{2013}/\-/g; # change en-dash to '-' as again causes problems for streaming web server
195
196 return $url;
197}
198
199
200sub url_safe
201{
202 my $self = shift @_;
203
204 my ($file) = @_;
205
206 my @url_utf8_chars
207 = map { $_ >= 128 # if non-ascii
208 ? "%" . sprintf("%02X", $_)
209 : chr($_) } unpack("U*", $file); # unpack Unicode characters
210
211 my $url = join("",@url_utf8_chars);
212
213
214 return $url;
215}
216
217
218
219sub gsdlhome_independent
220{
221 my $self = shift @_;
222 my ($filename) = @_;
223
224 my $gsdlhome = $ENV{'GSDLHOME'};
225 $gsdlhome = &util::filename_to_regex($gsdlhome);
226
227 my $filename_gsdlenv = $filename;
228
229 if ($ENV{'GSDLOS'} =~ /^windows$/i) {
230 $filename_gsdlenv =~ s@^$gsdlhome@%GSDLHOME%@;
231 }
232 else {
233 $filename_gsdlenv =~ s@^$gsdlhome@\$GSDLHOME@;
234 }
235
236 return $filename_gsdlenv;
237}
238
239
240sub ffmpeg_monitor_init
241{
242 my $saved_record_sep = $/;
243 $/ = "\r";
244
245 my $saved_buffer_len = $|;
246 $| = 1;
247
248 my $saved_rec = { 'saved_record_sep' => $saved_record_sep,
249 'saved_buffer_len' => $saved_buffer_len };
250
251 return $saved_rec;
252}
253
254
255
256sub ffmpeg_monitor_deinit
257{
258 my ($saved_rec) = @_;
259
260 my $saved_record_sep = $saved_rec->{'saved_record_sep'};
261 my $saved_buffer_len = $saved_rec->{'saved_buffer_len'};
262
263 $/ = $saved_record_sep;
264 $| = $saved_buffer_len;
265}
266
267
268sub ffmpeg_monitor_line
269{
270 my ($line) = @_;
271
272 my $had_error = 0;
273 my $generate_dot = 0;
274
275 if ($line =~ m/^frame=/)
276 {
277 $generate_dot = 1;
278 }
279
280 return ($had_error,$generate_dot);
281}
282
283
284
285
2861;
Note: See TracBrowser for help on using the repository browser.