source: gs2-extensions/video-and-audio/trunk/src/perllib/plugins/MultimediaConverter.pm@ 26921

Last change on this file since 26921 was 26921, checked in by jmt12, 11 years ago

making ffmpeg detection tests a little more robust due to version changes

File size: 7.4 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 -version 2>&1`;
96
97 if (!defined $result || $result !~ m/^FFmpeg version/im) {
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::unbuffered_monitor_init",
147 'monitor_line' , "MultimediaConverter::ffmpeg_monitor_line",
148 'monitor_deinit' , "MultimediaConverter::unbuffered_monitor_deinit" );
149
150
151 $self->{'ffmpeg_monitor'} = \@ffmpeg_monitor;
152
153 my @handbrake_monitor = ( 'monitor_init' , "MultimediaConverter::unbuffered_monitor_init",
154 'monitor_line' , "MultimediaConverter::handbrake_monitor_line",
155 'monitor_deinit' , "MultimediaConverter::unbuffered_monitor_deinit" );
156
157
158 $self->{'handbrake_monitor'} = \@handbrake_monitor;
159
160}
161
162
163
164
165sub ascii_only_filename
166{
167 my ($file) = @_;
168
169 my $file_unicode = pack("U0C*", map { ord($_) } split(//,$file)); # force explicitly to unicode
170
171 my @ascii_only_chars
172 = map { $_ >= 128 # if non-ascii
173 ? ""
174 : chr($_) } unpack("U*", $file_unicode); # unpack Unicode characters
175
176 my $ascii_file = join("",@ascii_only_chars);
177
178 if ($ascii_file eq "") {
179 print STDERR "Warning: filename includes no ASCII characters\n";
180 print STDERR " Keeping as original filename\n";
181 $ascii_file = $file;
182 }
183
184 return $ascii_file;
185}
186
187
188sub remove_difficult_chars
189{
190 my $self = shift @_;
191
192 my ($file) = @_;
193
194 # remove problematic characters from filename that make using it in a URL difficult
195
196 my $file_unicode = pack("U0C*", map { ord($_) } split(//,$file)); # force explicitly to unicode
197
198 my $url = $file_unicode;
199 $url =~ s/\x{2018}|\x{2019}|\x{201C}|\x{201D}//g; # remove smart quotes as cause problem in URL for streaming web server
200 $url =~ s/\x{2013}/\-/g; # change en-dash to '-' as again causes problems for streaming web server
201
202 return $url;
203}
204
205
206sub url_safe
207{
208 my $self = shift @_;
209
210 my ($file) = @_;
211
212 my @url_utf8_chars
213 = map { $_ >= 128 # if non-ascii
214 ? "%" . sprintf("%02X", $_)
215 : chr($_) } unpack("U*", $file); # unpack Unicode characters
216
217 my $url = join("",@url_utf8_chars);
218
219
220 return $url;
221}
222
223
224
225sub gsdlhome_independent
226{
227 my $self = shift @_;
228 my ($filename) = @_;
229
230 my $gsdlhome = $ENV{'GSDLHOME'};
231 $gsdlhome = &util::filename_to_regex($gsdlhome);
232
233 my $filename_gsdlenv = $filename;
234
235 if ($ENV{'GSDLOS'} =~ /^windows$/i) {
236 $filename_gsdlenv =~ s@^$gsdlhome@%GSDLHOME%@;
237 }
238 else {
239 $filename_gsdlenv =~ s@^$gsdlhome@\$GSDLHOME@;
240 }
241
242 return $filename_gsdlenv;
243}
244
245
246sub unbuffered_monitor_init
247{
248 my $saved_record_sep = $/;
249 $/ = "\r";
250
251 my $saved_buffer_len = $|;
252 $| = 1;
253
254 my $saved_rec = { 'saved_record_sep' => $saved_record_sep,
255 'saved_buffer_len' => $saved_buffer_len };
256
257 return $saved_rec;
258}
259
260
261
262sub unbuffered_monitor_deinit
263{
264 my ($saved_rec) = @_;
265
266 my $saved_record_sep = $saved_rec->{'saved_record_sep'};
267 my $saved_buffer_len = $saved_rec->{'saved_buffer_len'};
268
269 $/ = $saved_record_sep;
270 $| = $saved_buffer_len;
271}
272
273
274sub ffmpeg_monitor_line
275{
276 my ($line) = @_;
277
278 my $had_error = 0;
279 my $generate_dot = 0;
280
281 if ($line =~ m/^frame=/)
282 {
283 $generate_dot = 1;
284 }
285
286 return ($had_error,$generate_dot);
287}
288
289
290sub handbrake_monitor_line
291{
292 my ($line) = @_;
293
294 my $had_error = 0;
295 my $generate_dot = 0;
296
297 if ($line =~ m/^Encoding:/)
298 {
299 print STDERR $line;
300 }
301 else {
302 $generate_dot = 1;
303 }
304
305 return ($had_error,$generate_dot);
306}
307
3081;
Note: See TracBrowser for help on using the repository browser.