###########################################################################
#
# AudioConverter - helper plugin that does audio conversion
#
# A component of the Greenstone digital library software
# from the New Zealand Digital Library Project at the 
# University of Waikato, New Zealand.
#
# Copyright (C) 2008 New Zealand Digital Library Project
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
###########################################################################
package AudioConverter;

use MultimediaConverter;


use strict;
no strict 'refs'; # allow filehandles to be variables and viceversa

use gsprintf 'gsprintf';

BEGIN {
    @AudioConverter::ISA = ('MultimediaConverter');
}


my $arguments = [
		 ];

my $options = { 'name' => "ImageConverter",
		'desc' => "{ImageConverter.desc}",
		'abstract' => "yes",
		'inherits' => "yes",
		'args' => $arguments };

sub new {
    my ($class) = shift (@_);
    my ($pluginlist,$inputargs,$hashArgOptLists) = @_;
    push(@$pluginlist, $class);

    push(@{$hashArgOptLists->{"ArgList"}},@{$arguments});
    push(@{$hashArgOptLists->{"OptList"}},$options);

    my $self = new MultimediaConverter($pluginlist, $inputargs, $hashArgOptLists, 1);


    return bless $self, $class;

}

# Discover the characteristics of a audio file.

#  Equivalent step to that in ImagePlugin that uses ImageMagicks's
#  'indentify' utility

#  Here we use 'ffmpeg' for audio but for consistency keep the Perl
#  method name the same as before


sub identify { 
    my ($audio, $outhandle, $verbosity) = @_;

    # Use the ffmpeg command to get the file specs
    my $command = "ffmpeg -i \"$audio\"";

    print $outhandle "  $command\n" if ($verbosity > 2);
    my $result = '';
    $result = `$command 2>&1`;
    print $outhandle "  $result\n" if ($verbosity > 4);

    # Read the type, width, and height etc.
    my $vtype =  'unknown';
    my $vcodec = 'unknown';
    my $width =  'unknown';
    my $height = 'unknown';
    my $fps    = 'unknown';

    my $atype =  'unknown';
    my $afreq =  'unknown';
    my $achan =  'unknown';
    my $arate =  'unknown';

    my $audio_safe = quotemeta $audio;

    # strip off everything up to filename
    $result =~ s/^.*\'$audio_safe\'://s;

    if ($result =~ m/Audio: (\w+), (\d+) Hz, (\w+)(?:, (\d+.*))?/m) {
	$atype = $1;
	$afreq = $2;
	$achan = $3;
	$arate = $4 if (defined $4);
    }

    # Read the duration
    my $duration = "unknown";
    if ($result =~ m/Duration: (\d+:\d+:\d+\.\d+)/m) {
	$duration = $1;
    }
    print $outhandle "  file: $audio:\t $atype, $duration\n" 
	if ($verbosity > 2);

    if ($verbosity >3) {
	print $outhandle "\t freq = $afreq Hz, $achan, $arate\n";
    }

    # Return the specs
    return ($duration, -s $audio, $atype,$afreq,$achan,$arate);
}



sub audio_converto_cmd
{
    my $self = shift (@_);
    my ($originalfilename,$converttotype) = @_;

    my $output_dir = $self->{'cached_dir'};
    my $iaudio_root = $self->{'cached_file_root'};

    
    my $file = "$iaudio_root.$converttotype";
    my $filename = &util::filename_cat($output_dir,$file);
    
    my $exp_duration = $self->{'exp_duration'};
    my $t_opt = (defined $exp_duration) ? "-t $exp_duration" : "";
    
    my $main_opts = "-y $t_opt";
    

    my $originalfilename_gsdlenv = $self->gsdlhome_independent($originalfilename);
    my $filename_gsdlenv = $self->gsdlhome_independent($filename);
    
    
    my $convertto_cmd = "ffmpeg $main_opts -i \"$originalfilename_gsdlenv\"";
    $convertto_cmd .= " -y \"$filename_gsdlenv\"";
    
    return $convertto_cmd;
}



sub audio_stream_cmd
{
    my $self = shift (@_);
    my ($iaudio_filename,
	$streaming_bitrate,$streaming_size, 
	$opt_streaming_achan, $opt_streaming_arate) = @_;

    my $streaming_achan 
	= (defined $opt_streaming_achan) ? $opt_streaming_achan : 2;

    my $streaming_arate 
	= (defined $opt_streaming_arate) ? $opt_streaming_arate : 22050;

    my $output_dir = $self->{'cached_dir'};
    my $iaudio_root = $self->{'cached_file_root'};

    my $mp3_file = "${iaudio_root}_stream.mp3";
    my $mp3_filename = &util::filename_cat($output_dir,$mp3_file);

    my $exp_duration = $self->{'exp_duration'};
    my $t_opt = (defined $exp_duration) ? "-t $exp_duration" : "";

    my $main_opts = "-y $t_opt";

    my $bitrate_opt = "-b $streaming_bitrate";
    my $stream_opts .= " -ac $streaming_achan -ar $streaming_arate";


    my $all_opts = "$main_opts $stream_opts"; 

    my $ffmpeg_cmd;

    my $iaudio_filename_gsdlenv = $self->gsdlhome_independent($iaudio_filename);
    my $mp3_filename_gsdlenv = $self->gsdlhome_independent($mp3_filename);

    
    $ffmpeg_cmd = "ffmpeg -i \"$iaudio_filename_gsdlenv\" $all_opts -y \"$mp3_filename_gsdlenv\"";

    return ($ffmpeg_cmd,$mp3_filename,$mp3_file);
}



1;
