| new topic post reply | Tech Patterns Forum Index ==> Open Source and Free Software :: Applications and Projects |
|
techAdmin
Back to top
Status: Site Admin Joined: 26 Sep 2003 Posts: 2655 Location: East Coast, West Coast? I know it's one of them. |
nice work, I'll watch this, and once you feel it's stable, add it in.
I was expecting a full rewrite of this script from someone but they vaporized so I guess I'll start doing the maintaining again. First to add is better support for opts, specifically case sensitivity, I have the code for that, but was waiting for the new version, which I guess is now officially not happening. |
| Back to top |
Ah ah, glad you like !
Well, unfortunately I had to gave up on multithreading... Just to use forking instead :) It was really easy actually, here's a version that works on a dual core/threads. We could think of adding a parameter like "$cpu_cores". :: Code :: sub convert_file {
my $result; my $cmd; my ($inFile, $outFile) = @_; if ( $OUTPUT_TYPE eq 'ogg' ){ $result = `$COMMAND_OGG $SILENT_ARG_FO -q $QUALITY -o "$outFile" "$inFile"`; } elsif ( $OUTPUT_TYPE eq 'mp3' ){ # Modified: Odd @2011-03-23 01:51:26 - Include ID3 copying $cmd = &flac2mp3_cmd( $COMMAND_FLAC, "$inFile", $COMMAND_LAME, $QUALITY, "$outFile" ); $result = `$cmd`; } return $result; } sub sync_collection_files { my $file; @files; $destinationFile; $srcInfo; $srcModTime; $destInfo; $destModTime; my $pm = new Parallel::ForkManager(2); my $inFile; $outFile; $bFileCreated; @files = @_; $file = ''; $outFile = ''; $inFile = ''; $destinationFile = ''; $bFileCreated = '0'; $srcInfo = ''; $srcModTime = ''; $destInfo = ''; $destModTime = ''; foreach $file (@files) { $file =~ s/\n$//; $file =~ s/^\.\///; #print "F: $DIR_PREFIX_DEST/$file\n"; # Figure out what the destination file would be... $destinationFile = $file; if ( $EXTENSION eq $INPUT_TYPE ){ $destinationFile =~ s/\.$INPUT_TYPE$/\.$OUTPUT_TYPE/; } #print "D: $destinationFile\n"; # Now stat the destinationFile, and see if it's date is more recent # than that of the original file. If so, we re-encode. # We also re-encode if the user supplied --force $srcInfo = stat ("$DIR_PREFIX_SOURCE/$file"); $srcModTime = $srcInfo->mtime; $destInfo = stat ("$DIR_PREFIX_DEST/$destinationFile"); if ( $destInfo ) { $destModTime = $destInfo->mtime; # print "DEST_MOD: $destModTime :: SRC_MOD: $srcModTime :: FORCE: $force\n"; # } else { # print "NOT EXISTS: $destinationFile \n"; # print "P1: $file ==> \n\t$destinationFile\n"; } # If the destination file does not exist, or the user specified force, # or the srcfile is more recent then the dest file, we encode. if ( !$destInfo || $B_FORCE || ( $srcModTime > $destModTime) ) { $file =~ s/\`/\'/g; $inFile = "$DIR_PREFIX_SOURCE/$file" . "c"; chop ($inFile); $outFile = "$DIR_PREFIX_DEST/$destinationFile" . "g"; chop ($outFile); eval $PRINT_LINE_SMALL; if ( $EXTENSION eq $INPUT_TYPE ){ if ( ! $B_SILENT ) { print "ENCODE: $file ==> \n"; print " $destinationFile\n"; } else { # add line break only when file exists print "\nEncoding $file to $OUTPUT_TYPE..."; } $inFile =~ s/\0//g; $outFile =~ s/\0//g; $pm->start and next; # do the fork # if ( $OUTPUT_TYPE eq 'ogg' ){ # $cmd = "$COMMAND_OGG $SILENT_ARG_FO -q $QUALITY -o \"$outFile\" \"$inFile\""; # } # elsif ( $OUTPUT_TYPE eq 'mp3' ){ # # Modified: Odd @2011-03-23 01:51:26 - Include ID3 copying # $cmd = &flac2mp3_cmd( $COMMAND_FLAC, "$inFile", $COMMAND_LAME, $QUALITY, "$outFile" ); # #$result = `$cmd`; # } &convert_file($inFile, $outFile); $pm->finish; } else { if ( ! $B_SILENT ) { print "COPY: $file ==> \n"; print " $outFile\n"; } else { print "\nCopying $file..."; } $inFile =~ s/\0//g; $outFile =~ s/\0//g; $result = `cp -f "$inFile" "$outFile"`; } $bFileCreated = 'true'; $B_DEST_CHANGED = 'true'; } } if ( ! $bFileCreated ){ if ( ! $B_SILENT ) { print "No files to process of type: $EXTENSION\n"; } else { print "none found."; } } # wait for all the forks to finish before terminating # the parent.. otherwise terminating the parent force kills # all the forks $pm->wait_all_children; } And you need to add a line "use Parallel::ForkManager;" at the beginning (and add the proper Fork module... wasn't there by default on Ubuntu 11.10) Hope you like! |
|
techAdmin
Back to top
Status: Site Admin Joined: 26 Sep 2003 Posts: 2655 Location: East Coast, West Coast? I know it's one of them. |
Oh, I was going to note, no modules that are not in default perl install should be used, but if they are, for multithreading, the logic needs to test for that module and give error to let users know what to do.
It's actually fine for multithread to have a non base install module needed since that's a more specialized feature. In general I'd like to keep acxi as something you download and run as a script, and it will of course tell you if you are asking for a codec operation where the app needed is absent. So the same would go with an advanced feature, it would need to test for that module and give error and instructions on what to do if it's been requested. Not sure how you make perl do that. I'll take a look at the code tomorrow , thanks for the work. |
| Back to top |
Mmm that's a good point. Are we able to test the presence of a module in perl and act in consequence?
I think it's still worth having such an option. People who know about multi-core will be interested in this, especially if we describe it in the comments. Just to recap, we need: - a parameter to choose for a 1->1 library replication (thus allow a cleaning procedure) - to test the presence of the Pallel::ForkManager and have a small if allowing for a forking or standard approach - to add a $cpu_core parameter to set the number of possible forks |
| Back to top |
I made to patches for the script:
The first one is very simple: It will let you encode ogg files from quality -1 till 10 see [link]. :: Code :: 160c160
< print "--quality n -q n For ogg: n can be 1-10, 10 is the biggest file/highest quality.\n"; --- > print "--quality n -q n For ogg: n can be -1-10, 10 is the biggest file/highest quality.\n"; 352c352 < if ( $OUTPUT_TYPE eq 'ogg' && $QUALITY !~ m/^([1-9]|10)$/ ) { --- > if ( $OUTPUT_TYPE eq 'ogg' && $QUALITY !~ m/^(-[0-1]|(\d|10))$/ ) { 354c354 < $errorMessage = "$errorMessage\n\t$OUTPUT_TYPE only supports 1-10 quality. You entered: $QUALITY\n"; --- > $errorMessage = "$errorMessage\n\t$OUTPUT_TYPE only supports -1-10 quality. You entered: $QUALITY\n"; I also wanted to add the possibility to use fractional qualities, but it seems oggenc processes the fractions with a , (comma) or a . (dot) depending on your locale and I don't know how to easily implement that. The other patch makes it possible to copy playlists. :: Code :: 75a76
> our @COPY_PLAYLISTS; 124a126,131 > # > # Playlists types to copy over to the new directories. Has been > # tested with both .m3u and .cue files with relative paths in the > # files. Will not work (yet) with absolute paths or relative paths > # outside of your $DIR_PREFIX_SOURCE. > @COPY_PLAYLISTS = ( 'cue', 'm3u' ); 504c511,521 < } --- > } > elsif ( "@COPY_PLAYLISTS" =~ /(^|\s)$EXTENSION(\s|$)/ ) { > &sync_playlist_files ("$inFile", "$outFile" ); > if ( $LOG_LEVEL > 1 ) { > print "COPY: $file ==> \n"; > print " $outFile\n"; > } > elsif ( $LOG_LEVEL > 0 ) { > print "\nCopying $file..."; > } > } 555a573,590 > sub sync_playlist_files { > my ($inPlaylist, $outPlaylist) = @_; > my @outData; > open (INFILE, "$inPlaylist"); > while (<INFILE>) { > $_ =~ s/\.$INPUT_TYPE/\.$OUTPUT_TYPE/; > if ( $OUTPUT_TYPE eq 'mp3' && $EXTENSION eq 'cue' && $_ =~ m/^FILE/) { > $_ =~ s/WAVE$/MP3/; > } > @outData = (@outData,"$_"); > } > close INFILE; > open (OUTFILE, ">$outPlaylist"); > print OUTFILE join("",@outData); > close OUTFILE; > > } > 561c596 < @extensions = ( @COPY_TYPES, $INPUT_TYPE ); --- > @extensions = ( @COPY_TYPES, $INPUT_TYPE, @COPY_PLAYLISTS ); I've got it working for both cue and m3u files and they have to use a relative path to point to the music files. I guess it should also work with pls files, but I don't have any to test with. This is my first time doing anything in perl, and any comments, corrections and improvements are very welcome. |
|
techAdmin
Back to top
Status: Site Admin Joined: 26 Sep 2003 Posts: 2655 Location: East Coast, West Coast? I know it's one of them. |
looks ilke good ideas, don't worry about first time with perl, acxi is also my only perl project, it's the ideas and effort and code, m ost important, that matter.
|
| Back to top |
Hi!
Sorry for the long silence. Very busy times. I've been playing a bit with multithreading in the new version, but I think I'll rather go with forking instead, as Perl threads are not lightweight, and creates a full copy of the program for each thread. But it tends to go some months between each time I have a look at the script, and then I usually rewrite the whole think, so I can't really give an estimate on when it's done and how it'll be, unless someone sees it as very urgent... But I haven't forgotten about it, at least :) BR Odd |
|
All times are GMT - 8 Hours |
|