Audio-Metadata

 view release on metacpan or  search on metacpan

lib/Audio/Metadata/TextProcessor.pm  view on Meta::CPAN

package Audio::Metadata::TextProcessor;
{
  $Audio::Metadata::TextProcessor::VERSION = '0.16';
}
BEGIN {
  $Audio::Metadata::TextProcessor::VERSION = '0.15';
}

use strict;
use warnings;

use Audio::Metadata;
use Any::Moose;


has input_fh  => ( is => 'ro', isa => 'FileHandle', );
has output_fh => ( is => 'ro', isa => 'FileHandle', );
has debug     => ( is => 'rw', isa => 'Bool', default => 0, );


sub BUILDARGS {
    ## Overriden.
    my $self = shift;
    my ($init_params) = @_;

    my %new_args = %$init_params;
    foreach my $mode (qw/input output/) {

        next if !defined $init_params->{$mode};
        delete $new_args{$mode};

        open my $fh, $mode eq 'input' ? '<' : '>', $init_params->{$mode}
            or die "Couldn't open $mode stream \"$init_params->{$mode}\": $!";
        $new_args{"${mode}_fh"} = $fh;
    }

    return \%new_args;
}


sub update_from_cue {
    ## Reads track info from a cue file and saves to tracks, based on track numbers.
    my $self = shift;

    my @metadatas = $self->_input_cue;
    my @file_names = grep /^\d+[_ ]?-[_ ]?.+\.(flac|ogg|mp3)$/i, glob('*.*');

    die @metadatas . ' tracks parsed, but ' . @file_names . ' files found'
        unless @metadatas == @file_names;

    for (my $i = 0; $i < @file_names; $i++) {
        my $file_name = $file_names[$i];
        my $metadata = $metadatas[$i];

        my $metadata_writer = Audio::Metadata->new_from_path($file_name);
        $self->_log($file_name);

        foreach my $var (keys %$metadata) {
            $self->_log(" $var => $metadata->{$var}");
            $metadata_writer->set_var($var => $metadata->{$var});
        }
        $metadata_writer->save;
    }
}


sub update {
    ## Reads metadata from specified file handle and saves to media files.
    my $self = shift;

    my $fh = $self->input_fh;
    my %curr_item;
    while (my $line = <$fh>) {
        chomp $line;

        my ($var, $value) = $line =~ /^(\S+) *(.*)$/;
        if ($var) {
            $curr_item{$var} = $value;
        }
        else {
            $self->_apply_item(\%curr_item);
            %curr_item = ();
            next;
        }
    }
    $self->_apply_item(\%curr_item) if %curr_item;
}


sub _apply_item {
    ## Saves metadata to file in the given hash.
    my $self = shift;
    my ($item) = @_;

    my $metadata = Audio::Metadata->new_from_path($item->{_FILE_NAME});
    my $is_changed;

    foreach my $var (grep /^[^_]/, keys %$item) {
        no warnings 'uninitialized';
        next if $item->{$var} eq $metadata->get_var($var);

        $metadata->set_var($var => $item->{$var});
        $is_changed++;
    }

    $metadata->save if $is_changed;
}


sub _input_cue {
    ## Reads cue file from input file handle and returns track list as array of hashes.
    my $class = shift;

    # Define names of properties common to the whole album, and how to map
    # them to tags.
    my %common_props;
    my %common_props_map = (
        TITLE       => 'ALBUM',
        PERFORMER   => 'ARTIST',
    );

    # Go through .CUE file, parsing common properties as well as individual ones.
    my @tracks;
    my $curr_track_no;

    my $fh = $class->input_fh;
    while (<$fh>) {



( run in 1.956 second using v1.01-cache-2.11-cpan-13bb782fe5a )