A hint: This file contains one or more very long lines, so maybe it is better readable using the pure text view mode that shows the contents as wrapped lines within the browser window.
1 From c497331621c0a6c128169945f67b552e81ab539f Mon Sep 17 00:00:00 2001 2 From: Reuben Thomas <rrt@sc3d.org> 3 Date: Mon, 22 Jan 2018 13:21:55 +0000 4 Subject: [PATCH 2/2] Fix hardwired installation paths in pacpl 5 6 --- 7 Makefile.am | 10 + 8 configure | 16 +- 9 configure.ac | 2 +- 10 pacpl | 4034 ---------------------------------------------------------- 11 pacpl.in | 4034 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 12 5 files changed, 4059 insertions(+), 4037 deletions(-) 13 delete mode 100755 pacpl 14 create mode 100755 pacpl.in 15 16 diff --git a/Makefile.am b/Makefile.am 17 index d3506f1..ee5503b 100644 18 --- a/Makefile.am 19 +++ b/Makefile.am 20 @@ -74,8 +74,18 @@ DOC_DIR = $(DESTDIR)$(docdir) 21 MAN_DIR = $(DESTDIR)$(mandir)/man1 22 EXTRA_DIR = $(CONF_DIR)/extra 23 24 +edit = sed \ 25 + -e 's|@pkgdatadir[@]|$(pkgdatadir)|g' \ 26 + -e 's|@sysconfdir[@]|$(sysconfdir)|g' 27 + 28 all : pacpl.1.gz 29 30 +pacpl: pacpl.in Makefile 31 + rm -f $@ $@.tmp 32 + $(edit) '$@.in' >$@.tmp 33 + mv $@.tmp $@ 34 + chmod +x $@ 35 + 36 pacpl.1.gz : pacpl 37 $(POD2MAN) $< | $(GZIP) -9 > $@ 38 touch $@ 39 diff --git a/configure b/configure 40 index 49a871d..0423607 100755 41 --- a/configure 42 +++ b/configure 43 @@ -582,7 +582,7 @@ PACKAGE_BUGREPORT='' 44 PACKAGE_URL='' 45 46 ac_default_prefix=/usr 47 -ac_unique_file="pacpl" 48 +ac_unique_file="pacpl.in" 49 ac_subst_vars='LTLIBOBJS 50 LIBOBJS 51 DESTDIR 52 @@ -687,6 +687,7 @@ infodir 53 docdir 54 oldincludedir 55 includedir 56 +runstatedir 57 localstatedir 58 sharedstatedir 59 sysconfdir 60 @@ -758,6 +759,7 @@ datadir='${datarootdir}' 61 sysconfdir='${prefix}/etc' 62 sharedstatedir='${prefix}/com' 63 localstatedir='${prefix}/var' 64 +runstatedir='${localstatedir}/run' 65 includedir='${prefix}/include' 66 oldincludedir='/usr/include' 67 docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' 68 @@ -1010,6 +1012,15 @@ do 69 | -silent | --silent | --silen | --sile | --sil) 70 silent=yes ;; 71 72 + -runstatedir | --runstatedir | --runstatedi | --runstated \ 73 + | --runstate | --runstat | --runsta | --runst | --runs \ 74 + | --run | --ru | --r) 75 + ac_prev=runstatedir ;; 76 + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ 77 + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ 78 + | --run=* | --ru=* | --r=*) 79 + runstatedir=$ac_optarg ;; 80 + 81 -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) 82 ac_prev=sbindir ;; 83 -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ 84 @@ -1147,7 +1158,7 @@ fi 85 for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ 86 datadir sysconfdir sharedstatedir localstatedir includedir \ 87 oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ 88 - libdir localedir mandir 89 + libdir localedir mandir runstatedir 90 do 91 eval ac_val=\$$ac_var 92 # Remove trailing slashes. 93 @@ -1300,6 +1311,7 @@ Fine tuning of the installation directories: 94 --sysconfdir=DIR read-only single-machine data [PREFIX/etc] 95 --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] 96 --localstatedir=DIR modifiable single-machine data [PREFIX/var] 97 + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] 98 --libdir=DIR object code libraries [EPREFIX/lib] 99 --includedir=DIR C header files [PREFIX/include] 100 --oldincludedir=DIR C header files for non-gcc [/usr/include] 101 diff --git a/configure.ac b/configure.ac 102 index 281f31f..887f580 100644 103 --- a/configure.ac 104 +++ b/configure.ac 105 @@ -22,7 +22,7 @@ AC_SUBST(KDEDIR) 106 107 AC_PREFIX_DEFAULT(/usr) 108 AC_PREFIX_PROGRAM(pacpl) 109 -AC_CONFIG_SRCDIR(pacpl) 110 +AC_CONFIG_SRCDIR(pacpl.in) 111 112 AC_PROG_INSTALL 113 114 diff --git a/pacpl b/pacpl 115 deleted file mode 100755 116 index 2ad3b74..0000000 117 --- a/pacpl 118 +++ /dev/null 119 @@ -1,4034 +0,0 @@ 120 -#!/usr/bin/perl 121 -# 122 -# Perl Audio Converter 123 -# 124 -# Copyright (C) 2005-2017 Philip Lyons (vorzox@gmail.com) 125 -# 126 -# This program is free software; you can redistribute it and/or modify 127 -# it under the terms of the GNU General Public License as published by 128 -# the Free Software Foundation; either version 3 of the License, or 129 -# (at your option) any later version. 130 -# 131 -# This program is distributed in the hope that it will be useful, 132 -# but WITHOUT ANY WARRANTY; without even the implied warranty of 133 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 134 -# GNU General Public License for more details. 135 -# 136 -# You should have received a copy of the GNU General Public License 137 -# along with this program. If not, see <http://www.gnu.org/licenses/>. 138 - 139 -use strict; 140 -use warnings; 141 -use Getopt::Long; 142 -use File::Basename; 143 -use File::Find; 144 -use File::Spec::Functions qw(rel2abs); 145 -use Parallel::ForkManager; 146 - 147 -use feature qw(switch say); 148 - 149 -no if $] >= 5.018, warnings => "experimental::smartmatch"; 150 - 151 -# Tagging modules 152 -use MP3::Tag; 153 -use Audio::FLAC::Header; 154 -use Audio::Scan; 155 - 156 -# CDDB module 157 -use CDDB_get qw(get_cddb); 158 - 159 -# non-encoder/decoder related options 160 -my 161 -( 162 - $to, 163 - $recursive, 164 - $preserve, 165 - $rip, 166 - $help, 167 - $longhelp, 168 - $verbose, 169 - $verinfo, 170 - $dryrun, 171 - $delete, 172 - $keep, 173 - $overwrite, 174 - $formats, 175 - $topdir, 176 - $only, 177 - $first_run, 178 - 179 - @file, 180 - @dir, 181 - 182 - %run, 183 - %lang, 184 -); 185 - 186 -my $silent = "> /dev/null 2>&1"; 187 - 188 -# tagging options 189 -my 190 -( 191 - $title, 192 - $track, 193 - $artist, 194 - $album, 195 - $comment, 196 - $year, 197 - $genre, 198 - $taginfo, 199 -); 200 - 201 -# name, version & icon information 202 -my $name = "Perl Audio Converter"; 203 -my $version = "5.1.0"; 204 -my $icon_path = "/etc/pacpl/pacpl.png"; 205 - 206 -# If these options are toggled, messages/errors will be displayed 207 -# via kdialog or zenity/notify-send (depending on environment) 208 -my ($gui, $kde, $gnome); 209 - 210 -# Debugging (for developer use only) 211 -my $debug = 0; 212 - 213 -# default configuration. 214 -my %config = ( 215 - 216 - IMPORTM => 0, 217 - JOBS => 4, 218 - 219 - DEFOPTS => 1, 220 - EOPTS => '', 221 - DOPTS => '', 222 - NOPTS => '', 223 - 224 - BITRATE => 128, 225 - FREQ => 44100, 226 - CHANNELS => 2, 227 - EFFECT => '', 228 - FCOMP => 2, 229 - PCOMP => 3, 230 - ACOMP => 3000, 231 - OGGQUAL => 3, 232 - SPXQUAL => 8, 233 - AACQUAL => 100, 234 - MPCQUAL => 'radio', 235 - OFMODE => 'normal', 236 - OFOPT => 'fast', 237 - BRATIO => 2, 238 - BQUANL => 1.0, 239 - BPSIZE => 128, 240 - 241 - USE_CDDB => 1, 242 - CDDB_HOST => 'freedb.freedb.org', 243 - CDDB_PORT => 8880, 244 - CDDB_MODE => 'cddb', 245 - CDDB_INPUT => 1, 246 - DEVICE => '/dev/dvd', 247 - NSCHEME => '%ar - %ti', 248 - 249 - ZEN_DIR => 1, 250 - ZEN_OPTS => 1, 251 - KDE_DIR => 1, 252 - KDE_OPTS => 1, 253 - 254 - ); 255 - 256 -# location of configuration file 257 -my $conf_path = "/etc/pacpl"; 258 -my $po_dir = "/usr/share/pacpl/locale"; 259 -my $mod_dir = "$conf_path/modules"; 260 - 261 -my $conf_file; 262 - 263 -# load the appropriate locale file 264 -load_lang(); 265 - 266 -# try to load configuration file in this order... 267 -my @conf_locations = ( 268 - "$ENV{HOME}/.pacplrc", # Local 269 - "$conf_path/pacpl.conf", # Global 270 - "$ENV{PWD}/pacpl.conf", # Current Directory 271 - ); 272 - 273 -# try to load conf file from one of the above locations 274 -foreach my $i (@conf_locations) { 275 - if (not $conf_file and -e $i) { 276 - $conf_file = $i; 277 - say "$lang{debug} $lang{loaded_config} $conf_file" if $debug == 1; 278 - } 279 -} 280 - 281 -say "$lang{no_config}" if not $conf_file; 282 - 283 -# open config file. 284 -if ($conf_file and -e $conf_file) { 285 - 286 - open(CONF, "$conf_file") or die "$lang{opening_file} $conf_file - $!\n"; 287 - 288 - my @conf_opts = <CONF>; 289 - @conf_opts = grep(!/^#|^$/, @conf_opts); 290 - 291 - close(CONF); 292 - 293 - # now read config file options and change default values accordingly. 294 - foreach (@conf_opts) { 295 - chomp; 296 - my ($k, $v) = split(/\s*=\s*/); 297 - $config{$k} = $v if exists($config{$k}) and $v; 298 - say "$lang{debug} $k = $v" if $debug == 1 and exists($config{$k}); 299 - } 300 -} 301 - 302 -my $codecs_conf = "$conf_path/codecs.conf"; 303 - 304 -# set default encoders/decoders 305 -sub load_codecs { 306 - 307 - open(CODECS, "$codecs_conf") or die "$lang{opening_file} $codecs_conf - $!\n"; 308 - 309 - my @codecs = <CODECS>; 310 - @codecs = grep(!/^$|^#/, @codecs); 311 - @codecs = grep(s/^\s*|\s*$//, @codecs); 312 - 313 - close(CODECS); 314 - 315 - foreach (@codecs) { 316 - 317 - chomp; 318 - my ($k, $v) = split(/\s*=\s*/); 319 - my ($e, $d) = split(/,/, $v); 320 - 321 - $k =~ tr/A-Z/a-z/; 322 - 323 - $run{$k}{DEFAULT_ENCODER} = $e if (exists($run{$k}{DEFAULT_ENCODER})); 324 - $run{$k}{DEFAULT_DECODER} = $d if (exists($run{$k}{DEFAULT_DECODER})); 325 - } 326 -} 327 - 328 -# load po file and store in %lang hash 329 -sub load_lang { 330 - 331 - my $po = "$po_dir/$ENV{LANG}.po"; 332 - $po =~ s/\.UTF-8//i if $po =~ /UTF-8/i; 333 - $po =~ s/\.utf8//i if $po =~ /utf8/i; 334 - $po =~ s/_\w+// if not -e $po; 335 - $po = "$po_dir/en_US.po" if not -e $po; 336 - 337 - open(LANG, "< $po") or die "error: could not open - $po\n$!\n"; 338 - 339 - my @data = <LANG>; 340 - @data = grep(!/^#|^$/, @data); 341 - 342 - close(LANG); 343 - 344 - foreach (@data) { 345 - chomp; 346 - s/=/__EQ__/; 347 - my ($k, $v) = split(/\s*__EQ__\s*/, $_); 348 - $lang{$k} = $v; 349 - } 350 - 351 -} 352 - 353 -my $banner = 1; 354 - 355 -# print error messages 356 -sub perror { 357 - my ($key, $msg) = @_; 358 - say "$name - $version\n"; 359 - say "$lang{error}: $lang{$key} $msg" . "\n"; 360 - system("kdialog --title \"$name\" --error \"$lang{error}: $lang{$key} $msg\" &") if $gui and $kde; 361 - system("zenity --title \"$name\" --error \"$lang{error}: $lang{$key} $msg\" &") if $gui and $gnome; 362 - die "$lang{seek_help}\n"; 363 -} 364 - 365 -# print notices/warnings 366 -sub pnotice { 367 - 368 - my ($key, $msg, $nm) = @_; 369 - 370 - say "$name - $version\n" if $banner == 1; 371 - print "$lang{$key} $msg"; 372 - say '' if $nm == 1; 373 - say "\n" if $nm == 2; 374 - 375 - $banner = 0; 376 -} 377 - 378 -# defaults for user variables. 379 -my $outfile; 380 -my $outdir; 381 -my $defopts = $config{DEFOPTS}; 382 -my $eopts = $config{EOPTS}; 383 -my $dopts = $config{DOPTS}; 384 -my $nopts = $config{NOPTS}; 385 -my $normalize = $config{NOPTS}; 386 -my $bitrate = $config{BITRATE}; 387 -my $freq = $config{FREQ}; 388 -my $channels = $config{CHANNELS}; 389 -my $effect = $config{EFFECT}; 390 -my $fcomp = $config{FCOMP}; 391 -my $acomp = $config{ACOMP}; 392 -my $oggqual = $config{OGGQUAL}; 393 -my $spxqual = $config{SPXQUAL}; 394 -my $aacqual = $config{AACQUAL}; 395 -my $mpcqual = $config{MPCQUAL}; 396 -my $ofmode = $config{OFMODE}; 397 -my $ofopt = $config{OFOPT}; 398 -my $bratio = $config{BRATIO}; 399 -my $bquanl = $config{BQUANL}; 400 -my $bpsize = $config{BPSIZE}; 401 - 402 -my $cdinfo; 403 -my $nocddb; 404 -my $noinput; 405 -my $device = $config{DEVICE}; 406 -my $nscheme = $config{NSCHEME}; 407 -my $my_encoder; 408 -my $my_decoder; 409 -my $encoder; 410 -my $decoder; 411 - 412 -my $jobs = $config{JOBS}; 413 - 414 -# command line options 415 -GetOptions 416 -( 417 - 't|to=s' => \$to, 418 - 'r|recursive' => \$recursive, 419 - 'p|preserve' => \$preserve, 420 - 'h|help' => \$help, 421 - 'l|longhelp' => \$longhelp, 422 - 'v|verbose' => \$verbose, 423 - 'f|formats' => \$formats, 424 - 'o|only=s' => \$only, 425 - 'k|keep' => \$keep, 426 - 'j|jobs=n' => \$jobs, 427 - 428 - 'taginfo' => \$taginfo, 429 - 430 - 'version' => \$verinfo, 431 - 'dryrun' => \$dryrun, 432 - 'delete' => \$delete, 433 - 'overwrite' => \$overwrite, 434 - 'normalize' => \$normalize, 435 - 'encoder=s' => \$my_encoder, 436 - 'decoder=s' => \$my_decoder, 437 - 438 - 'title=s' => \$title, 439 - 'track=n' => \$track, 440 - 'artist=s' => \$artist, 441 - 'album=s' => \$album, 442 - 'comment=s' => \$comment, 443 - 'year=n' => \$year, 444 - 'genre=s' => \$genre, 445 - 446 - 'gui' => \$gui, 447 - 'kde' => \$kde, 448 - 'gnome' => \$gnome, 449 - 450 - 'eopts=s' => \$eopts, 451 - 'dopts=s' => \$dopts, 452 - 'defopts=n' => \$defopts, 453 - 'nopts=s' => \$nopts, 454 - 'outfile=s' => \$outfile, 455 - 'outdir=s' => \$outdir, 456 - 457 - 'bitrate=n' => \$bitrate, 458 - 'freq=n' => \$freq, 459 - 'channels=n' => \$channels, 460 - 'effect=s' => \$effect, 461 - 'fcomp=n' => \$fcomp, 462 - 'acomp=n' => \$acomp, 463 - 'oggqual=n' => \$oggqual, 464 - 'spxqual=n' => \$spxqual, 465 - 'aacqual=n' => \$aacqual, 466 - 'mpcqual=s' => \$mpcqual, 467 - 'ofmode=s' => \$ofmode, 468 - 'ofopt=s' => \$ofopt, 469 - 'bratio=n' => \$bratio, 470 - 'bquanl=n' => \$bquanl, 471 - 'bpsize=n' => \$bpsize, 472 - 473 - 'rip=s' => \$rip, 474 - 'nocddb' => \$nocddb, 475 - 'noinput' => \$noinput, 476 - 'device=s' => \$device, 477 - 'nscheme=s' => \$nscheme, 478 - 'cdinfo' => \$cdinfo, 479 -); 480 - 481 -if (defined($preserve) && !defined($outdir)) { 482 - die "You must specify --outdir when you use --preserve option. See man page.\n"; 483 -} 484 - 485 -$silent = '' if $verbose; 486 - 487 -my $opts; 488 -my $total_converted = 0; 489 -my $total_failed = 0; 490 - 491 -# Initialize the fork manager with a count set through pacpl.conf or via the command line 492 -my $pm = Parallel::ForkManager->new($jobs); 493 - 494 -# conversion options. when adding a new format, 495 -# wild card %i = input file and %o = output file 496 -%run = ( 497 - 498 - '3g2' => { 499 - 500 - DEFAULT_ENCODER => 'ffmpeg', 501 - DEFAULT_DECODER => 'ffmpeg', 502 - 503 - ENCODER => { 504 - ffmpeg => { 505 - NAME => 'ffmpeg', 506 - ESTR => sub { 507 - $opts = "-ar 8000 -ac 1" if $defopts == 1; 508 - $opts = '' if $defopts == 0; 509 - "-y -i %i $eopts $opts %o" 510 - }, 511 - 512 - PROMPT => { NONE => 0, }, 513 - }, 514 - 515 - avconv => { 516 - NAME => 'avconv', 517 - ESTR => sub { 518 - $opts = "-ar 8000 -ac 1" if $defopts == 1; 519 - $opts = '' if $defopts == 0; 520 - "-y -i %i $eopts $opts %o" 521 - }, 522 - 523 - PROMPT => { NONE => 0, }, 524 - }, 525 - 526 - }, 527 - 528 - DECODER => { 529 - ffmpeg => { 530 - NAME => 'ffmpeg', 531 - DSTR => sub { "-y -i %o $dopts %o" }, 532 - }, 533 - 534 - avconv => { 535 - NAME => 'avconv', 536 - DSTR => sub { "-y -i %o %dopts %o" }, 537 - }, 538 - }, 539 - 540 - TAGS => { 541 - READ => 0, 542 - WRITE => 0, 543 - MODULE => undef, 544 - }, 545 - 546 - }, 547 - 548 - '3gp' => { 549 - 550 - DEFAULT_ENCODER => 'ffmpeg', 551 - DEFAULT_DECODER => 'ffmpeg', 552 - 553 - ENCODER => { 554 - ffmpeg => { 555 - NAME => 'ffmpeg', 556 - ESTR => sub { 557 - $opts = "-ar 8000 -ac 1" if $defopts == 1; 558 - $opts = '' if $defopts == 0; 559 - "-y -i %i $eopts $opts %o" 560 - }, 561 - 562 - PROMPT => { NONE => 0, }, 563 - }, 564 - 565 - avconv => { 566 - NAME => 'avconv', 567 - ESTR => sub { 568 - $opts = "-ar 8000 -ac 1" if $defopts == 1; 569 - $opts = '' if $defopts == 0; 570 - "-y -i %i $eopts $opts %o" 571 - }, 572 - 573 - PROMPT => { NONE => 0, }, 574 - }, 575 - 576 - }, 577 - 578 - DECODER => { 579 - ffmpeg => { 580 - NAME => 'ffmpeg', 581 - DSTR => sub { "-y -i %o $dopts %o" }, 582 - }, 583 - 584 - avconv => { 585 - NAME => 'avconv', 586 - DSTR => sub { "-y -i %o %dopts %o" }, 587 - }, 588 - }, 589 - 590 - TAGS => { 591 - READ => 0, 592 - WRITE => 0, 593 - MODULE => undef, 594 - }, 595 - 596 - }, 597 - 598 - aac => { 599 - 600 - DEFAULT_ENCODER => "faac", 601 - DEFAULT_DECODER => "faad", 602 - 603 - ENCODER => { 604 - faac => { 605 - NAME => "faac", 606 - ESTR => sub { 607 - $opts = "-q $aacqual" if $defopts == 1; 608 - $opts = '' if $defopts == 0; 609 - "$eopts $opts %i -o %o" 610 - }, 611 - PROMPT => { AACQUAL => 1 }, 612 - }, 613 - 614 - ffmpeg => { 615 - NAME => 'ffmpeg', 616 - ESTR => sub { 617 - $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 618 - $opts = '' if $defopts == 0; 619 - "-y -i %i $eopts $opts %o" 620 - }, 621 - 622 - PROMPT => { 623 - BITRATE => 1, 624 - FREQ => 1, 625 - CHANNELS => 1, 626 - }, 627 - }, 628 - 629 - avconv => { 630 - NAME => 'avconv', 631 - ESTR => sub { 632 - $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 633 - $opts = '' if $defopts == 1, 634 - }, 635 - 636 - PROMPT => { 637 - BITRATE => 1, 638 - FREQ => 1, 639 - CHANNELS => 1, 640 - }, 641 - }, 642 - }, 643 - 644 - DECODER => { 645 - faad => { 646 - NAME => "faad", 647 - DSTR => sub { "$dopts -o %i %o" }, 648 - }, 649 - 650 - ffmpeg => { 651 - NAME => "ffmpeg", 652 - DSTR => sub { "$dopts -y -i %i %o" }, 653 - }, 654 - 655 - avconv => { 656 - NAME => 'avconv', 657 - DSTR => sub { "$dopts -y -i %i %o" }, 658 - }, 659 - 660 - mplayer => { 661 - NAME => "mplayer", 662 - DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 663 - }, 664 - }, 665 - 666 - TAGS => { 667 - READ => 0, 668 - WRITE => 0, 669 - MODULE => undef, 670 - }, 671 - }, 672 - 673 - ac3 => { 674 - 675 - DEFAULT_ENCODER => "ffmpeg", 676 - DEFAULT_DECODER => "ffmpeg", 677 - 678 - ENCODER => { 679 - ffmpeg => { 680 - NAME => "ffmpeg", 681 - ESTR => sub { 682 - $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 683 - $opts = '' if $defopts == 0; 684 - "-y -i %i $eopts $opts %o" 685 - }, 686 - 687 - PROMPT => { 688 - BITRATE => 1, 689 - FREQ => 1, 690 - CHANNELS => 1, 691 - }, 692 - }, 693 - 694 - avconv => { 695 - NAME => "avconv", 696 - ESTR => sub { 697 - $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 698 - $opts = '' if $defopts == 0; 699 - "-y -i %i $eopts $opts %o" 700 - }, 701 - PROMPT => { 702 - BITRATE => 1, 703 - FREQ => 1, 704 - CHANNELS => 1, 705 - }, 706 - }, 707 - 708 - aften => { 709 - NAME => "aften", 710 - ESTR => sub { 711 - $opts = "-v 1 -q $bitrate -2" if $defopts == 1; 712 - $opts = '' if $defopts == 0; 713 - "$eopts $opts %i %o" 714 - }, 715 - 716 - PROMPT => { 717 - BITRATE => 1, 718 - }, 719 - }, 720 - 721 - }, 722 - 723 - DECODER => { 724 - mplayer => { 725 - NAME => "mplayer", 726 - DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 727 - }, 728 - 729 - ffmpeg => { 730 - NAME => "ffmpeg", 731 - DSTR => sub { "$dopts -y -i %i %o" }, 732 - }, 733 - 734 - avconv => { 735 - NAME => "avconv", 736 - DSTR => sub { "$dopts -y -i %i %o" }, 737 - }, 738 - }, 739 - 740 - TAGS => { 741 - READ => 0, 742 - WRITE => 0, 743 - MODULE => undef, 744 - }, 745 - }, 746 - 747 - adts => { 748 - 749 - DEFAULT_ENCODER => 'ffmpeg', 750 - DEFAULT_DECODER => 'ffmpeg', 751 - 752 - ENCODER => { 753 - ffmpeg => { 754 - NAME => 'ffmpeg', 755 - ESTR => sub { 756 - $opts = "-ab $bitrate.k -ar $freq -ac $channels -codec:a libfaac" if $defopts == 1; 757 - $opts = '' if $defopts == 0; 758 - "-y -i %i $opts $eopts -strict -2 %o" 759 - }, 760 - PROMPT => { 761 - BITRATE => 1, 762 - FREQ => 1, 763 - CHANNELS => 1, 764 - }, 765 - }, 766 - 767 - avconv => { 768 - NAME => 'avconv', 769 - ESTR => sub { 770 - $opts = "-ab $bitrate.k -ar $freq -ac $channels -codec:a libfaac" if $defopts == 1; 771 - $opts = '' if $defopts == 0; 772 - "-y -i %i $opts $eopts %o" 773 - }, 774 - 775 - PROMPT => { 776 - BITRATE => 1, 777 - FREQ => 1, 778 - CHANNELS => 1, 779 - }, 780 - }, 781 - }, 782 - 783 - DECODER => { 784 - ffmpeg => { 785 - NAME => 'ffmpeg', 786 - DSTR => "$dopts -y -i %i %o", 787 - }, 788 - 789 - avconv => { 790 - NAME => 'avconv', 791 - DSTR => "$dopts -y -i %i %o", 792 - }, 793 - }, 794 - 795 - TAGS => { 796 - READ => 0, 797 - WRITE => 0, 798 - MODULE => undef, 799 - }, 800 - }, 801 - 802 - ape => { 803 - 804 - DEFAULT_ENCODER => "mac", 805 - DEFAULT_DECODER => "mac", 806 - 807 - ENCODER => { 808 - mac => { 809 - NAME => "mac", 810 - ESTR => sub { 811 - $opts = "-c$acomp" if $defopts == 1; 812 - $opts = '' if $defopts == 0; 813 - "%i %o $opts $eopts" 814 - }, 815 - 816 - PROMPT => { ACOMP => 1 }, 817 - }, 818 - }, 819 - 820 - DECODER => { 821 - mac => { 822 - NAME => "mac", 823 - DSTR => sub { "%i %o -d $dopts" }, 824 - }, 825 - 826 - ffmpeg => { 827 - NAME => 'ffmpeg', 828 - DSTR => sub { "-y -i %i %dopts %o" }, 829 - }, 830 - 831 - avconv => { 832 - NAME => 'avconv', 833 - DSTR => sub { "-y -i %i $dopts %o" }, 834 - }, 835 - }, 836 - 837 - TAGS => { 838 - READ => 1, 839 - WRITE => 0, 840 - MODULE => "Audio::Scan", 841 - }, 842 - }, 843 - 844 - amr => { 845 - 846 - DEFAULT_ENCODER => "ffmpeg", 847 - DEFAULT_DECODER => "ffmpeg", 848 - 849 - ENCODER => { 850 - ffmpeg => { 851 - NAME => "ffmpeg", 852 - ESTR => sub { 853 - $opts = "-ar 8000 -ac 1" if $defopts == 1; 854 - $opts = '' if $defopts == 0; 855 - "-y -i %i $eopts $opts %o" 856 - }, 857 - 858 - PROMPT => { NONE => 0, }, 859 - }, 860 - 861 - avconv => { 862 - NAME => "avconv", 863 - ESTR => sub { 864 - $opts = "-ar 8000 -ac 1" if $defopts == 1; 865 - $opts = '' if $defopts == 0; 866 - "-y -i %i $eopts $opts %o" 867 - }, 868 - 869 - PROMPT => { NONE => 0, }, 870 - }, 871 - 872 - }, 873 - 874 - DECODER => { 875 - ffmpeg => { 876 - NAME => 'ffmpeg', 877 - DSTR => sub { "-y -i %i $dopts %o" }, 878 - }, 879 - 880 - avconv => { 881 - NAME => 'ffmpeg', 882 - DSTR => sub { "-y -i %i %dopts %o" }, 883 - }, 884 - }, 885 - 886 - TAGS => { 887 - READ => 0, 888 - WRITE => 0, 889 - MODULE => undef, 890 - }, 891 - 892 - }, 893 - 894 - bonk => { 895 - 896 - DEFAULT_ENCODER => "bonk", 897 - DEFAULT_DECODER => "bonk", 898 - 899 - ENCODER => { 900 - bonk => { 901 - NAME => "bonk", 902 - ESTR => sub { 903 - $opts = "-q $bquanl -b $bratio -s $bpsize" if $defopts == 1; 904 - $opts = '' if $defopts == 0; 905 - "encode $eopts $opts %i -o %o" 906 - }, 907 - 908 - PROMPT => { 909 - BQUANL => 1, 910 - BRATIO => 1, 911 - BPSIZE => 1, 912 - }, 913 - }, 914 - }, 915 - 916 - DECODER => { 917 - bonk => { 918 - NAME => "bonk", 919 - DSTR => sub { "decode %i -o %o" }, 920 - }, 921 - }, 922 - 923 - TAGS => { 924 - READ => 0, 925 - WRITE => 0, 926 - MODULE => undef, 927 - }, 928 - }, 929 - 930 - dts => { 931 - 932 - DEFAULT_ENCODER => 'ffmpeg', 933 - DEFAULT_DECODER => 'ffmpeg', 934 - 935 - ENCODER => { 936 - ffmpeg => { 937 - NAME => 'ffmpeg', 938 - ESTR => sub { 939 - $opts = '' if $defopts == 1; 940 - $opts = '' if $defopts == 0; 941 - "-y -i %i $opts $eopts -strict -2 -codec:a libfaac %o" 942 - }, 943 - 944 - PROMPT => { NONE => 0, }, 945 - }, 946 - 947 - avconv => { 948 - NAME => 'avconv', 949 - ESTR => sub { 950 - $opts = '' if $defopts == 1 or $defopts == 0; 951 - "-y -i %i $opts $eopts -codec:a libfaac %o", 952 - }, 953 - PROMPT => { NONE => 0, }, 954 - }, 955 - 956 - dcaenc => { 957 - NAME => 'dcaenc', 958 - ESTR => sub { 959 - $opts = "$bitrate" if $defopts == 0; 960 - $opts = '' if $defopts == 1; 961 - "%i %o $opts" 962 - }, 963 - 964 - PROMPT => { NONE => 0, }, 965 - }, 966 - }, 967 - 968 - DECODER => { 969 - ffmpeg => { 970 - NAME => 'ffmpeg', 971 - DSTR => "$dopts -y -i %i %o", 972 - }, 973 - 974 - avconv => { 975 - NAME => 'avconv', 976 - DSTR => "$dopts -y -i %i %o", 977 - }, 978 - }, 979 - 980 - TAGS => { 981 - READ => 0, 982 - WRITE => 0, 983 - MODULE => undef, 984 - }, 985 - }, 986 - 987 - flac => { 988 - 989 - DEFAULT_ENCODER => "flac", 990 - DEFAULT_DECODER => "flac", 991 - 992 - ENCODER => { 993 - flac => { 994 - NAME => "flac", 995 - ESTR => sub { 996 - $opts = "-$fcomp" if $defopts == 1; 997 - $opts = '' if $defopts == 0; 998 - "$eopts -f $opts %i -o %o" 999 - }, 1000 - PROMPT => { FCOMP => 1 }, 1001 - }, 1002 - 1003 - flake => { 1004 - NAME => "flake", 1005 - ESTR => sub { 1006 - $opts = "-$fcomp" if $defopts == 1; 1007 - $opts = '' if $defopts == 0; 1008 - "$eopts $opts %i -o %o" 1009 - }, 1010 - PROMPT => { FCOMP => 1 }, 1011 - }, 1012 - 1013 - ffmpeg => { 1014 - NAME => "ffmpeg", 1015 - ESTR => sub { 1016 - $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 1017 - $opts = '' if $defopts == 0; 1018 - "-y -i %i $eopts $opts %o" 1019 - }, 1020 - 1021 - PROMPT => { 1022 - BITRATE => 1, 1023 - FREQ => 1, 1024 - CHANNELS => 1, 1025 - }, 1026 - }, 1027 - 1028 - avconv => { 1029 - NAME => 'avconv', 1030 - ESTR => sub { 1031 - $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 1032 - $opts = '' if $defopts == 1; 1033 - "-y -i %i $eopts $opts %o" 1034 - }, 1035 - PROMPT => { 1036 - BITRATE => 1, 1037 - FREQ => 1, 1038 - CHANNELS => 1, 1039 - }, 1040 - }, 1041 - }, 1042 - 1043 - DECODER => { 1044 - flac => { 1045 - NAME => "flac", 1046 - DSTR => sub { "$dopts -f -d %i -o %o" }, 1047 - }, 1048 - 1049 - ffmpeg => { 1050 - NAME => "ffmpeg", 1051 - DSTR => sub { "$dopts -y -i %i %o" }, 1052 - }, 1053 - 1054 - avconv => { 1055 - NAME => 'avconv', 1056 - DSTR => sub { "$dopts -y -i %i %o" }, 1057 - }, 1058 - 1059 - mplayer => { 1060 - NAME => "mplayer", 1061 - DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 1062 - }, 1063 - }, 1064 - 1065 - TAGS => { 1066 - READ => 1, 1067 - WRITE => 1, 1068 - MODULE => "Audio::FLAC::Header", 1069 - }, 1070 - }, 1071 - 1072 - fla => { 1073 - 1074 - DEFAULT_ENCODER => "flac", 1075 - DEFAULT_DECODER => "flac", 1076 - 1077 - ENCODER => { 1078 - flac => { 1079 - NAME => "flac", 1080 - ESTR => sub { 1081 - $opts = "-$fcomp" if $defopts == 1; 1082 - $opts = '' if $defopts == 0; 1083 - "$eopts -f $opts %i -o %o" 1084 - }, 1085 - PROMPT => { FCOMP => 1 }, 1086 - }, 1087 - }, 1088 - 1089 - DECODER => { 1090 - flac => { 1091 - NAME => "flac", 1092 - DSTR => sub { "$dopts -f -d %i -o %o" }, 1093 - }, 1094 - 1095 - mplayer => { 1096 - NAME => "mplayer", 1097 - DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 1098 - }, 1099 - }, 1100 - 1101 - TAGS => { 1102 - READ => 1, 1103 - WRITE => 1, 1104 - MODULE => "Audio::FLAC::Header", 1105 - }, 1106 - }, 1107 - 1108 - la => { 1109 - 1110 - DEFAULT_ENCODER => "la", 1111 - DEFAULT_DECODER => "la", 1112 - 1113 - ENCODER => { 1114 - la => { 1115 - NAME => "la", 1116 - ESTR => sub { "-overwrite $eopts %i %o" }, 1117 - PROMPT => { NONE => 0, }, 1118 - }, 1119 - }, 1120 - 1121 - DECODER => { 1122 - la => { 1123 - NAME => "la", 1124 - ESTR => sub { "-console $dopts %i > %o" }, 1125 - }, 1126 - }, 1127 - 1128 - TAGS => { 1129 - READ => 0, 1130 - WRITE => 0, 1131 - MODULE => undef, 1132 - }, 1133 - }, 1134 - 1135 - mp2 => { 1136 - 1137 - DEFAULT_ENCODER => "ffmpeg", 1138 - DEFAULT_DECODER => "ffmpeg", 1139 - 1140 - ENCODER => { 1141 - ffmpeg => { 1142 - NAME => 'ffmpeg', 1143 - ESTR => sub { 1144 - $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 1145 - $opts = '' if $defopts == 0; 1146 - "-y -i %i $eopts $opts %o" 1147 - }, 1148 - 1149 - PROMPT => { 1150 - BITRATE => 1, 1151 - FREQ => 1, 1152 - CHANNELS => 1, 1153 - }, 1154 - }, 1155 - 1156 - avconv => { 1157 - NAME => 'avconv', 1158 - ESTR => sub { 1159 - $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 1160 - $opts = '' if $defopts == 0; 1161 - "-y -i %i $eopts $opts %o" 1162 - }, 1163 - PROMPT => { 1164 - BITRATE => 1, 1165 - FREQ => 1, 1166 - CHANNELS => 1, 1167 - }, 1168 - }, 1169 - 1170 - toolame => { 1171 - NAME => 'toolame', 1172 - ESTR => sub { 1173 - $opts = "-b $bitrate" if $defopts == 1; 1174 - $opts = '' if $defopts == 0; 1175 - "$eopts $opts %i %o" 1176 - }, 1177 - 1178 - PROMPT => { 1179 - BITRATE => 1, 1180 - }, 1181 - }, 1182 - 1183 - twolame => { 1184 - NAME => 'twolame', 1185 - ESTR => sub { 1186 - $opts = "-b $bitrate -s $freq" if $defopts == 1; 1187 - $opts = '' if $defopts == 0; 1188 - "$eopts $opts %i %o" 1189 - }, 1190 - 1191 - PROMPT => { 1192 - BITRATE => 1, 1193 - FREQ => 1, 1194 - }, 1195 - }, 1196 - 1197 - sox => { 1198 - NAME => 'sox', 1199 - ESTR => sub { 1200 - $opts = "-c $channels -r $bitrate" if $defopts == 1; 1201 - $opts = '' if $defopts == 0; 1202 - "%i $eopts $opts %o" 1203 - }, 1204 - 1205 - PROMPT => { 1206 - BITRATE => 1, 1207 - CHANNELS => 1, 1208 - }, 1209 - }, 1210 - }, 1211 - 1212 - DECODER => { 1213 - 1214 - ffmpeg => { 1215 - NAME => 'ffmpeg', 1216 - DSTR => "$dopts -y -i %i %o", 1217 - }, 1218 - 1219 - avconv => { 1220 - NAME => 'avconv', 1221 - DSTR => "%dopts -y -i %i %o", 1222 - }, 1223 - 1224 - mplayer => { 1225 - NAME => 'mplayer', 1226 - DSTR => "-vc null -vo null -ao pcm:file=%o %i", 1227 - }, 1228 - }, 1229 - 1230 - TAGS => { 1231 - READ => 0, 1232 - WRITE => 0, 1233 - MODULE => undef, 1234 - }, 1235 - }, 1236 - 1237 - mp3 => { 1238 - 1239 - DEFAULT_ENCODER => "lame", 1240 - DEFAULT_DECODER => "lame", 1241 - 1242 - ENCODER => { 1243 - lame => { 1244 - NAME => "lame", 1245 - ESTR => sub { 1246 - $opts = "--resample $freq -b $bitrate -h" if $defopts == 1; 1247 - $opts = '' if $defopts == 0; 1248 - "$eopts $opts %i %o" 1249 - }, 1250 - 1251 - PROMPT => { 1252 - BITRATE => 1, 1253 - FREQ => 1, 1254 - }, 1255 - }, 1256 - 1257 - bladeenc => { 1258 - NAME => "bladeenc", 1259 - ESTR => sub { 1260 - $opts = "-br $bitrate" if $defopts == 1; 1261 - $opts = '' if $defopts == 0; 1262 - "$eopts $opts %i %o" 1263 - }, 1264 - PROMPT => { BITRATE => 1 }, 1265 - }, 1266 - 1267 - ffmpeg => { 1268 - NAME => "ffmpeg", 1269 - ESTR => sub { 1270 - $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 1271 - $opts = '' if $defopts == 0; 1272 - "$eopts -y -i %i $opts %o" 1273 - }, 1274 - 1275 - PROMPT => { 1276 - BITRATE => 1, 1277 - FREQ => 1, 1278 - CHANNELS => 1, 1279 - }, 1280 - }, 1281 - 1282 - avconv => { 1283 - NAME => 'avconv', 1284 - ESTR => sub { 1285 - $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 1286 - $opts = '' if $defopts == 0; 1287 - "-y -i %i $eopts $opts %o" 1288 - }, 1289 - PROMPT => { 1290 - BITRATE => 1, 1291 - FREQ => 1, 1292 - CHANNELS => 1, 1293 - }, 1294 - }, 1295 - 1296 - sox => { 1297 - NAME => "sox", 1298 - ESTR => sub { 1299 - $opts = "-r $freq -c $channels" if $defopts == 1; 1300 - $opts = '' if $defopts == 0; 1301 - "%i $eopts $opts %o" 1302 - }, 1303 - 1304 - PROMPT => { 1305 - FREQ => 1, 1306 - CHANNELS => 1, 1307 - }, 1308 - }, 1309 - }, 1310 - 1311 - DECODER => { 1312 - lame => { 1313 - NAME => "lame", 1314 - DSTR => sub { "$dopts --decode %i %o" }, 1315 - }, 1316 - 1317 - ffmpeg => { 1318 - NAME => "ffmpeg", 1319 - DSTR => sub { "$dopts -y -i %i %o" }, 1320 - }, 1321 - 1322 - avconv => { 1323 - NAME => 'avconv', 1324 - DSTR => sub { "$dopts -y -i %i %O" }, 1325 - }, 1326 - 1327 - mplayer => { 1328 - NAME => "mplayer", 1329 - DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 1330 - }, 1331 - 1332 - sox => { 1333 - NAME => "sox", 1334 - DSTR => sub { "%i $dopts %o" }, 1335 - }, 1336 - }, 1337 - 1338 - TAGS => { 1339 - READ => 1, 1340 - WRITE => 1, 1341 - MODULE => "MP3::Tag", 1342 - }, 1343 - }, 1344 - 1345 - mp3hd => { 1346 - 1347 - DEFAULT_ENCODER => "mp3hdEncoder", 1348 - DEFAULT_DECODER => "mp3hdDecoder", 1349 - 1350 - ENCODER => { 1351 - mp3hdEncoder => { 1352 - NAME => "mp3hdEncoder", 1353 - ESTR => sub { 1354 - $opts = "-br $bitrate" if $defopts == 1; 1355 - $opts = '' if $defopts == 0; 1356 - "$eopts $opts -if %i -of %o" 1357 - }, 1358 - PROMPT => { BITRATE => 1 }, 1359 - }, 1360 - }, 1361 - 1362 - DECODER => { 1363 - mp3hdDecoder => { 1364 - NAME => "mp3hdDecoder", 1365 - DSTR => sub { "$dopts -if %i -of %o" }, 1366 - }, 1367 - }, 1368 - 1369 - TAGS => { 1370 - WRITE => 1, 1371 - READ => 1, 1372 - MODULE => "MP3::Tag", 1373 - }, 1374 - }, 1375 - 1376 - mp4 => { 1377 - 1378 - DEFAULT_ENCODER => "faac", 1379 - DEFAULT_DECODER => "faad", 1380 - 1381 - ENCODER => { 1382 - 1383 - faac => { 1384 - NAME => "faac", 1385 - ESTR => sub { 1386 - $opts = "-q $aacqual" if $defopts == 1; 1387 - $opts = '' if $defopts == 0; 1388 - "$eopts -w $opts %i -o %o" 1389 - }, 1390 - PROMPT => { AACQUAL => 1 }, 1391 - }, 1392 - 1393 - ffmpeg => { 1394 - NAME => "ffmpeg", 1395 - ESTR => sub { 1396 - $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 1397 - $opts = '' if $defopts == 0; 1398 - "-y -i %i $eopts $opts %o" 1399 - }, 1400 - 1401 - PRIMPT => { 1402 - BITRATE => 1, 1403 - FREQ => 1, 1404 - CHANNELS => 1, 1405 - }, 1406 - }, 1407 - 1408 - avconv => { 1409 - NAME => 'avconv', 1410 - ESTR => sub { 1411 - $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 1412 - $opts = '' if $defopts == 0; 1413 - "-y -i %i $eopts $opts %o" 1414 - }, 1415 - 1416 - PROMPT => { 1417 - BITRATE => 1, 1418 - FREQ => 1, 1419 - CHANNELS => 1, 1420 - }, 1421 - }, 1422 - }, 1423 - 1424 - DECODER => { 1425 - 1426 - faad => { 1427 - NAME => "faad", 1428 - DSTR => sub { "$dopts -o %o %i" }, 1429 - }, 1430 - 1431 - ffmpeg => { 1432 - NAME => "ffmpeg", 1433 - DSTR => sub { "$dopts -y -i %i %o" }, 1434 - }, 1435 - 1436 - avconv => { 1437 - NAME => 'avconv', 1438 - DSTR => sub { "$dopts -y -i %i %o" }, 1439 - }, 1440 - 1441 - mplayer => { 1442 - NAME => "mplayer", 1443 - DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 1444 - }, 1445 - }, 1446 - 1447 - TAGS => { 1448 - READ => 1, 1449 - WRITE => 1, 1450 - MODULE => "Audio::Scan", 1451 - }, 1452 - }, 1453 - 1454 - m4a => { 1455 - 1456 - DEFAULT_ENCODER => "faac", 1457 - DEFAULT_DECODER => "faad", 1458 - 1459 - ENCODER => { 1460 - 1461 - faac => { 1462 - NAME => "faac", 1463 - ESTR => sub { 1464 - $opts = "-q $aacqual" if $defopts == 1; 1465 - $opts = '' if $defopts == 0; 1466 - "$eopts -w $opts %i -o %o" 1467 - }, 1468 - PROMPT => { AACQUAL => 1 }, 1469 - }, 1470 - 1471 - ffmpeg => { 1472 - NAME => "ffmpeg", 1473 - ESTR => sub { 1474 - $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 1475 - $opts = '' if $defopts == 0; 1476 - "$eopts -y -i %i $opts %o" 1477 - }, 1478 - 1479 - PROMPT => { 1480 - BITRATE => 1, 1481 - FREQ => 1, 1482 - CHANNELS => 1, 1483 - }, 1484 - }, 1485 - 1486 - avconv => { 1487 - NAME => 'avconv', 1488 - ESTR => sub { 1489 - $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 1490 - $opts = '' if $defopts == 0; 1491 - "-y -i %i $eopts $opts %o" 1492 - }, 1493 - 1494 - PROMPT => { 1495 - BITRATE => 1, 1496 - FREQ => 1, 1497 - CHANNELS => 1, 1498 - }, 1499 - }, 1500 - }, 1501 - 1502 - DECODER => { 1503 - 1504 - faad => { 1505 - NAME => "faad", 1506 - DSTR => sub { "$dopts -o %o %i" }, 1507 - }, 1508 - 1509 - ffmpeg => { 1510 - NAME => "ffmpeg", 1511 - DSTR => sub { "$dopts -y -i %i %o" }, 1512 - }, 1513 - 1514 - avconv => { 1515 - NAME => 'avconv', 1516 - DSTR => sub { "$dopts -y -i %i %o" }, 1517 - }, 1518 - 1519 - mplayer => { 1520 - NAME => "mplayer", 1521 - DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 1522 - }, 1523 - 1524 - }, 1525 - 1526 - ESTR => sub { "$eopts -w -q $aacqual %i -o %o" }, 1527 - 1528 - TAGS => { 1529 - READ => 1, 1530 - WRITE => 1, 1531 - MODULE => "Audio::Scan", 1532 - }, 1533 - }, 1534 - 1535 - m4b => { 1536 - 1537 - DEFAULT_ENCODER => undef, 1538 - DEFAULT_DECODER => "faad", 1539 - 1540 - DECODER => { 1541 - faad => { 1542 - NAME => "faad", 1543 - DSTR => sub { "$dopts -o %o %i" }, 1544 - }, 1545 - 1546 - mplayer => { 1547 - NAME => "mplayer", 1548 - DSTR => sub { "$dopts -vc null -vo null -ao pcm:file=%o %i" }, 1549 - }, 1550 - 1551 - ffmpeg => { 1552 - NAME => 'ffmpeg', 1553 - DSTR => sub { "$dopts -y -i %i %o" }, 1554 - }, 1555 - 1556 - avconv => { 1557 - NAME => 'avconv', 1558 - DSTR => sub { "$dopts -y -i %i %o" }, 1559 - }, 1560 - }, 1561 - 1562 - TAGS => { 1563 - READ => 0, 1564 - WRITE => 1, 1565 - MODULE => undef, 1566 - }, 1567 - }, 1568 - 1569 - mpc => { 1570 - 1571 - DEFAULT_ENCODER => "mpcenc", 1572 - DEFAULT_DECODER => "mpcdec", 1573 - 1574 - ENCODER => { 1575 - 1576 - mpcenc => { 1577 - NAME => "mpcenc", 1578 - ESTR => sub { 1579 - $opts = "--$mpcqual" if $defopts == 1; 1580 - $opts = '' if $defopts == 0; 1581 - "$eopts --overwrite $opts %i %o" 1582 - }, 1583 - PROMPT => { MPCQUAL => 1 }, 1584 - }, 1585 - }, 1586 - 1587 - DECODER => { 1588 - 1589 - mpcdec => { 1590 - NAME => "mpcdec", 1591 - DSTR => sub { "$dopts %i %o" }, 1592 - }, 1593 - 1594 - ffmpeg => { 1595 - NAME => 'ffmpeg', 1596 - DSTR => sub { "$dopts -y -i %i %o" }, 1597 - }, 1598 - 1599 - avconv => { 1600 - NAME => 'avconv', 1601 - DSTR => sub { "$dopts -y -i %i %o" }, 1602 - }, 1603 - 1604 - mplayer => { 1605 - NAME => "mplayer", 1606 - DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 1607 - }, 1608 - }, 1609 - 1610 - TAGS => { 1611 - READ => 1, 1612 - WRITE => 1, 1613 - MODULE => "Audio::Scan", 1614 - }, 1615 - 1616 - PROMPT => { 1617 - MPCQUAL => 1, 1618 - }, 1619 - }, 1620 - 1621 - mpp => { 1622 - 1623 - DEFAULT_ENCODER => "mpcenc", 1624 - DEFAULT_DECODER => "mpcdec", 1625 - 1626 - ENCODER => { 1627 - 1628 - mpcenc => { 1629 - NAME => "mpcenc", 1630 - ESTR => sub { 1631 - $opts = "--$mpcqual" if $defopts == 1; 1632 - $opts = '' if $defopts == 0; 1633 - "$eopts --overwrite $opts %i %o" 1634 - }, 1635 - PROMPT => { MPCQUAL => 1 }, 1636 - }, 1637 - }, 1638 - 1639 - DECODER => { 1640 - 1641 - mpcdec => { 1642 - NAME => "mpcdec", 1643 - DSTR => sub { "$dopts %i %o" }, 1644 - }, 1645 - 1646 - ffmpeg => { 1647 - NAME => 'ffmpeg', 1648 - DSTR => sub { "$dopts -y -i %i %o" }, 1649 - }, 1650 - 1651 - avconv => { 1652 - NAME => 'avconv', 1653 - DSTR => sub { "$dopts -y -i %i %o" }, 1654 - }, 1655 - 1656 - mplayer => { 1657 - NAME => "mplayer", 1658 - DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 1659 - }, 1660 - }, 1661 - 1662 - TAGS => { 1663 - READ => 1, 1664 - WRITE => 1, 1665 - MODULE => "Audio::Scan", 1666 - }, 1667 - }, 1668 - 1669 - off => { 1670 - DEFAULT_ENCODER => 'off', 1671 - DEFAULT_DECODER => 'off', 1672 - 1673 - ENCODER => { 1674 - off => { 1675 - NAME => 'off', 1676 - ESTR => sub { 1677 - $opts = "--mode $ofmode --optimize $ofopt" if $defopts == 1; 1678 - $opts = '' if $defopts == 0; 1679 - "$eopts --overwrite $opts %i --output %o" 1680 - }, 1681 - 1682 - PROMPT => { 1683 - OFMODE => 1, 1684 - OFOPT => 1, 1685 - }, 1686 - }, 1687 - }, 1688 - 1689 - DECODER => { 1690 - off => { 1691 - NAME => 'off', 1692 - DSTR => sub { "$dopts --overwrite --decode %i --output %o" }, 1693 - }, 1694 - }, 1695 - 1696 - TAGS => { 1697 - READ => 0, 1698 - WRITE => 0, 1699 - MODULE => undef, 1700 - }, 1701 - }, 1702 - 1703 - ofr => { 1704 - 1705 - DEFAULT_ENCODER => "ofr", 1706 - DEFAULT_DECODER => "ofr", 1707 - 1708 - ENCODER => { 1709 - ofr => { 1710 - NAME => "ofr", 1711 - ESTR => sub { 1712 - $opts = "--mode $ofmode --optimize $ofopt" if $defopts == 1; 1713 - $opts = '' if $defopts == 0; 1714 - "$eopts --overwrite $opts %i --output %o" 1715 - }, 1716 - 1717 - PROMPT => { 1718 - OFMODE => 1, 1719 - OFOPT => 1, 1720 - }, 1721 - }, 1722 - }, 1723 - 1724 - DECODER => { 1725 - ofr => { 1726 - NAME => "ofr", 1727 - DSTR => sub { "$dopts --overwrite --decode %i --output %o" }, 1728 - }, 1729 - }, 1730 - 1731 - TAGS => { 1732 - READ => 0, 1733 - WRITE => 0, 1734 - MODULE => undef, 1735 - }, 1736 - }, 1737 - 1738 - ofs => { 1739 - 1740 - DEFAULT_ENCODER => "ofs", 1741 - DEFAULT_DECODER => "ofs", 1742 - 1743 - ENCODER => { 1744 - ofs => { 1745 - NAME => "ofs", 1746 - ESTR => sub { 1747 - $opts = "--mode $ofmode --optimize $ofopt" if $defopts == 1; 1748 - $opts = '' if $defopts == 0; 1749 - "$eopts --overwrite $opts %i --output %o" 1750 - }, 1751 - 1752 - PROMPT => { 1753 - OFMODE => 1, 1754 - OFOPT => 1, 1755 - }, 1756 - }, 1757 - }, 1758 - 1759 - DECODER => { 1760 - ofs => { 1761 - NAME => "ofs", 1762 - DSTR => sub { "$dopts --overwrite --decode %i --output %o" }, 1763 - }, 1764 - }, 1765 - 1766 - TAGS => { 1767 - READ => 0, 1768 - WRITE => 0, 1769 - MODULE => undef, 1770 - }, 1771 - }, 1772 - 1773 - 1774 - oga => { 1775 - DEFAULT_ENCODER => 'oggenc', 1776 - DEFAULT_DECODER => 'oggdec', 1777 - 1778 - ENCODER => { 1779 - oggenc => { 1780 - NAME => 'oggenc', 1781 - ESTR => sub { 1782 - $opts = "--resample $freq -q $oggqual" if $defopts == 1; 1783 - $opts = '' if $defopts == 0; 1784 - "$eopts $opts %i %o" 1785 - }, 1786 - PROMPT => { 1787 - FREQ => 1, 1788 - OGGQUAL => 1, 1789 - }, 1790 - }, 1791 - 1792 - ffmpeg => { 1793 - NAME => "ffmpeg", 1794 - ESTR => sub { 1795 - $opts = "-ab $bitrate.k -ar $freq -ac $channels -codec:a libvorbis" if $defopts == 1; 1796 - $opts = '' if $defopts == 0; 1797 - "-y -i %i $eopts $opts %o" 1798 - }, 1799 - 1800 - PROMPT => { 1801 - BITRATE => 1, 1802 - FREQ => 1, 1803 - CHANNELS => 1, 1804 - }, 1805 - }, 1806 - 1807 - avconv => { 1808 - NAME => 'avconv', 1809 - ESTR => sub { 1810 - $opts = "-ab $bitrate.k -ar $freq -ac $channels -codec:a libvorbis" if $defopts == 1; 1811 - $opts = '' if $defopts == 0; 1812 - "-y -i %i $eopts $opts %o" 1813 - }, 1814 - 1815 - PROMPT => { 1816 - BITRATE => 1, 1817 - FREQ => 1, 1818 - CHANNELS => 1, 1819 - }, 1820 - }, 1821 - 1822 - sox => { 1823 - NAME => "sox", 1824 - ESTR => sub { 1825 - $opts = "-r $freq -c $channels" if $defopts == 1; 1826 - $opts = '' if $defopts == 0; 1827 - "%i $eopts $opts %o" 1828 - }, 1829 - 1830 - PROMPT => { 1831 - FREQ => 1, 1832 - CHANNELS => 1, 1833 - }, 1834 - }, 1835 - }, 1836 - 1837 - DECODER => { 1838 - oggdec => { 1839 - NAME => "oggdec", 1840 - DSTR => sub { "$dopts %i --output %o" }, 1841 - }, 1842 - 1843 - ffmpeg => { 1844 - NAME => "ffmpeg", 1845 - DSTR => sub { "$dopts -y -i %i %o" }, 1846 - }, 1847 - 1848 - avconv => { 1849 - NAME => 'avconv', 1850 - DSTR => sub { "$dopts -y -i %i %o" }, 1851 - }, 1852 - 1853 - mplayer => { 1854 - NAME => "mplayer", 1855 - DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 1856 - }, 1857 - 1858 - sox => { 1859 - NAME => "sox", 1860 - DSTR => sub { "%i $dopts %o" }, 1861 - }, 1862 - }, 1863 - 1864 - TAGS => { 1865 - READ => 1, 1866 - WRITE => 1, 1867 - MODULE => "vorbiscomment", 1868 - }, 1869 - }, 1870 - 1871 - ogg => { 1872 - 1873 - DEFAULT_ENCODER => "oggenc", 1874 - DEFAULT_DECODER => "oggdec", 1875 - 1876 - ENCODER => { 1877 - oggenc => { 1878 - NAME => "oggenc", 1879 - ESTR => sub { 1880 - $opts = "--resample $freq -q $oggqual" if $defopts == 1; 1881 - $opts = '' if $defopts == 0; 1882 - "$eopts $opts %i -o %o" 1883 - }, 1884 - 1885 - PROMPT => { 1886 - FREQ => 1, 1887 - OGGQUAL => 1, 1888 - }, 1889 - }, 1890 - 1891 - ffmpeg => { 1892 - NAME => "ffmpeg", 1893 - ESTR => sub { 1894 - $opts = "-ab $bitrate.k -ar $freq -ac $channels -codec:a libvorbis" if $defopts == 1; 1895 - $opts = '' if $defopts == 0; 1896 - "-y -i %i $eopts $opts %o" 1897 - }, 1898 - 1899 - PROMPT => { 1900 - BITRATE => 1, 1901 - FREQ => 1, 1902 - CHANNELS => 1, 1903 - }, 1904 - }, 1905 - 1906 - avconv => { 1907 - NAME => 'avconv', 1908 - ESTR => sub { 1909 - $opts = "-ab $bitrate.k -ar $freq -ac $channels -codec:a libvorbis" if $defopts == 1; 1910 - $opts = '' if $defopts == 0; 1911 - "-y -i %i $eopts $opts %o" 1912 - }, 1913 - 1914 - PROMPT => { 1915 - BITRATE => 1, 1916 - FREQ => 1, 1917 - CHANNELS => 1, 1918 - }, 1919 - }, 1920 - 1921 - sox => { 1922 - NAME => "sox", 1923 - ESTR => sub { 1924 - $opts = "-r $freq -c $channels" if $defopts == 1; 1925 - $opts = '' if $defopts == 0; 1926 - "%i $eopts $opts %o" 1927 - }, 1928 - 1929 - PROMPT => { 1930 - FREQ => 1, 1931 - CHANNELS => 1, 1932 - }, 1933 - }, 1934 - }, 1935 - 1936 - DECODER => { 1937 - oggdec => { 1938 - NAME => "oggdec", 1939 - DSTR => sub { "$dopts %i --output %o" }, 1940 - }, 1941 - 1942 - ffmpeg => { 1943 - NAME => "ffmpeg", 1944 - DSTR => sub { "$dopts -y -i %i %o" }, 1945 - }, 1946 - 1947 - avconv => { 1948 - NAME => 'avconv', 1949 - DSTR => sub { "$dopts -y -i %i %o" }, 1950 - }, 1951 - 1952 - mplayer => { 1953 - NAME => "mplayer", 1954 - DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 1955 - }, 1956 - 1957 - sox => { 1958 - NAME => "sox", 1959 - DSTR => sub { "%i $dopts %o" }, 1960 - }, 1961 - }, 1962 - 1963 - TAGS => { 1964 - READ => 1, 1965 - WRITE => 1, 1966 - MODULE => "vorbiscomment", 1967 - }, 1968 - }, 1969 - 1970 - opus => { 1971 - 1972 - DEFAULT_ENCODER => "opusenc", 1973 - DEFAULT_DECODER => "opusdec", 1974 - 1975 - ENCODER => { 1976 - opusenc => { 1977 - NAME => 'opusenc', 1978 - ESTR => sub { 1979 - $opts = "--bitrate $bitrate" if $defopts == 1; 1980 - $opts = '' if $defopts == 0; 1981 - "$eopts $opts %i %o" 1982 - }, 1983 - PROMTP => { 1984 - BITRATE => 1, 1985 - }, 1986 - }, 1987 - }, 1988 - 1989 - DECODER => { 1990 - opusdec => { 1991 - NAME => 'opusdec', 1992 - DSTR => sub { "--force-wav %i %o" }, 1993 - PROMPT => { NONE => 0 }, 1994 - }, 1995 - }, 1996 - 1997 - TAGS => { 1998 - READ => 0, 1999 - WRITE => 0, 2000 - MODULE => undef, 2001 - }, 2002 - }, 2003 - 2004 - raw => { 2005 - 2006 - DEFAULT_ENCODER => "sox", 2007 - DEFAULT_DECODER => "sox", 2008 - 2009 - ENCODER => { 2010 - sox => { 2011 - NAME => 'sox', 2012 - ESTR => sub { 2013 - $opts = "-r $freq -c $channels" if $defopts == 1; 2014 - $opts = '' if $defopts == 0; 2015 - "%i $opts $eopts %o $effect" 2016 - }, 2017 - 2018 - PROMPT => { 2019 - FREQ => 1, 2020 - CHANNELS => 1, 2021 - }, 2022 - }, 2023 - }, 2024 - 2025 - DECODER => { 2026 - sox => { 2027 - NAME => 'sox', 2028 - DSTR => sub { "-w -s -r $freq -c $channels $dopts %i %o" }, 2029 - }, 2030 - }, 2031 - 2032 - TAGS => { 2033 - READ => 0, 2034 - WRITE => 0, 2035 - MODULE => undef, 2036 - }, 2037 - }, 2038 - 2039 - rm => { 2040 - 2041 - DEFAULT_ENCODER => 'ffmpeg', 2042 - DEFAULT_DECODER => 'ffmpeg', 2043 - 2044 - ENCODER => { 2045 - ffmpeg => { 2046 - NAME => 'ffmpeg', 2047 - ESTR => sub { 2048 - $opts = "-ar $freq -ac $channels" if $defopts == 1; 2049 - $opts = '' if $defopts == 0; 2050 - "-y -i %i $eopts $opts %o" 2051 - }, 2052 - 2053 - PROMPT => { 2054 - FREQ => 1, 2055 - CHANNELS => 1, 2056 - }, 2057 - }, 2058 - 2059 - avconv => { 2060 - NAME => 'avconv', 2061 - ESTR => sub { 2062 - $opts = "-ar $freq -ac $channels" if $defopts == 1; 2063 - $opts = '' if $defopts == 0; 2064 - "-y -i %i $eopts $opts %o" 2065 - }, 2066 - 2067 - PROMPT => { 2068 - FREQ => 1, 2069 - CHANNELS => 1, 2070 - }, 2071 - }, 2072 - }, 2073 - 2074 - DECODER => { 2075 - mplayer => { 2076 - NAME => 'mplayer', 2077 - DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 2078 - }, 2079 - 2080 - ffmpeg => { 2081 - NAME => 'ffmpeg', 2082 - DSTR => sub { "$dopts -y -i %i %o" }, 2083 - }, 2084 - 2085 - avconv => { 2086 - NAME => 'avconv', 2087 - DSTR => sub { "$dopts -y -i %i %o" }, 2088 - }, 2089 - }, 2090 - 2091 - TAGS => { 2092 - READ => 0, 2093 - WRITE => 0, 2094 - MODULE => undef, 2095 - }, 2096 - }, 2097 - 2098 - shn => { 2099 - 2100 - DEFAULT_ENCODER => "shorten", 2101 - DEFAULT_DECODER => "shorten", 2102 - 2103 - ENCODER => { 2104 - shorten => { 2105 - NAME => "shorten", 2106 - ESTR => sub { 2107 - $opts = "-c $channels" if $defopts == 1; 2108 - $opts = '' if $defopts == 0; 2109 - "$eopts $opts %i %o" 2110 - }, 2111 - PROMPT => { CHANNELS => 1 }, 2112 - }, 2113 - }, 2114 - 2115 - DECODER => { 2116 - shorten => { 2117 - NAME => "shorten", 2118 - DSTR => sub { "-x %i %o" }, 2119 - }, 2120 - }, 2121 - 2122 - TAGS => { 2123 - READ => 0, 2124 - WRITE => 0, 2125 - MODULE => undef, 2126 - }, 2127 - }, 2128 - 2129 - spx => { 2130 - 2131 - DEFAULT_ENCODER => "speexenc", 2132 - DEFAULT_DECODER => "speexdec", 2133 - 2134 - ENCODER => { 2135 - speexenc => { 2136 - NAME => "speexenc", 2137 - ESTR => sub { 2138 - $opts = "--quality $spxqual" if $defopts == 1; 2139 - $opts = '' if $defopts == 0; 2140 - "$eopts $opts %i %o" 2141 - }, 2142 - PROMPT => { SPXQUAL => 1 }, 2143 - }, 2144 - 2145 - ffmpeg => { 2146 - NAME => 'ffmpeg', 2147 - ESTR => sub { 2148 - $opts = "--bitrate $bitrate.k" if $defopts == 1; 2149 - $opts = '' if $defopts == 0; 2150 - "-y -i %i $eopts $opts %o" 2151 - }, 2152 - 2153 - PROMPT => { 2154 - BITRATE => 1, 2155 - }, 2156 - }, 2157 - 2158 - avconv => { 2159 - NAME => 'avconv', 2160 - ESTR => sub { 2161 - $opts = "--bitrate $bitrate.k" if $defopts == 1; 2162 - $opts = '' if $defopts == 0; 2163 - "-y -i $eopts $opts %o" 2164 - }, 2165 - PROMPT => { 2166 - BITRATE => 1, 2167 - }, 2168 - }, 2169 - }, 2170 - 2171 - DECODER => { 2172 - speexdec => { 2173 - NAME => "speexdec", 2174 - DSTR => sub { "$dopts %i %o" }, 2175 - }, 2176 - 2177 - ffmpeg => { 2178 - NAME => 'ffmpeg', 2179 - DSTR => sub { "$dopts -y -i %i %o" }, 2180 - }, 2181 - 2182 - avconv => { 2183 - NAME => 'avconv', 2184 - DSTR => sub { "$dopts -y -i %i %o" }, 2185 - }, 2186 - }, 2187 - 2188 - TAGS => { 2189 - READ => 1, 2190 - WRITE => 1, 2191 - MODULE => undef, 2192 - }, 2193 - }, 2194 - 2195 - tta => { 2196 - 2197 - DEFAULT_ENCODER => "ttaenc", 2198 - DEFAULT_DECODER => "ttaenc", 2199 - 2200 - ENCODER => { 2201 - ttaenc => { 2202 - NAME => "ttaenc", 2203 - ESTR => sub { "$eopts -e %i -o %o" }, 2204 - PROMPT => { NONE => 0, }, 2205 - }, 2206 - }, 2207 - 2208 - DECODER => { 2209 - ttaenc => { 2210 - NAME => "ttaenc", 2211 - DSTR => sub { "$dopts -d %i -o %o" }, 2212 - }, 2213 - 2214 - ffmpeg => { 2215 - NAME => "ffmpeg", 2216 - DSTR => sub { "$dopts -y -i %i %o" }, 2217 - }, 2218 - 2219 - avconv => { 2220 - NAME => 'avconv', 2221 - DSTR => sub { "$dopts -y -i %i %o" }, 2222 - }, 2223 - 2224 - mplayer => { 2225 - NAME => "mplayer", 2226 - DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 2227 - }, 2228 - }, 2229 - 2230 - TAGS => { 2231 - READ => 0, 2232 - WRITE => 0, 2233 - MODULE => undef, 2234 - }, 2235 - }, 2236 - 2237 - wav => { 2238 - 2239 - DEFAULT_ENCODER => "mv", 2240 - DEFAULT_DECODER => "cp", 2241 - 2242 - ENCODER => { 2243 - mv => { 2244 - NAME => "mv", 2245 - ESTR => sub { "%i %o" }, 2246 - PROMPT => { NONE => 0, }, 2247 - }, 2248 - }, 2249 - 2250 - DECODER => { 2251 - cp => { 2252 - NAME => "cp", 2253 - DSTR => sub { "%i %o" }, 2254 - } 2255 - }, 2256 - 2257 - TAGS => { 2258 - READ => 0, 2259 - WRITE => 0, 2260 - MODULE => undef, 2261 - }, 2262 - }, 2263 - 2264 - wv => { 2265 - 2266 - DEFAULT_ENCODER => "wavpack", 2267 - DEFAULT_DECODER => "wvunpack", 2268 - 2269 - ENCODER => { 2270 - wavpack => { 2271 - NAME => "wavpack", 2272 - ESTR => sub { "$eopts -h -y %i -o %o" }, 2273 - PROMPT => { NONE => 0, }, 2274 - }, 2275 - 2276 - ffmpeg => { 2277 - NAME => 'ffmpeg', 2278 - ESTR => sub { "-y -i %i $eopts %o" }, 2279 - PROMPT => { NONE => 0, }, 2280 - }, 2281 - 2282 - avconv => { 2283 - NAME => 'avconv', 2284 - ESTR => sub { "-y -i %i $eopts %o" }, 2285 - PROMPT => { NONE => 0, }, 2286 - }, 2287 - }, 2288 - 2289 - DECODER => { 2290 - wvunpack => { 2291 - NAME => "wvunpack", 2292 - DSTR => sub { "$dopts -y %i -o %o" }, 2293 - }, 2294 - 2295 - ffmpeg => { 2296 - NAME => "ffmpeg", 2297 - DSTR => sub { "$dopts -y -i %i %o" }, 2298 - }, 2299 - 2300 - avconv => { 2301 - NAME => 'avconv', 2302 - DSTR => sub { "$dopts -y -i %i %o" }, 2303 - }, 2304 - 2305 - mplayer => { 2306 - NAME => "mplayer", 2307 - DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 2308 - }, 2309 - }, 2310 - 2311 - TAGS => { 2312 - READ => 1, 2313 - WRITE => 1, 2314 - MODULE => "Audio::Scan", 2315 - }, 2316 - }, 2317 -); 2318 - 2319 -# supported ffmpeg/avconv formats (decode only) 2320 -my @ffmpeg_codecs = ( "mmf", "ra", "wma" ); 2321 -my @ffmpeg_forks = ( "avconv", "ffmpeg" ); 2322 - 2323 -foreach my $fork (@ffmpeg_forks) { 2324 - 2325 - foreach my $codec (@ffmpeg_codecs) { 2326 - 2327 - $run{$codec}{DEFAULT_ENCODER} = $fork; 2328 - $run{$codec}{DEFAULT_DECODER} = $fork; 2329 - $run{$codec}{ENCODER}{$fork}{NAME} = $fork; 2330 - $run{$codec}{DECODER}{$fork}{NAME} = $fork; 2331 - $run{$codec}{DECODER}{$fork}{DSTR} = sub {"-y %i $dopts %o"}; 2332 - $run{$codec}{ENCODER}{$fork}{ESTR} = sub {"-y -i %i $eopts -ab $bitrate.k -ar $freq -ac $channels %o"}; 2333 - $run{$codec}{TAGS}{READ} = 0; 2334 - $run{$codec}{TAGS}{WRITE} = 0; 2335 - $run{$codec}{TAGS}{MODULE} = undef; 2336 - } 2337 - 2338 -} 2339 - 2340 -# support reading of WMA tags via Audio::Scan 2341 -$run{wma}{TAGS}{READ} = 1; 2342 -$run{wma}{TAGS}{MODULE} = "Audio::Scan"; 2343 - 2344 -# supported video to audio types 2345 -my @movie_codecs = ( 2346 - "rv", "asf", "avi", "divx", 2347 - "mkv", "mpg", "mpeg", "mov", 2348 - "ogm", "qt", "vcd", "vob", 2349 - "wmv", "flv", "svcd", "m4v", 2350 - "nsv", "nuv", "psp", "smk", 2351 - "ogv", "webm", 2352 - 2353 - # decode only audio formats 2354 - "vqf", "tak", 2355 - ); 2356 - 2357 -foreach (@movie_codecs) { 2358 - $run{$_}{DEFAULT_ENCODER} = undef; 2359 - $run{$_}{DEFAULT_DECODER} = "ffmpeg"; 2360 - $run{$_}{DECODER}{mplayer}{NAME} = "mplayer"; 2361 - $run{$_}{DECODER}{ffmpeg}{NAME} = "ffmpeg"; 2362 - $run{$_}{DECODER}{mplayer}{DSTR} = sub { "$dopts -vc null -vo null -ao pcm:file=%o %i" }; 2363 - $run{$_}{DECODER}{ffmpeg}{DSTR} = sub { "$dopts -i %i %o"; }; 2364 - $run{$_}{TAGS}{READ} = 0; 2365 - $run{$_}{TAGS}{WRITE} = 0; 2366 - $run{$_}{TAGS}{MODULE} = undef; 2367 -} 2368 - 2369 -# supported sndfile-convert formats 2370 -my @sndfile = ( 2371 - "pvf", "caf", "sf", "paf", "fap", "sd2", 2372 - "mat4", "mat5", "mat", "ircam", "w64", "nist", 2373 - "rf64", 2374 - ); 2375 - 2376 -foreach (@sndfile) { 2377 - 2378 - $run{$_}{DEFAULT_ENCODER} = "sndfile-convert"; 2379 - $run{$_}{DEFAULT_DECODER} = "sndfile-convert"; 2380 - $run{$_}{ENCODER}{"sndfile-convert"}{NAME} = "sndfile-convert"; 2381 - $run{$_}{DECODER}{"sndfile-convert"}{NAME} = "sndfile-convert"; 2382 - $run{$_}{ENCODER}{"sndfile-convert"}{ESTR} = sub { "$eopts %i %o" }; 2383 - $run{$_}{DECODER}{"sndfile-convert"}{DSTR} = sub { "$dopts %i %o" }; 2384 - $run{$_}{TAGS}{READ} = 0; 2385 - $run{$_}{TAGS}{WRITE} = 0; 2386 - $run{$_}{TAGS}{MODULE} = undef; 2387 -} 2388 - 2389 -# supported sox formats 2390 -my @sox_codecs = ( 2391 - "aiff", "aif", "au", "snd", "voc", 2392 - "smp", "avr", "cdr", "8svx", "amb", 2393 - "dat", "dvms", "f32", "f64", "fssd", 2394 - "gsrt", "hcom", "txw", "vms", "al", 2395 - "sou", "ima", "prc", "cvu", 2396 - "maud", 2397 - ); 2398 - 2399 -foreach (@sox_codecs) { 2400 - 2401 - $run{$_}{DEFAULT_ENCODER} = "sox"; 2402 - $run{$_}{DEFAULT_DECODER} = "sox"; 2403 - $run{$_}{ENCODER}{sox}{NAME} = "sox"; 2404 - $run{$_}{DECODER}{sox}{NAME} = "sox"; 2405 - $run{$_}{ENCODER}{sox}{ESTR} = sub { "%i -r $freq -c $channels $eopts %o $effect" }; 2406 - $run{$_}{DECODER}{sox}{DSTR} = sub { "%i $dopts %o" }; 2407 - $run{$_}{TAGS}{READ} = 0; 2408 - $run{$_}{TAGS}{WRITE} = 0; 2409 - $run{$_}{TAGS}{MODULE} = undef; 2410 - 2411 - $run{$_}{ENCODER}{sox}{PROMPT}{FREQ} = 1; 2412 - $run{$_}{ENCODER}{sox}{PROMPT}{CHANNELS} = 1; 2413 - 2414 -} 2415 - 2416 -# load codecs.conf file 2417 -load_codecs() if -e $codecs_conf; 2418 - 2419 -my $out_name = $outfile; 2420 -my $out_dir = $outdir; 2421 -my $first_message = 1; 2422 -my %files; 2423 -my $number = 0; 2424 - 2425 -# process all files and directories 2426 -sub proc_input { 2427 - 2428 - $to =~ tr/A-Z/a-z/; 2429 - 2430 - perror("bad_input","") unless(exists($run{$to})); 2431 - 2432 - proc_preserve_dir($dir[0]) if @dir and $preserve; # process recursive directory preservation (sends to proc_files 2433 - proc_dirs() if @dir and not $preserve; # process directories including recursively (sends to proc_files) 2434 - proc_files() if @file; # process all files 2435 - fork_files(); # start the conversion process. 2436 -} 2437 - 2438 -# process all files (all roads lead to rome) 2439 -sub proc_files { 2440 - 2441 - if (@file) { 2442 - 2443 - foreach my $i (sort(@file)) { 2444 - 2445 - my ($file, $dir, $ext) = fileparse("$i", qr/\.[^.]*/); 2446 - 2447 - $ext =~ s/^\.//; 2448 - $dir = rel2abs($dir); 2449 - $outdir = $dir if not defined($out_dir) and not $preserve; 2450 - $outdir = $out_dir if $preserve; 2451 - 2452 - my $if = $ext; 2453 - $if =~ tr/A-Z/a-z/; 2454 - 2455 - $only =~ tr/A-Z/a-z/ if $only; 2456 - 2457 - next if $only and $if ne $only; 2458 - 2459 - $encoder = $my_encoder if defined($my_encoder); 2460 - $decoder = $my_decoder if defined($my_decoder); 2461 - 2462 - $encoder = $run{$to}{DEFAULT_ENCODER} if not $my_encoder; 2463 - $decoder = $run{$if}{DEFAULT_DECODER} if not $my_decoder; 2464 - 2465 - if (-e "$file.$to" and not $overwrite) { 2466 - pnotice("overwrite","$file.$to",1); 2467 - $total_failed++; 2468 - next; 2469 - } 2470 - 2471 - if (check_input($file,$dir,$if) == 0) { 2472 - 2473 - pnotice("unk_encoder","$file.$ext",1), next unless(exists($run{$to}{ENCODER}{$encoder})); 2474 - pnotice("unk_decoder","$file.$ext",1), next unless(exists($run{$if}{DECODER}{$decoder})); 2475 - 2476 - get_visual_opts($to,$outdir) if $gui and not defined($first_run); 2477 - 2478 - $first_run = 1; 2479 - 2480 - perror("multi_out","") if (defined($out_name) and $#file gt 0 or defined($out_name) and @dir); 2481 - perror("no_outdir","") if (not -e $outdir and not -d $outdir); 2482 - 2483 - $outfile = "$file" if not $out_name; 2484 - 2485 - if ($keep and $if eq $to) { 2486 - system("cp -v \"$dir/$file.$ext\" \"$outdir/$outfile.$ext\"") if $outdir ne $dir and not -e "$outdir/$outfile.$ext"; 2487 - next if $outdir eq $dir; 2488 - } 2489 - 2490 - else { 2491 - $files{"FILE$number"}{FILE} = "$dir/$file"; 2492 - $files{"FILE$number"}{OUTF} = "$outdir/$outfile"; 2493 - $files{"FILE$number"}{EXT} = "$ext"; 2494 - $files{"FILE$number"}{NAME} = "$file"; 2495 - $files{"FILE$number"}{OUTD} = "$outfile"; 2496 - $files{"FILE$number"}{DECODER} = "$decoder"; 2497 - 2498 - $number++; 2499 - } 2500 - 2501 - } 2502 - } 2503 - } 2504 - undef(@file); 2505 -} 2506 - 2507 -# process directories and push all to @file arrary 2508 -sub proc_dirs { 2509 - 2510 - if (@dir) { 2511 - 2512 - my @tmp_dir = @dir; 2513 - undef(@dir); 2514 - $topdir = $tmp_dir[0]; 2515 - 2516 - if (not $recursive) { 2517 - 2518 - undef(@file); 2519 - 2520 - foreach my $d (@tmp_dir) { 2521 - 2522 - opendir(DIR, "$d") or perror("opening_dir","$d: $!"); 2523 - my @dir_files = readdir(DIR); 2524 - closedir(DIR); 2525 - perror("empty_dir","$d") if $#dir_files <= 1; 2526 - 2527 - foreach my $f (@dir_files) { 2528 - 2529 - if (not -d $f and not -d "$d/$f") { 2530 - push(@file, "$d/$f"); 2531 - undef($out_name); 2532 - } 2533 - } 2534 - } 2535 - 2536 - proc_files(); 2537 - return 0; 2538 - 2539 - } 2540 - 2541 - elsif ($recursive) { 2542 - 2543 - if (not $preserve) { 2544 - 2545 - undef(@file); 2546 - 2547 - foreach my $r (@tmp_dir) { 2548 - 2549 - $r = rel2abs($r); 2550 - 2551 - find ( sub { 2552 - my $rfile = $File::Find::name; 2553 - push(@file, $rfile) if not -d $rfile; 2554 - }, $r 2555 - ); 2556 - } 2557 - 2558 - proc_files(); 2559 - return 0; 2560 - 2561 - } 2562 - } 2563 - 2564 - } 2565 -} 2566 - 2567 -# preserve directory structuer (revised 10-7-2013) 2568 -my $out_dir_original = rel2abs($outdir) if $outdir and -d $outdir; 2569 - 2570 -sub proc_preserve_dir { 2571 - 2572 -$topdir = rel2abs($dir[0]); 2573 - 2574 -perror("no_outdir","") if not defined($out_dir_original); 2575 -perror("no_outdir","") if not -d $out_dir_original; 2576 - 2577 -undef(@file); # clear the array before we begin. 2578 - 2579 -find ( sub { 2580 - my $val = $File::Find::name; 2581 - $val =~ s/(\$)/\\\$/g; 2582 - 2583 - if ($val ne $topdir) { 2584 - 2585 - $val =~ s/$topdir\///; 2586 - 2587 - # create mirrored directories in output directory 2588 - if (not -f fileparse("$topdir/$val") and not -d "$out_dir_original/$val") { 2589 - say "creating directory $out_dir_original/$val" if not -f "$topdir/$val" and $verbose; 2590 - mkdir("$out_dir_original/$val", 0755) if not -f "$topdir/$val"; 2591 - } 2592 - 2593 - # this will list all files in their original directories 2594 - if (-f "$topdir/$val") { 2595 - say "$lang{debug} pushing to \@file: $topdir/$val" if $debug == 1; 2596 - push(@file, "$topdir/$val"); 2597 - } 2598 - 2599 - # set $out_dir to the 2600 - $out_dir = "$out_dir_original/" . dirname($val) if -f "$topdir/$val"; 2601 - 2602 - # send file, and output dir to proc_files(); 2603 - proc_files(); 2604 - } 2605 - 2606 - }, $topdir 2607 - ); 2608 -} 2609 - 2610 -# convert input to destination format 2611 -sub convert { 2612 - 2613 - my ($inf, $outf, $infmt, $iname, $oname, $dec) = @_; 2614 - 2615 - my $if = $infmt; 2616 - $if =~ tr/A-Z/a-z/; 2617 - 2618 - clear_tag_hash() if not $rip; 2619 - 2620 - # catch ^C. will have to be pressed repeatedly to exit the process. 2621 - $SIG{INT} = sub { 2622 - unlink("$outf.$$.wav"); 2623 - kill 9, $$; 2624 - }; 2625 - 2626 - # check to see if encoder/decoder exists. if not, see if we have one 2627 - # that supports the desired input/output formats. 2628 - $decoder = $dec; 2629 - check_encoder(); 2630 - check_decoder($infmt); 2631 - 2632 - my $decode_string = $run{$if}{DECODER}{$decoder}{DSTR}->(); 2633 - $decode_string =~ s/%i/\"$inf.$infmt\"/; 2634 - $decode_string =~ s/%o/\"$outf.$$.wav\"/; 2635 - $decode_string =~ s/(\$|\\)/\\$1/g; 2636 - 2637 - pnotice("debug","\n$run{$if}{DECODER}{$decoder}{NAME} $decode_string", 2) if $dryrun; 2638 - 2639 - # decode input file to temporary wav 2640 - system("$run{$if}{DECODER}{$decoder}{NAME} $decode_string $silent") if not $dryrun; 2641 - 2642 - # remove temporary wav file and die if decode fails 2643 - if ($? > 0) { 2644 - unlink("$outf.$$.wav") if -e "$outf.$$.wav"; 2645 - say ""; 2646 - $banner = 0; 2647 - pnotice("decode_failed","$inf.$infmt: try with --verbose",1); 2648 - return 1; 2649 - } 2650 - 2651 - # normalize wav file before encoding to output format 2652 - perror("no_app","normalize") if $normalize and not `which normalize 2>/dev/null`; 2653 - system("normalize $nopts \"$outf.$$.wav\"") if $normalize; 2654 - 2655 - # copy meta-data from input file to %tag_name 2656 - read_tags("$inf.$infmt", "$if") if $run{$if}{TAGS}{READ} == 1 and not $dryrun; 2657 - 2658 - my $tag_opts = format_tags($to); # tag options for mp4/m4a/m4b/mpc/mpp/bonk/spx/wv 2659 - 2660 - my $encode_string = $run{$to}{ENCODER}{$encoder}{ESTR}->(); 2661 - $encode_string =~ s/%i/$tag_opts \"$outf.$$.wav\"/ if $to =~ /mpc|mpp|mp4|m4a/ and $encoder eq "faac" or $encoder eq "mpcenc"; 2662 - $encode_string =~ s/%i/\"$outf.$$.wav\" $tag_opts/ if $to =~ /mpc|mpp|mp4|m4a/ and $encoder eq "ffmpeg" or $encoder eq "avconv"; 2663 - $encode_string =~ s/%i/\"$outf.$$.wav\"/ if $to !~ /mpc|mpp|mp4|m4a/; 2664 - $encode_string =~ s/%o/$tag_opts \"$outf.$to\"/ if $tag_opts ne " " and $to !~ /mpc|mpp|mp4|m4a/; 2665 - $encode_string =~ s/%o/\"$outf.$to\"/ if $tag_opts eq " " or $to =~ /mpc|mpp|mp4|m4a/; 2666 - $encode_string =~ s/(\$|\\)/\\$1/g; 2667 - 2668 - # read tag options from command line if present 2669 - get_user_tags(); 2670 - 2671 - pnotice("debug","\n$run{$to}{ENCODER}{$encoder}{NAME} $encode_string", 2) if $dryrun; 2672 - 2673 - # encode temporary WAV to desired output format. 2674 - system("$run{$to}{ENCODER}{$encoder}{NAME} $encode_string $silent") if not $dryrun; 2675 - 2676 - # remove partially encoded output file and temporary wav if encoding fails 2677 - if ($? > 0) { 2678 - unlink("$outf.$to") if -e "$outf.$to"; 2679 - unlink("$outf.$$.wav") if -e "$outf.$$.wav"; 2680 - say ""; 2681 - $banner = 0; 2682 - pnotice("encode_failed","$outf.$to: $?",1); 2683 - return 1; 2684 - } 2685 - 2686 - # write meta-data to output file from %tag_name hash 2687 - write_tags("$outf.$to", "$to") if $run{$to}{TAGS}{WRITE} == 1 and $tag_opts eq " " and not $dryrun; 2688 - 2689 - unlink("$outf.$$.wav") if not $dryrun; 2690 - unlink("$inf.$infmt") if $delete and not $dryrun; 2691 - 2692 - pnotice("removed_tmp","$outf.$$.wav","2") if $verbose; 2693 - pnotice("removed_src","$inf.$infmt", "2") if $delete and $verbose; 2694 -} 2695 - 2696 -$pm->run_on_finish 2697 -( sub { 2698 - my $pid = shift; 2699 - my $exit_code = shift; 2700 - my $ident = shift; 2701 - 2702 - if (-e "$ident.$to") { 2703 - $total_converted++; 2704 - } 2705 - say "$lang{debug} PID: $pid EXIT_CODE: $exit_code IDENTITY: \"$ident.$to\"" if $debug == 1; 2706 - } 2707 -); 2708 - 2709 -# convert all files that have been placed in the %files hash through various procs* 2710 -sub fork_files { 2711 - 2712 - say "\n$name - $version\n" if not $gui and $banner == 1; 2713 - 2714 - foreach (sort(keys(%files))) 2715 - { 2716 - $pm->start($files{$_}{OUTF}) and next; 2717 - my $msg = "$lang{converting}" . " " . basename($files{$_}{FILE}) . ".$files{$_}{EXT} -> $to"; 2718 - say "$msg" if not $gui; 2719 - system("kdialog --icon $icon_path --title \"$name\" --passivepopup \"$msg\" 10 &") if $gui and $kde; 2720 - system("notify-send \"$name\" \"$msg\" -t 35 -i $icon_path &") if $gui and $gnome; 2721 - convert("$files{$_}{FILE}","$files{$_}{OUTF}","$files{$_}{EXT}","$files{$_}{NAME}","$files{$_}{OUTD}","$files{$_}{DECODER}"); 2722 - $pm->finish; 2723 - } 2724 - 2725 - $pm->wait_all_children; 2726 - $total_failed = $number - $total_converted if $total_converted < $number; 2727 - 2728 - my $finished_msg = "\n$lang{total_converted} $total_converted, $lang{failed} $total_failed\n"; 2729 - 2730 - say "$finished_msg" if not $gui; 2731 - system("kdialog --icon $icon_path --title \"$name\" --passivepopup \"$finished_msg\" 10 &") if $gui and $kde; 2732 - system("notify-send \"$name\" \"$finished_msg\" -t 35 -i $icon_path &") if $gui and $gnome; 2733 - 2734 -} 2735 - 2736 -# if the default encoder does not exist, cycle through the supported 2737 -# encoders until we find one that does. 2738 -sub check_encoder { 2739 - 2740 - if (not `which $encoder 2>/dev/null`) { 2741 - my $first_encoder = $encoder; 2742 - foreach (keys %{$run{$to}{ENCODER}}) { $encoder = $_ and return if `which $_ 2>/dev/null`; } 2743 - perror("no_encode_app","$to") if $encoder eq $first_encoder; 2744 - } 2745 - 2746 - else { return 0; } 2747 -} 2748 - 2749 -# if the default decoder does not exist, cycle through the supported 2750 -# decoders until we find one that does. 2751 -sub check_decoder { 2752 - 2753 - my $from = shift; 2754 - 2755 - if (not `which $decoder 2>/dev/null`) { 2756 - my $first_decoder = $decoder; 2757 - foreach (keys %{$run{$from}{DECODER}}) { $decoder = $_ and return if `which $_ 2>/dev/null`; } 2758 - perror("no_decode_app","$from") if $decoder eq $first_decoder; 2759 - } 2760 - 2761 - else { return 0; } 2762 -} 2763 - 2764 -# make sure encoding/decoding is supported. 2765 -sub check_input { 2766 - 2767 - my $file = shift; 2768 - my $dir = shift; 2769 - my $ext = shift; 2770 - 2771 - perror("no_encoder","$to") unless(defined($run{$to}{ENCODER})); 2772 - 2773 - unless(defined($run{$ext}{DECODER})) { 2774 - pnotice("no_decoder","$ext",2) if $verbose or not $only; 2775 - $total_failed++; 2776 - return 1; 2777 - } 2778 - 2779 - return 0; 2780 -} 2781 - 2782 -######################################## 2783 -# GUI options for KDE & Gnome Plugins # 2784 -######################################## 2785 - 2786 -my $kdialog = "kdialog --title \"$name\""; 2787 -my $zenity = "zenity --title \"$name\" --list --radiolist --width 100 --height 300 --column '' --column "; 2788 - 2789 -sub get_visual_opts { 2790 - 2791 - my ($to_fmt,$od) = @_; 2792 - 2793 - # escape illegal characters in output directory name 2794 - $od =~ s/('|\(|\)|"|\\)/\\$1/g; 2795 - 2796 - $outdir = `kdialog --getexistingdirectory $od` if $config{KDE_DIR} == 1 and $kde; 2797 - $outdir = `zenity --title \"$lang{gui_outdir}\" --file-selection --directory --filename=\`pwd\`` if $config{ZEN_DIR} == 1 and $gnome; 2798 - 2799 - chomp($outdir); 2800 - $out_dir = $outdir; 2801 - exit(1) if not $outdir; 2802 - 2803 - if ($config{KDE_OPTS} == 1 or $config{ZEN_OPTS} == 1) { 2804 - foreach (keys %{$run{$to_fmt}{ENCODER}{$encoder}{PROMPT}}) { 2805 - prompt_user($_); 2806 - } 2807 - } 2808 -} 2809 - 2810 -sub prompt_user { 2811 - 2812 - my $opt = shift; 2813 - 2814 - given ($opt) { 2815 - 2816 - when (/^BITRATE/) { 2817 - $bitrate = `$kdialog --default $bitrate --combobox \"$lang{gui_bitrate}\" 56 112 128 160 192 256 320` if $kde; 2818 - $bitrate = `$zenity \"$lang{gui_bitrate}\" FALSE 56 FALSE 112 FALSE 128 FALSE 160 TRUE 192 FALSE 256 FALSE 320` if $gnome; 2819 - chomp($bitrate); 2820 - exit(1) if not $bitrate; 2821 - } 2822 - 2823 - when (/^FREQ/) { 2824 - $freq = `$kdialog --default $freq --combobox \"$lang{gui_freq}\" 32000 44100 48000` if $kde; 2825 - $freq = `$zenity \"$lang{gui_freq}\" FALSE 32000 TRUE 44100 FALSE 48000` if $gnome; 2826 - chomp($freq); 2827 - exit(1) if not $freq; 2828 - } 2829 - 2830 - when (/^CHANNELS/) { 2831 - $channels = `$kdialog --default $channels --combobox \"$lang{gui_chans}\" 1 2` if $kde; 2832 - $channels = `$zenity \"$lang{gui_chans}\" FALSE 1 TRUE 2` if $gnome; 2833 - chomp($channels); 2834 - exit(1) if not $channels; 2835 - } 2836 - 2837 - when (/^FCOMP/) { 2838 - $fcomp = `$kdialog --default $fcomp --combobox \"$lang{gui_fcomp}\" 0 1 2 3 4 5 6 7 8` if $kde; 2839 - $fcomp = `$zenity \"$lang{gui_fcomp}\" FALSE 0 FALSE 1 TRUE 2 FALSE 3 FALSE 4 FALSE 5 FALSE 6 FALSE 7 FALSE 8` if $gnome; 2840 - chomp($fcomp); 2841 - exit(1) if not $fcomp; 2842 - } 2843 - 2844 - when (/^ACOMP/) { 2845 - $acomp = `$kdialog --default $acomp --combobox \"$lang{gui_acomp}\" 1000 2000 3000 4000 5000` if $kde; 2846 - $acomp = `$zenity \"$lang{gui_acomp}\" FALSE 1000 FALSE 2000 TRUE 3000 FALSE 4000 FALSE 5000` if $gnome; 2847 - chomp($acomp); 2848 - exit(1) if not $acomp; 2849 - } 2850 - 2851 - when (/^OGGQUAL/) { 2852 - $oggqual = `$kdialog --default $oggqual --combobox \"$lang{gui_oggqual}\" 0 1 2 3 4 5 6 7 8 9 10` if $kde; 2853 - $oggqual = `$zenity \"$lang{gui_oggqual}\" FALSE 0 FALSE 1 FALSE 2 TRUE 3 FALSE 4 FALSE 5 FALSE 6 FALSE 7 FALSE 8 FALSE 9 FALSE 10` if $gnome; 2854 - chomp($oggqual); 2855 - exit(1) if not $oggqual; 2856 - } 2857 - 2858 - when (/^SPXQUAL/) { 2859 - $spxqual = `$kdialog --default $spxqual --combobox \"$lang{gui_spxqual}\" 0 1 2 3 4 5 6 7 8 9 10` if $kde; 2860 - $spxqual = `$zenity \"$lang{gui_spxqual}\" FALSE 0 FALSE 1 FALSE 2 FALSE 3 FALSE 4 FALSE 5 FALSE 6 FALSE 7 TRUE 8 FALSE 9 FALSE 10` if $gnome; 2861 - chomp($spxqual); 2862 - exit(1) if not $spxqual; 2863 - } 2864 - 2865 - when (/^AACQUAL/) { 2866 - $aacqual = `$kdialog --default $aacqual --combobox \"$lang{gui_aacqual}\" 100 200 300 400 500` if $kde; 2867 - $aacqual = `$zenity \"$lang{gui_aacqual}\" TRUE 100 FALSE 200 FALSE 300 FALSE 400 FALSE 500` if $gnome; 2868 - chomp($aacqual); 2869 - exit(1) if not $aacqual; 2870 - } 2871 - 2872 - when (/^MPCQUAL/) { 2873 - $mpcqual = `$kdialog --default $mpcqual --combobox \"$lang{gui_mpcqual}\" thumb radio standard xtreme insane braindead` if $kde; 2874 - $mpcqual = `$zenity \"$lang{gui_mpcqual}\" FALSE thumb TRUE radio FALSE standard FALSE xtreme FALSE insane FALSE braindead` if $gnome; 2875 - chomp($mpcqual); 2876 - exit(1) if not $mpcqual; 2877 - } 2878 - 2879 - when (/^OFMODE/ ) { 2880 - $ofmode = `$kdialog --default $ofmode --combobox \"$lang{gui_ofmode}\" fast normal high extra best highnew extranew bestnew` if $kde; 2881 - $ofmode = `$zenity \"$lang{gui_ofmode}\" FALSE fast TRUE normal FALSE high FALSE extra FALSE best FALSE highnew FALSE extranew FALSE bestnew` if $gnome; 2882 - chomp($ofmode); 2883 - exit(1) if not $ofmode; 2884 - } 2885 - 2886 - when (/^OFOPT/) { 2887 - $ofopt = `$kdialog --default $ofopt --combobox \"$lang{gui_ofopt}\" none fast normal high best` if $kde; 2888 - $ofopt = `$zenity \"$lang{gui_ofopt}\" FALSE none TRUE fast FALSE normal FALSE high FALSE best` if $gnome; 2889 - chomp($ofopt); 2890 - exit(1) if not $ofopt; 2891 - } 2892 - 2893 - when (/^BRATIO/) { 2894 - $bratio = `$kdialog --default $bratio --combobox \"$lang{gui_bratio}\" 1 2 3 4 5` if $kde; 2895 - $bratio = `$zenity \"$lang{gui_bratio}\" FALSE 1 TRUE 2 FALSE 3 FALSE 4 FALSE 5` if $gnome; 2896 - chomp($bratio); 2897 - exit(1) if not $bratio; 2898 - } 2899 - 2900 - when (/^BQUANL/) { 2901 - $bquanl = `$kdialog --default $bquanl --combobox \"$lang{gui_bquanl}\" 1.00 1.25 1.50 1.75 2.00` if $kde; 2902 - $bquanl = `$zenity \"$lang{gui_bquanl}\" TRUE 1.00 FALSE 1.25 FALSE 1.50 FALSE 1.75 FALSE 2.00` if $gnome; 2903 - chomp($bquanl); 2904 - exit(1) if not $bquanl; 2905 - } 2906 - 2907 - when (/^BPSIZE/) { 2908 - $bpsize = `$kdialog --default $bpsize --combobox \"$lang{gui_bpsize}\" 10 128` if $kde; 2909 - $bpsize = `$zenity \"$lang{gui_bpsize}\" FALSE 10 TRUE 128` if $gnome; 2910 - chomp($bpsize); 2911 - exit(1) if not $bpsize; 2912 - } 2913 - 2914 - default { return 0; } 2915 - } 2916 - 2917 -} 2918 - 2919 -# all copied tags will be stored here for furture use 2920 -my %tag_name = 2921 -( 2922 - title => undef, 2923 - track => undef, 2924 - artist => undef, 2925 - album => undef, 2926 - comment => undef, 2927 - year => undef, 2928 - genre => undef, 2929 -); 2930 - 2931 -# override tags read from input file if any of the tagging 2932 -# options are specified by the user during conversion. 2933 -sub get_user_tags 2934 -{ 2935 - $tag_name{title} = $title if $title; 2936 - $tag_name{track} = $track if $track; 2937 - $tag_name{artist} = $artist if $artist; 2938 - $tag_name{album} = $album if $album; 2939 - $tag_name{comment} = $comment if $comment; 2940 - $tag_name{year} = $year if $year; 2941 - $tag_name{genre} = $genre if $genre; 2942 -} 2943 - 2944 -# the formats MP4/M4A/M4B/MPC/MPP/WV/BONK have no tag writing module. 2945 -# tags therefore have to be written during encode via various 2946 -# command line args. 2947 -sub format_tags { 2948 - 2949 - my $type = shift; 2950 - 2951 - given ($type) { 2952 - 2953 - when (/^mp4$|^m4a$|^m4b$/) { 2954 - 2955 - if ($run{$to}{ENCODER}{$encoder}{NAME} eq "ffmpeg" or $run{$to}{ENCODER}{$encoder}{NAME} eq "avconv") { 2956 - 2957 - $tag_name{track} = 0 if not $tag_name{track}; 2958 - $tag_name{year} = 0 if not $tag_name{year}; 2959 - 2960 - return "-metadata TITLE=\"$tag_name{title}\" -metadata TRACK=\"$tag_name{track}\" -metadata ARTIST=\"$tag_name{artist}\" -metadata ALBUM=\"$tag_name{album}\" -metadata COMMENT=\"$tag_name{comment}\" -metadata YEAR=\"$tag_name{year}\" -metadata GENRE=\"$tag_name{genre}\""; 2961 - 2962 - } else { 2963 - 2964 - return "--title \"$tag_name{title}\" --track \"$tag_name{track}\" --artist \"$tag_name{artist}\" --album \"$tag_name{album}\" --comment \"$tag_name{comment}\" --year \"$tag_name{year}\" --genre \"$tag_name{genre}\""; 2965 - 2966 - } 2967 - } 2968 - 2969 - when (/^mpc$|^mpp$/) { return "--artist \"$tag_name{artist}\" --title \"$tag_name{title}\" --album \"$tag_name{album}\" --track \"$tag_name{track}\" --genre \"$tag_name{genre}\" --year \"$tag_name{year}\" --comment \"$tag_name{comment}\""; } 2970 - when (/^wv$/) { return "-w \"Title=$tag_name{title}\" -w \"Track=$tag_name{track}\" -w \"Artist=$tag_name{artist}\" -w \"Album=$tag_name{album}\" -w \"Comment=$tag_name{comment}\" -w \"Year=$tag_name{year}\" -w \"Genre=$tag_name{genre}\""; } 2971 - when (/^bonk$/) { return "-t \"$tag_name{title}\" -a \"$tag_name{artist}\" -c \"$tag_name{comment}\""; } 2972 - when (/^spx$/) { return "--author \"$tag_name{artist}\" --title \"$tag_name{title}\" --comment \"year=$tag_name{year}\" --comment \"tracknumber=$tag_name{track}\" --comment \"album=$tag_name{album}\" --comment \"genre=$tag_name{genre}\" --comment \"comment=$tag_name{comment}\""; } 2973 - 2974 - default { return " "; } 2975 - } 2976 -} 2977 - 2978 -# meta-data is read based on input file extension. 2979 -# all tags which are present will be copied to 2980 -# the %tag_name hash. 2981 -sub read_tags { 2982 - 2983 - my $in_file = shift; 2984 - my $in_format = shift; 2985 - 2986 - my $tag_module = $run{$in_format}{TAGS}{MODULE}; 2987 - 2988 - given ($in_format) { 2989 - 2990 - when (/^mp3$|^mp3hd$/) { 2991 - my $mp3tag = $tag_module->new($in_file); 2992 - my @tags = $mp3tag->autoinfo(); 2993 - 2994 - $tag_name{title} = "$tags[0]" if $tags[0]; 2995 - $tag_name{track} = "$tags[1]" if $tags[1]; 2996 - $tag_name{artist} = "$tags[2]" if $tags[2]; 2997 - $tag_name{album} = "$tags[3]" if $tags[3]; 2998 - $tag_name{comment} = "$tags[4]" if $tags[4]; 2999 - $tag_name{year} = "$tags[5]" if $tags[5]; 3000 - $tag_name{genre} = "$tags[6]" if $tags[6]; 3001 - 3002 - return 0; 3003 - } 3004 - 3005 - when (/^ogg$|^oga$/) { 3006 - my $ogg_tag = Audio::Scan->scan_tags($in_file)->{tags}; 3007 - 3008 - $tag_name{title} = $ogg_tag->{TITLE} if $ogg_tag->{TITLE}; 3009 - $tag_name{track} = $ogg_tag->{TRACKNUMBER} if $ogg_tag->{TRACKNUMBER}; 3010 - $tag_name{artist} = $ogg_tag->{ARTIST} if $ogg_tag->{ARTIST}; 3011 - $tag_name{album} = $ogg_tag->{ALBUM} if $ogg_tag->{ALBUM}; 3012 - $tag_name{comment} = $ogg_tag->{COMMENT} if $ogg_tag->{COMMENT}; 3013 - $tag_name{year} = $ogg_tag->{YEAR} if $ogg_tag->{YEAR}; 3014 - $tag_name{genre} = $ogg_tag->{GENRE} if $ogg_tag->{GENRE}; 3015 - 3016 - return 0; 3017 - } 3018 - 3019 - when (/^spx$/) { 3020 - my $pid = open(SPX, "speexdec \"$in_file\" tmp1-$$.wav 2>&1 |") or perror("opening_file","$in_file"); 3021 - my @data = <SPX>; 3022 - @data = grep(!/^$|^#/, @data); 3023 - 3024 - close(SPX); 3025 - 3026 - foreach (@data) { 3027 - 3028 - next unless /=/; 3029 - chomp; 3030 - 3031 - my ($k, $v) = split /=/; 3032 - $k =~ tr/A-Z/a-z/; 3033 - $tag_name{$k} = $v if exists($tag_name{$k}); 3034 - $tag_name{artist} = $v if $k =~ /^author/i; 3035 - $tag_name{track} = $v if $k =~ /^tracknumber/i; 3036 - } 3037 - 3038 - unlink("tmp-$$.wav"); 3039 - return 0; 3040 - } 3041 - 3042 - when (/^flac$|^fla$/) { 3043 - my $flac_tag = Audio::Scan->scan_tags($in_file)->{tags}; 3044 - 3045 - $tag_name{title} = $flac_tag->{TITLE} if $flac_tag->{TITLE}; 3046 - $tag_name{track} = $flac_tag->{TRACKNUMBER} if $flac_tag->{TRACKNUMBER}; 3047 - $tag_name{artist} = $flac_tag->{ARTIST} if $flac_tag->{ARTIST}; 3048 - $tag_name{album} = $flac_tag->{ALBUM} if $flac_tag->{ALBUM}; 3049 - $tag_name{comment} = $flac_tag->{COMMENT} if $flac_tag->{COMMENT}; 3050 - $tag_name{year} = $flac_tag->{DATE} if $flac_tag->{DATE}; 3051 - $tag_name{genre} = $flac_tag->{GENRE} if $flac_tag->{GENRE}; 3052 - 3053 - return 0; 3054 - } 3055 - 3056 - when (/^mp4$|^m4a$|^m4b$/) { 3057 - my $mp4_tag = $tag_module->scan_tags($in_file)->{tags}; 3058 - 3059 - $tag_name{title} = $mp4_tag->{NAM} if $mp4_tag->{NAM}; 3060 - $tag_name{track} = $mp4_tag->{TRKN} if $mp4_tag->{TRKN}; 3061 - $tag_name{artist} = $mp4_tag->{ART} if $mp4_tag->{ART}; 3062 - $tag_name{album} = $mp4_tag->{ALB} if $mp4_tag->{ALB}; 3063 - $tag_name{comment} = $mp4_tag->{CMT} if $mp4_tag->{CMT}; 3064 - $tag_name{year} = $mp4_tag->{DAY} if $mp4_tag->{DAY}; 3065 - $tag_name{genre} = $mp4_tag->{GNRE} if $mp4_tag->{GNRE}; 3066 - 3067 - return 0; 3068 - } 3069 - 3070 -when (/^ape$|^mpc$|^mpp$|^wv$/) { 3071 - my $audio_tag = $tag_module->scan_tags($in_file)->{tags}; 3072 - 3073 - $tag_name{title} = $audio_tag->{TITLE} if $audio_tag->{TITLE}; 3074 - $tag_name{track} = $audio_tag->{TRACK} if $audio_tag->{TRACK}; 3075 - $tag_name{artist} = $audio_tag->{ARTIST} if $audio_tag->{ARTIST}; 3076 - $tag_name{album} = $audio_tag->{ALBUM} if $audio_tag->{ALBUM}; 3077 - $tag_name{comment} = $audio_tag->{COMMENT} if $audio_tag->{COMMENT}; 3078 - $tag_name{year} = $audio_tag->{YEAR} if $audio_tag->{YEAR}; 3079 - $tag_name{genre} = $audio_tag->{GENRE} if $audio_tag->{GENRE}; 3080 - 3081 - return 0; 3082 - } 3083 - 3084 - when (/^wma$/) { 3085 - my $wma_tag = $tag_module->scan_tags($in_file)->{tags}; 3086 - 3087 - $tag_name{title} = $wma_tag->{TITLE} if $wma_tag->{TITLE}; 3088 - $tag_name{track} = $wma_tag->{TRACKNUMBER} if $wma_tag->{TRACKNUMBER}; 3089 - $tag_name{artist} = $wma_tag->{AUTHOR} if $wma_tag->{AUTHOR}; 3090 - $tag_name{album} = $wma_tag->{ALBUMTITLE} if $wma_tag->{ALBUMTITLE}; 3091 - $tag_name{comment} = $wma_tag->{DESCRIPTION} if $wma_tag->{DESCRIPTION}; 3092 - $tag_name{year} = $wma_tag->{YEAR} if $wma_tag->{YEAR}; 3093 - $tag_name{genre} = $wma_tag->{GENRE} if $wma_tag->{GENRE}; 3094 - 3095 - return 0; 3096 - } 3097 - 3098 - default { return 1; } 3099 - } 3100 -} 3101 - 3102 -# write meta-data stored in %tag_name to output file. 3103 -sub write_tags { 3104 - 3105 - my $out_file = shift; 3106 - my $out_format = shift; 3107 - 3108 - my $tag_m; 3109 - 3110 - given ($out_format) { 3111 - 3112 - when (/^mp3$|^mp3hd$/) { 3113 - $tag_m = MP3::Tag->config(write_v24 => 'YES'); 3114 - $tag_m = MP3::Tag->new("$out_file"); 3115 - 3116 - # ID3v2 Tags 3117 - unless(exists($tag_m->{ID3v2})) { $tag_m->new_tag("ID3v2"); } 3118 - 3119 - $tag_m->{ID3v2}->add_frame("TIT2", "$tag_name{title}") if defined($tag_name{title}); 3120 - $tag_m->{ID3v2}->add_frame("TRCK", "$tag_name{track}") if defined($tag_name{track}); 3121 - $tag_m->{ID3v2}->add_frame("TPE1", "$tag_name{artist}") if defined($tag_name{artist}); 3122 - $tag_m->{ID3v2}->add_frame("TALB", "$tag_name{album}") if defined($tag_name{album}); 3123 - $tag_m->{ID3v2}->comment("$tag_name{comment}") if defined($tag_name{comment}); 3124 - $tag_m->{ID3v2}->add_frame("TYER", "$tag_name{year}") if defined($tag_name{year}); 3125 - $tag_m->{ID3v2}->add_frame("TCON", "$tag_name{genre}") if defined($tag_name{genre}); 3126 - 3127 - $tag_m->{ID3v2}->write_tag; 3128 - 3129 - # ID3v1 Tags 3130 - unless(exists($tag_m->{ID3v1})) { $tag_m->new_tag("ID3v1"); } 3131 - 3132 - $tag_m->{ID3v1}->title("$tag_name{title}") if defined($tag_name{title}); 3133 - $tag_m->{ID3v1}->track("$tag_name{track}") if defined($tag_name{track}); 3134 - $tag_m->{ID3v1}->artist("$tag_name{artist}") if defined($tag_name{artist}); 3135 - $tag_m->{ID3v1}->album("$tag_name{album}") if defined($tag_name{album}); 3136 - $tag_m->{ID3v1}->comment("$tag_name{comment}") if defined($tag_name{comment}); 3137 - $tag_m->{ID3v1}->year("$tag_name{year}") if defined($tag_name{year}); 3138 - $tag_m->{ID3v1}->genre("$tag_name{genre}") if defined($tag_name{genre}); 3139 - 3140 - $tag_m->{ID3v1}->write_tag; 3141 - 3142 - return 0; 3143 - 3144 - } 3145 - 3146 - when (/^ogg$|^oga$/) { 3147 - $tag_m = ''; 3148 - 3149 - $tag_m = "$tag_m -t \"TITLE=$tag_name{title}\"" if $tag_name{title}; 3150 - $tag_m = "$tag_m -t \"TRACKNUMBER=$tag_name{track}\"" if $tag_name{track}; 3151 - $tag_m = "$tag_m -t \"ARTIST=$tag_name{artist}\"" if $tag_name{artist}; 3152 - $tag_m = "$tag_m -t \"ALBUM=$tag_name{album}\"" if $tag_name{album}; 3153 - $tag_m = "$tag_m -t \"COMMENT=$tag_name{comment}\"" if $tag_name{comment}; 3154 - $tag_m = "$tag_m -t \"YEAR=$tag_name{year}\"" if $tag_name{year}; 3155 - $tag_m = "$tag_m -t \"GENRE=$tag_name{genre}\"" if $tag_name{genre}; 3156 - 3157 - system("vorbiscomment -w $tag_m \"$out_file\"") if $tag_m ne ''; 3158 - 3159 - return 0; 3160 - } 3161 - 3162 - when (/^fla$|^flac$/) { 3163 - $tag_m = Audio::FLAC::Header->new("$out_file"); 3164 - my $tag_i = $tag_m->tags(); 3165 - 3166 - $tag_i->{TITLE} = "$tag_name{title}" if $tag_name{title}; 3167 - $tag_i->{TRACKNUMBER} = "$tag_name{track}" if $tag_name{track}; 3168 - $tag_i->{ARTIST} = "$tag_name{artist}" if $tag_name{artist}; 3169 - $tag_i->{ALBUM} = "$tag_name{album}" if $tag_name{album}; 3170 - $tag_i->{COMMENT} = "$tag_name{comment}" if $tag_name{comment}; 3171 - $tag_i->{DATE} = "$tag_name{year}" if $tag_name{year}; 3172 - $tag_i->{GENRE} = "$tag_name{genre}" if $tag_name{genre}; 3173 - 3174 - $tag_m->write(); 3175 - 3176 - return 0; 3177 - } 3178 - 3179 - default { perror("no_write_tag","$out_file"); } 3180 - } 3181 - 3182 -} 3183 - 3184 -# this is necessary when converting multiple files. 3185 -# it prevents old tags from the previous file being 3186 -# copied over to the next file in line. 3187 -sub clear_tag_hash { 3188 - foreach (keys(%tag_name)) { 3189 - $tag_name{$_} = ''; 3190 - } 3191 -} 3192 - 3193 -# display meta-data for selected file(s) 3194 -sub show_taginfo { 3195 - 3196 - perror("no_input","") if $#file < 0; 3197 - 3198 - foreach my $i (@file) { 3199 - 3200 - my ($file, $dir, $ext) = fileparse("$i", qr/\.[^.]*/); 3201 - 3202 - $ext =~ s/^\.//; 3203 - 3204 - my $from = $ext; 3205 - $from =~ tr/A-Z/a-z/; 3206 - 3207 - if ($run{$from}{TAGS}{READ} == 1) { 3208 - 3209 - clear_tag_hash(); 3210 - read_tags("$dir/$file.$ext","$from"); 3211 - 3212 - say ''; 3213 - 3214 - pnotice("tag_info","$file.$ext",2); 3215 - 3216 - say " Artist: $tag_name{artist}"; 3217 - say " Title: $tag_name{title}"; 3218 - say " Album: $tag_name{album}"; 3219 - say " Track: $tag_name{track}"; 3220 - say "Comment: $tag_name{comment}"; 3221 - say " Year: $tag_name{year}"; 3222 - say " Genre: $tag_name{genre}"; 3223 - 3224 - say ''; 3225 - 3226 - } else { pnotice("no_read_tag","$file.$ext",2); } 3227 - } 3228 -} 3229 - 3230 -# write tags to file supplied by the user 3231 -sub write_user_tags { 3232 - 3233 - perror("no_input","") if $#file < 0; 3234 - 3235 - say ''; 3236 - say "$name - $version\n"; 3237 - 3238 - foreach (@file) { 3239 - 3240 - my ($file, $dir, $ext) = fileparse("$_", qr/\.[^.]*/); 3241 - 3242 - $ext =~ s/^\.//; 3243 - my $from = $ext; 3244 - $from =~ tr/A-Z/a-z/; 3245 - 3246 - if ($run{$from}{TAGS}{WRITE} == 1) { 3247 - 3248 - clear_tag_hash(); 3249 - read_tags("$dir/$file.$ext","$from"); 3250 - 3251 - $tag_name{title} = $title if $title; 3252 - $tag_name{track} = $track if $track; 3253 - $tag_name{artist} = $artist if $artist; 3254 - $tag_name{album} = $album if $album; 3255 - $tag_name{comment} = $comment if $comment; 3256 - $tag_name{year} = $year if $year; 3257 - $tag_name{genre} = $genre if $genre; 3258 - 3259 - write_tags("$dir/$file.$ext","$from"); 3260 - say "$lang{write_tag_i} $file.$ext"; 3261 - 3262 - } else { perror("no_write_tag","$file.$ext"); } 3263 - } 3264 - say ''; 3265 -} 3266 - 3267 -# print out list of supported encode & decode formats 3268 -sub show_formats { 3269 - 3270 -say "\n$name - $version\n"; 3271 -say "EXT E D ENCODER DECODER TAG-READ TAG-WRITE"; 3272 -say "----------------------------------------------------------------------"; 3273 - 3274 -my $enc_count = 0; 3275 -my $dec_count = 0; 3276 - 3277 - foreach (sort(keys(%run))) { 3278 - 3279 - my $e = "N"; $e = "Y" if defined($run{$_}{DEFAULT_ENCODER}); 3280 - my $d = "N"; $d = "Y" if defined($run{$_}{DEFAULT_DECODER}); 3281 - my $r = "N"; $r = "Y" if $run{$_}{TAGS}{READ} == 1; 3282 - my $w = "N"; $w = "Y" if $run{$_}{TAGS}{WRITE} == 1; 3283 - 3284 - my $enc = ''; $enc = $run{$_}{DEFAULT_ENCODER} if defined($run{$_}{DEFAULT_ENCODER}); 3285 - my $dec = ''; $dec = $run{$_}{DEFAULT_DECODER} if defined($run{$_}{DEFAULT_DECODER}); 3286 - 3287 - printf("%-9s %-3s %-3s %-15s %-18s %-10s %s\n", $_, $e, $d, $enc, $dec, $r, $w); 3288 - 3289 - ++$enc_count if $enc ne ''; 3290 - ++$dec_count if $dec ne ''; 3291 - 3292 - } 3293 - 3294 - say "\n$lang{enc_fmts} $enc_count --- $lang{dec_fmts} $dec_count\n"; 3295 - 3296 -} 3297 - 3298 -# show encoders for output format 3299 -sub show_encoders { 3300 - say "\n$name - $version\n\n$lang{show_encoders}: $my_encoder\n"; 3301 - foreach (sort(keys %{$run{$my_encoder}{ENCODER}})) { 3302 - print "$_ -> "; 3303 - print "installed" if `which $_ 2>/dev/null`; 3304 - print "not found" if not `which $_ 2>/dev/null`; 3305 - print " (default)" if $_ eq $run{$my_encoder}{DEFAULT_ENCODER}; 3306 - say ''; 3307 - } 3308 - say ''; 3309 -} 3310 - 3311 -# show decoders for input format 3312 -sub show_decoders { 3313 - say "\n$name - $version\n\n$lang{show_decoders}: $my_decoder\n"; 3314 - foreach (sort(keys %{$run{$my_decoder}{DECODER}})) { 3315 - print "$_ -> "; 3316 - print "installed" if `which $_ 2>/dev/null`; 3317 - print " (default)" if $_ eq $run{$my_decoder}{DEFAULT_DECODER}; 3318 - say ''; 3319 - } 3320 - say ''; 3321 -} 3322 - 3323 -################# 3324 -# cd ripping... # 3325 -################# 3326 - 3327 -# get total number of tracks from cdparanoia query 3328 -sub get_total_tracks { 3329 - 3330 - open(CDINFO, "cdparanoia -Q 2>&1 |") or die "can't fork: $!\n"; 3331 - my @cdquery = <CDINFO>; 3332 - close(CDINFO); 3333 - 3334 - my $fmt_tracks = $cdquery[-3]; 3335 - $fmt_tracks =~ s/\s//g; 3336 - 3337 - my @ttracks = split(/\./, $fmt_tracks); 3338 - 3339 - return "$ttracks[0]"; 3340 - 3341 -} 3342 - 3343 -my (%cd, %ripconfig, @cdtrack, $track_total); 3344 - 3345 -# setup the cddb config 3346 -sub get_cddb_config { 3347 - 3348 - $config{USE_CDDB} = 0 && return if $nocddb; 3349 - 3350 - $config{CDDB_INPUT} = 0 if $noinput; 3351 - 3352 - $ripconfig{CDDB_HOST} = $config{CDDB_HOST}; 3353 - $ripconfig{CDDB_PORT} = $config{CDDB_PORT}; 3354 - $ripconfig{CDDB_MODE} = $config{CDDB_MODE}; 3355 - $ripconfig{DEVICE} = $device; 3356 - $ripconfig{CDDB_INPUT} = $config{CDDB_INPUT}; 3357 - 3358 - print $ripconfig{CDDB_HOST}; 3359 - 3360 - %cd = get_cddb(\%ripconfig); 3361 - 3362 - if (not $cd{title}) { 3363 - pnotice("no_cddb","",2); 3364 - $config{USE_CDDB} = 0; 3365 - } 3366 - else { 3367 - @cdtrack = @{$cd{track}}; 3368 - $track_total = $cd{tno}; 3369 - } 3370 - 3371 -} 3372 - 3373 -# check to see if a disc is present 3374 -sub query_disc { 3375 - system("cdparanoia -q -d $device -Q > /dev/null 2>&1"); 3376 - perror("no_disc","$device") if $? > 0; 3377 -} 3378 - 3379 -# set tag info from cddb 3380 -sub tag_track { 3381 - 3382 - my $tno = shift; 3383 - 3384 - $tag_name{artist} = $cd{artist} if $cd{artist}; 3385 - $tag_name{title} = $cdtrack[$tno-1] if $cdtrack[$tno-1]; 3386 - $tag_name{genre} = $cd{cat} if $cd{cat}; 3387 - $tag_name{track} = $tno; 3388 - $tag_name{album} = $cd{title} if $cd{title}; 3389 - $tag_name{year} = $cd{year} if $cd{year}; 3390 - $tag_name{comment} = ''; 3391 - 3392 -} 3393 - 3394 -# process and convert ripped track 3395 -sub rip_cd { 3396 - 3397 - my ($on,$tno) = @_; 3398 - 3399 - $outdir = $ENV{HOME}; 3400 - $to =~ tr/A-Z/a-z/; 3401 - 3402 - get_visual_opts($to,$out_dir) if $gui and not defined($first_run); 3403 - $first_run = 1; 3404 - pnotice("ripping_track","$tno",2); 3405 - 3406 - $on =~ s/\//_/g; 3407 - 3408 - say "\ncdparanoia -d $device $tno $on.wav\n" if $dryrun; 3409 - system("cdparanoia -d $device $tno \"$on.wav\" >/dev/null 2>&1") if not $dryrun; 3410 - 3411 - if ($to !~ /wav/i) { 3412 - 3413 - push(@file, "$on.wav"); 3414 - tag_track($tno); 3415 - proc_input(); 3416 - clear_tag_hash(); 3417 - undef(@file); 3418 - unlink("$on.wav") if not $dryrun; 3419 - pnotice("removed_tmp","$on.wav",2) if $verbose; 3420 - 3421 - } 3422 -} 3423 - 3424 -# rip selected tracks or all from disc 3425 -sub proc_cd { 3426 - 3427 - perror("no_app","cdparanoia") if not `which cdparanoia 2>/dev/null`; 3428 - 3429 - query_disc(); 3430 - get_cddb_config(); 3431 - 3432 - my $total_tracks = get_total_tracks(); 3433 - 3434 - if ($rip eq "all") { 3435 - 3436 - if ($config{USE_CDDB} ne 1) { 3437 - 3438 - for(my $i=1;$i<=$total_tracks;$i++) { 3439 - rip_cd($i, $i); 3440 - } 3441 - 3442 - } elsif ($config{USE_CDDB} eq 1) { 3443 - 3444 - my $n = 1; 3445 - 3446 - foreach my $i (@cdtrack) { 3447 - 3448 - my $out_string = $nscheme; 3449 - 3450 - chomp($cdtrack[$n-1]); 3451 - 3452 - $out_string =~ s/%ar/$cd{artist}/; 3453 - $out_string =~ s/%ti/$cdtrack[$n-1]/; 3454 - $out_string =~ s/%tr/$n/; 3455 - $out_string =~ s/%ab/$cd{title}/; 3456 - $out_string =~ s/%yr/$cd{year}/; 3457 - 3458 - rip_cd($out_string, $n); 3459 - 3460 - ++$n; 3461 - } 3462 - } 3463 - 3464 - } else { 3465 - 3466 - my @tracks = split(/,/, $rip); 3467 - 3468 - foreach my $i (@tracks) { 3469 - 3470 - next if $i > $total_tracks or $i < 1; 3471 - 3472 - my $out_string = $nscheme; 3473 - 3474 - $out_string =~ s/%ar/$cd{artist}/; 3475 - $out_string =~ s/%ti/$cdtrack[$i-1]/; 3476 - $out_string =~ s/%tr/$i/; 3477 - $out_string =~ s/%ab/$cd{title}/; 3478 - $out_string =~ s/%yr/$cd{year}/; 3479 - 3480 - rip_cd($out_string, $i) if $config{USE_CDDB} == 1; 3481 - rip_cd($i, $i) if $config{USE_CDDB} == 0; 3482 - } 3483 - } 3484 -} 3485 - 3486 -# get/print cddb information from disc 3487 -sub cdinfo { 3488 - 3489 - query_disc(); 3490 - get_cddb_config(); 3491 - 3492 - say "$name - $version\n"; 3493 - 3494 - say "Artist = $cd{artist}"; 3495 - say "Album = $cd{title}"; 3496 - say "Genre = $cd{genre}"; 3497 - say "Tracks = $cd{tno}"; 3498 - say "Year = $cd{year}\n"; 3499 - 3500 - my $n = 1; 3501 - 3502 - foreach (@cdtrack) { 3503 - say "Track $n: $_"; 3504 - ++$n; 3505 - } 3506 - 3507 - exit(0); 3508 -} 3509 - 3510 -# version / license information 3511 -sub version { 3512 - 3513 -say " 3514 -$name - $version 3515 - 3516 -Copyright (C) 2005-2017 Philip Lyons 3517 - 3518 -This is free software. You may redistribute copies of it under the terms of 3519 -the GNU General Public License <http://www.gnu.org/licenses/gpl.html>. 3520 -There is NO WARRANTY, to the extent permitted by law. 3521 -"; 3522 - 3523 -} 3524 - 3525 -# help & longhelp menu 3526 -sub help_menu { 3527 - 3528 -say "\n$name - $version"; 3529 - 3530 -say " 3531 --t, --to $lang{to} 3532 --r, --recursive $lang{recursive} 3533 --p, --preserve $lang{preserve} 3534 --f, --formats $lang{formats} 3535 --o, --only $lang{only} 3536 --k, --keep $lang{keep} 3537 --j, --jobs $lang{jobs} 3538 --h, --help $lang{help} 3539 --l, --longhelp $lang{longhelp} 3540 --v, --verbose $lang{verbose} 3541 -"; 3542 - 3543 -say "$lang{user_opts} 3544 - 3545 ---defopts $lang{defopts} 3546 ---eopts $lang{eopts} 3547 ---dopts $lang{dopts} 3548 ---nopts $lang{nopts} 3549 ---outfile $lang{outfile} 3550 ---outdir $lang{outdir} 3551 ---dryrun $lang{dryrun} 3552 ---overwrite $lang{overwrited} 3553 ---normalize $lang{normalize} 3554 ---delete $lang{delete} 3555 ---encoder $lang{encoder} 3556 ---decoder $lang{decoder} 3557 ---version $lang{version} 3558 - 3559 -$lang{enc_opts} 3560 - 3561 ---bitrate $lang{bitrate} 3562 ---freq $lang{freq} 3563 ---channels $lang{channels} 3564 ---effect $lang{effect} 3565 ---fcomp $lang{fcomp} 3566 ---acomp $lang{acomp} 3567 ---oggqual $lang{oggqual} 3568 ---spxqual $lang{spxqual} 3569 ---aacqual $lang{aacqual} 3570 ---mpcqual $lang{mpcqual} 3571 ---ofmode $lang{ofmode} 3572 ---ofopt $lang{ofopt} 3573 ---bratio $lang{bratio} 3574 ---bquanl $lang{bquanl} 3575 ---bpsize $lang{bpsize} 3576 - 3577 -$lang{tag_opts} 3578 - 3579 ---artist $lang{artist} 3580 ---title $lang{title} 3581 ---track $lang{track} 3582 ---year $lang{year} 3583 ---album $lang{album} 3584 ---genre $lang{genre} 3585 ---comment $lang{comment} 3586 ---taginfo $lang{taginfo} 3587 - 3588 -$lang{tag_usage} 3589 - 3590 -$lang{rip_opts} 3591 - 3592 ---rip $lang{rip} 3593 ---nocddb $lang{nocddb} 3594 ---noinput $lang{noinput} 3595 ---nscheme $lang{nscheme} 3596 ---cdinfo $lang{cdinfo} 3597 ---device $lang{device} 3598 - 3599 -$lang{rip_usage}" if $longhelp; 3600 - 3601 -say "\n$lang{usage}\n"; 3602 - 3603 -} 3604 - 3605 -sub load_module { 3606 - my ($file) = @_; 3607 - my $return; 3608 - unless($return = do $file) { 3609 - perror("opening_file","$file: $@ $!") if $@ or !defined($return) or not !$return; 3610 - } 3611 -} 3612 - 3613 -sub import_module { 3614 - my ($format_ref) = @_; 3615 - my $format_name=$format_ref->{NAME}; 3616 - $run{$format_name} = $format_ref; 3617 -} 3618 - 3619 -# load all user modules 3620 -sub load_user_modules { 3621 - my @imported_mods; 3622 - opendir(DIR, "$mod_dir") or perror("opening_dir","$mod_dir: $!"); 3623 - foreach (readdir(DIR)) { 3624 - load_module("$mod_dir/$_") if $_ !~ /^\./; 3625 - push(@imported_mods, $_) if $_ !~ /^\./; 3626 - } 3627 - closedir(DIR); 3628 - say "$lang{imported} @imported_mods"; 3629 -} 3630 - 3631 -# place files/directories in their respective arrays 3632 -if (@ARGV) { 3633 - foreach (@ARGV) { 3634 - if (-f $_) { push(@file,$_); print "$lang{debug} adding $_ to \@file\n" if $debug == 1; } 3635 - elsif (-d $_) { push(@dir, $_); print "$lang{debug} adding $_ to \@dir\n" if $debug == 1; } 3636 - else { perror("no_infile","$_"); } 3637 - } 3638 -} 3639 - 3640 -load_user_modules() if $config{IMPORTM} == 1; 3641 - 3642 -if ($to and @ARGV and not $rip) { proc_input(); } 3643 - 3644 -elsif ($to and $rip) { proc_cd(); } 3645 -elsif ($my_encoder and not $to) { show_encoders(); } 3646 -elsif ($my_decoder and not $to) { show_decoders(); } 3647 -elsif ($verinfo) { version(); } 3648 -elsif ($longhelp) { help_menu(); } 3649 -elsif ($formats) { show_formats(); } 3650 -elsif ($cdinfo) { cdinfo(); } 3651 -elsif ($taginfo and not $to) { show_taginfo(); } 3652 -elsif ($title or $track or $artist or $album or $comment or $year or $genre) { write_user_tags(); } 3653 - 3654 -else { help_menu(); } 3655 - 3656 -__END__ 3657 - 3658 -=head1 NAME 3659 - 3660 -pacpl - Perl Audio Converter, a multi purpose converter/ripper/tagger 3661 - 3662 -=head1 SYNOPSIS 3663 - 3664 -pacpl --to <format> <options> [file(s)/directory(s)] 3665 - 3666 -=head1 DESCRIPTION 3667 - 3668 -Perl Audio Converter 3669 - 3670 -A Linux CLI tool for converting multiple audio types from one format to another. 3671 - 3672 -It supports the following audio formats: 3673 - 3674 -======================================== 3675 - 3676 -3G2, 3GP, 8SVX, AAC, AC3, ADTS, AIFF, AL, AMB, AMR, APE, AU, 3677 -AVR, BONK, CAF, CDR, CVU, DAT, DTS, DVMS, F32, F64, FAP, FLA, 3678 -FLAC, FSSD, GSRT, HCOM, IMA, IRCAM, LA, MAT, MAUD, MAT4, MAT5, 3679 -M4A, MP2, MP3, MP4, MPC, MPP, NIST, OFF, OFR, OFS, OPUS, OGA, 3680 -OGG, PAF, PRC, PVF, RA, RAM, RAW, RF64, SD2, SF, SHN, SMP, SND, 3681 -SOU, SPX, SRN, TAK, TTA, TXW, VOC, VMS, VQF, W64, WAV, WMA, 3682 -and WV. 3683 - 3684 -It can also extract audio from the following video extensions: 3685 - 3686 -============================================================== 3687 - 3688 -RM, RV, ASF, DivX, MPG, MKV, MPEG, AVI, MOV, OGM, OGV, QT, VCD, 3689 -SVCD, M4V, NSV, NUV, PSP, SMK, VOB, FLV, WEBM and WMV. 3690 - 3691 -Parallel Processing, a CD ripping function with CDDB support, batch conversion, 3692 -tag preservation for most supported formats, independent tag reading & writing, 3693 -service menus for KDE Dolphin/Konqueror, GNOME Nautilus script, and action 3694 -scripts for Nemo/Thunar are also provided. 3695 - 3696 -=head1 OPTIONS 3697 - 3698 -B<-t, --to> I<format> 3699 - 3700 -set encode format for the input file(s) or directory(ies). you can see a 3701 -complete list of supported encode formats by using the B<--formats> option. 3702 - 3703 -B<-r, --recursive> 3704 - 3705 -recursively scan and convert input folder(s) to destination format. 3706 - 3707 -B<-p, --preserve> 3708 - 3709 -when recursively converting a directory, preserve the input folders directory 3710 -structure in the specified output directory. such as: 3711 - 3712 -pacpl --to ogg -r -p /home/mp3s --outdir /home/oggs 3713 - 3714 -in the example above, let's assume the directory structure was: 3715 - 3716 -=over 21 3717 - 3718 -=item /home/mp3s/Alternative 3719 - 3720 -=item /home/mp3s/Alternative/New 3721 - 3722 -=item /home/mp3s/Rap 3723 - 3724 -=item /home/mp3s/Country 3725 - 3726 -=item /home/mp3s/Techno/ 3727 - 3728 -=back 3729 - 3730 -the output directory will now contain: 3731 - 3732 -=over 4 3733 - 3734 -=item /home/oggs/Alternative 3735 - 3736 -=item /home/oggs/Alternative/New 3737 - 3738 -=item /home/oggs/Rap 3739 - 3740 -=item /home/oggs/Country 3741 - 3742 -=item /home/oggs/Techno 3743 - 3744 -=back 3745 - 3746 -with all files in each sub-folder converted to ogg. 3747 - 3748 -B<-o, --only> I<format> 3749 - 3750 -only convert files matching extension. this option is useful when you have 3751 -a directory or batch of files with mixed audio types and only need to 3752 -convert one specific type. 3753 - 3754 -B<-k, --keep> 3755 - 3756 -do not re-encode files with extensions matching the destination extension. 3757 -instead...copy them to the output folder, or skip to the next file. 3758 - 3759 -B<-j, --jobs> 3760 - 3761 -number of simultanious jobs to run at once. the default limit 3762 -is set to 4 in pacpl.conf. You can modify this value on the fly 3763 -using --jobs=<num> or set it perminately in the configuration file 3764 - 3765 -=over 4 3766 - 3767 -=item B<-f, --formats> show a list of supported encode/decode formats. 3768 - 3769 -=item B<-h, --help> show the short help menu. 3770 - 3771 -=item B<-l, --longhelp> display the complete list of options. 3772 - 3773 -=item B<--version> show version and licensing information. 3774 - 3775 -=back 3776 - 3777 -=head1 USER OPTIONS 3778 - 3779 -B<--defopts> I<1/0> 3780 - 3781 -to turn off default encoder options use --defopts 0. this option gives you 3782 -more control when using the --eopts command. 3783 - 3784 -defopts is set to 1 by default. you can also toggle this option in 3785 -/etc/pacpl/pacpl.conf. 3786 - 3787 -B<--eopts> I<options> 3788 - 3789 -this option allows you to use encoder options not implemented by pacpl. 3790 -an example would be: 3791 - 3792 -pacpl --to mp4 --eopts="-c 44100 -I 1,2" YourFile.mp3 3793 - 3794 -B<--dopts> I<options> 3795 - 3796 -this option allows you to use decoder options not implemented by pacpl. 3797 -an example would be: 3798 - 3799 -pacpl --to mpc --dopts="--start 60" YourFile.ogg 3800 - 3801 -B<--outfile> I<name> 3802 - 3803 -set the output file name to I<name>. 3804 - 3805 -B<--outdir> I<directory> 3806 - 3807 -place all encoded files in I<directory>. 3808 - 3809 -B<--dryrun> 3810 - 3811 -show what would be done without actually converting anything. this is a 3812 -good way to trouble shoot, or to see what would be done without actually 3813 -touching your files. 3814 - 3815 -B<--overwrite> 3816 - 3817 -replace the output file if it already exists. 3818 - 3819 -B<--normalize> 3820 - 3821 -adjusts volume levels of audio files. 3822 - 3823 -B<--nopts> I<options> 3824 - 3825 -this allows you to specify normalize options not implemented by pacpl 3826 - 3827 -B<--delete> 3828 - 3829 -remove source/input file after the conversion process has finished. 3830 - 3831 -B<--encoder> I<encoder> 3832 - 3833 -specify an alternate encoder for the selected output file(s) 3834 - 3835 -you can see a list of supported encoders by using the following: 3836 - 3837 -pacpl --encoder I<format> 3838 - 3839 -B<--decoder> I<decoder> 3840 - 3841 -specify an alternate decoder for the selected input file(s) 3842 - 3843 -you can see a list of supported decoders by using the following: 3844 - 3845 -pacpl --decoder I<format> 3846 - 3847 -B<-v, --verbose> 3848 - 3849 -show detailed information about the encoding process and what's actually 3850 -being done. 3851 - 3852 -=head1 ENCODER OPTIONS 3853 - 3854 -B<--bitrate> I<num> 3855 - 3856 -set the bitrate to I<num>. default is 128. this option does not apply 3857 -to all formats. 3858 - 3859 -B<--freq> I<num> 3860 - 3861 -set the frequency to I<num>. default is 44100. this option does not apply 3862 -to all formats. 3863 - 3864 -B<--channels> I<num> 3865 - 3866 -set the number of audio channels in the output file to I<num>. this option 3867 -does not apply to all formats. 3868 - 3869 -B<--effect> I<str> 3870 - 3871 -see B<sox>(1). this option only applies to the following: 3872 - 3873 -AIFF, AU, SND, RAW, VOC, SMP, AVR, and CDR 3874 - 3875 -B<--fcomp> I<num> 3876 - 3877 -set flac compression level to I<num>. fastest -0, highest -8, default -2 3878 - 3879 -=over 4 3880 - 3881 -=item 1 = fast 3882 - 3883 -=item 2 = simple 3884 - 3885 -=item 3 = medium (default) 3886 - 3887 -=item 4 = high 3888 - 3889 -=item 5 = extra high, 3890 - 3891 -=back 3892 - 3893 -B<--acomp> I<num> 3894 - 3895 -set ape compression level to I<num>. 3896 - 3897 -=over 4 3898 - 3899 -=item 1000 = fast 3900 - 3901 -=item 2000 = normal 3902 - 3903 -=item 3000 = high (default) 3904 - 3905 -=item 4000 = extra high 3906 - 3907 -=item 5000 = insane 3908 - 3909 -=back 3910 - 3911 -B<--oggqual> I<num> 3912 - 3913 -set ogg quality level to I<num>. -1, very low and 10 very high, default 3 3914 - 3915 -B<--spxqual> I<num> 3916 - 3917 -set speex quality level to I<num>. 0-10, default 8 (use --bitrate <num> when using ffmpeg/avconv as encoder) 3918 - 3919 -B<--aacqual> I<num> 3920 - 3921 -set aac, mp4, m4a, or m4b quality level to I<num>. default 300 3922 - 3923 -B<--mpcqual> I<str> 3924 - 3925 -set mpc/mpp quality level to I<str>. 3926 - 3927 -=over 4 3928 - 3929 -=item thumb low quality/internet, (typ. 58... 86 kbps) 3930 - 3931 -=item radio medium (MP3) quality, (typ. 112...152 kbps - default) 3932 - 3933 -=item standard high quality (dflt), (typ. 142...184 kbps) 3934 - 3935 -=item xtreme extreme high quality, (typ. 168...212 kbps) 3936 - 3937 -=back 3938 - 3939 -B<--ofmode> I<str> 3940 - 3941 -set off/ofr/ofs compression mode to I<str>. normal, extra, and extranew modes 3942 -are recommended for general use. available options are: 3943 - 3944 -=over 4 3945 - 3946 -=item fast 3947 - 3948 -=item normal (default) 3949 - 3950 -=item high 3951 - 3952 -=item extra 3953 - 3954 -=item best 3955 - 3956 -=item highnew 3957 - 3958 -=item extranew 3959 - 3960 -=item bestnew 3961 - 3962 -=back 3963 - 3964 -B<--ofopt> I<str> 3965 - 3966 -set off/ofr/ofs optimization level to I<str>. 3967 - 3968 -specify the optimization level in the engine. In order to achieve 3969 -optimal compression at all sample types, sample rates, and audio 3970 -content, the core compression engine has the possibility to find the 3971 -optimal values for its parameters, at the cost of slightly increased 3972 -compression time only. The default recommended value is fast. 3973 -do not use normal (or even high or best) for this parameter unless 3974 -encoding time does not matter and you want to obtain the smallest 3975 -possible file for a given compression mode. The difference between 3976 -the optimize levels fast and best (which is up to three times slower 3977 -than fast) is very small, generally under 0.05%, but may be also 3978 -larger in some rare cases. Note that the none optimize level is 3979 -forced by the encoder to fast optimize level for the extra, best, 3980 -highnew, extranew, and bestnew modes. 3981 - 3982 -available options are: 3983 - 3984 -=over 4 3985 - 3986 -=item none 3987 - 3988 -=item fast (default) 3989 - 3990 -=item normal 3991 - 3992 -=item high 3993 - 3994 -=item best 3995 - 3996 -=back 3997 - 3998 -B<--bratio> I<num> 3999 - 4000 -set bonk down sampling ratio. default 2 4001 - 4002 -B<--bquanl> I<num> 4003 - 4004 -set bonk quantanization level. default 1.0 4005 - 4006 -B<--bpsize> I<num> 4007 - 4008 -set bonk predictor size. default 128 4009 - 4010 -=head1 TAGGING OPTIONS 4011 - 4012 -B<note:> 4013 - 4014 -tagging outside of the encoding process can only be performed on the 4015 -following audio types: 4016 - 4017 -=over 4 4018 - 4019 -=item MP3 4020 - 4021 -=item OGG 4022 - 4023 -=item FLA 4024 - 4025 -=item FLAC 4026 - 4027 -=back 4028 - 4029 -B<--artist> I<str> 4030 - 4031 -set artist information to I<str>. 4032 - 4033 -B<--title> I<str> 4034 - 4035 -set title information to I<str>. 4036 - 4037 -B<--track> I<num> 4038 - 4039 -set track information to I<num>. 4040 - 4041 -B<--year> I<num> 4042 - 4043 -set year/date information to I<num>. 4044 - 4045 -B<--album> I<str> 4046 - 4047 -set album information to I<str>. 4048 - 4049 -B<--genre> I<str> 4050 - 4051 -set genre information to I<str>. 4052 - 4053 -B<--comment> I<str> 4054 - 4055 -set comment information to I<str>. 4056 - 4057 -B<--taginfo> I<file> 4058 - 4059 -show tagging information for I<file>. multiple files can be specified 4060 -at once. 4061 - 4062 -=head1 RIPPING OPTIONS 4063 - 4064 -B<--rip> I<num/all> 4065 - 4066 -rip selected tracks separated by comma or all from current disc. 4067 - 4068 -=over 4 4069 - 4070 -=item pacpl --rip all --to flac 4071 - 4072 -=item pacpl --rip 1,3,9,15 --to flac 4073 - 4074 -=back 4075 - 4076 -B<--nocddb> 4077 - 4078 -disable cddb. use this option if you do not want tagging based on cddb. 4079 - 4080 -B<--noinput> 4081 - 4082 -disable cddb interactivity. this is enabled by default. 4083 - 4084 -B<--nscheme> I<str> 4085 - 4086 -set naming scheme to I<str>. default is %ar - %ti 4087 - 4088 -available options are: 4089 - 4090 -=over 4 4091 - 4092 -=item %ar = artist 4093 - 4094 -=item %ti = song title 4095 - 4096 -=item %tr = track 4097 - 4098 -=item %yr = year 4099 - 4100 -=item %ab = album 4101 - 4102 -=back 4103 - 4104 -B<eg:> --nscheme="(%tr)-%ti" 4105 - 4106 -B<--device> I<device> 4107 - 4108 -set device to I<device>. default is /dev/dvd 4109 - 4110 -B<--cdinfo> 4111 - 4112 -show cddb information for current disc. 4113 - 4114 -=head1 SEE ALSO 4115 - 4116 -=over 4 4117 - 4118 -=item B<sox>(1) B<ffmpeg>(1) B<lame>(1) B<oggenc>(1) B<oggdec>(1) 4119 - 4120 -=item B<flac>(1) B<shorten>(1) B<faac>(1) B<faad>(1) B<mpcenc>(1) 4121 - 4122 -=item B<mpcdec>(1) B<mplayer>(1) B<speexenc>(1) B<speexdec>(1) 4123 - 4124 -=item B<sndfile-convert>(1) B<normalize>(1) B<cdparanoia>(1) 4125 - 4126 -=item B<opusenc>(1) B<opusdec>(1) B<wavpack>(1) B<ffmpeg>(1) 4127 - 4128 -=item B<mplayer>(1) B<avconv>(1) 4129 - 4130 -=back 4131 - 4132 -=head1 BUGS 4133 - 4134 -Report all bugs to Philip Lyons (vorzox@gmail.com) 4135 - 4136 -=head1 LICENSING 4137 - 4138 -This program is free software; you can redistribute it and/or modify 4139 -it under the terms of the GNU General Public License as published by 4140 -the Free Software Foundation; either version 3 of the License, or 4141 -(at your option) any later version. 4142 - 4143 -This program is distributed in the hope that it will be useful, 4144 -but WITHOUT ANY WARRANTY; without even the implied warranty of 4145 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 4146 -GNU General Public License for more details. 4147 - 4148 -You should have received a copy of the GNU General Public License 4149 -along with this program. If not, see <http://www.gnu.org/licenses/>. 4150 - 4151 -=head1 AUTHOR 4152 - 4153 -Copyright (C) 2005-2017 Philip Lyons (vorzox@gmail.com) 4154 diff --git a/pacpl.in b/pacpl.in 4155 new file mode 100755 4156 index 0000000..3690069 4157 --- /dev/null 4158 +++ b/pacpl.in 4159 @@ -0,0 +1,4034 @@ 4160 +#!/usr/bin/perl 4161 +# 4162 +# Perl Audio Converter 4163 +# 4164 +# Copyright (C) 2005-2017 Philip Lyons (vorzox@gmail.com) 4165 +# 4166 +# This program is free software; you can redistribute it and/or modify 4167 +# it under the terms of the GNU General Public License as published by 4168 +# the Free Software Foundation; either version 3 of the License, or 4169 +# (at your option) any later version. 4170 +# 4171 +# This program is distributed in the hope that it will be useful, 4172 +# but WITHOUT ANY WARRANTY; without even the implied warranty of 4173 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 4174 +# GNU General Public License for more details. 4175 +# 4176 +# You should have received a copy of the GNU General Public License 4177 +# along with this program. If not, see <http://www.gnu.org/licenses/>. 4178 + 4179 +use strict; 4180 +use warnings; 4181 +use Getopt::Long; 4182 +use File::Basename; 4183 +use File::Find; 4184 +use File::Spec::Functions qw(rel2abs); 4185 +use Parallel::ForkManager; 4186 + 4187 +use feature qw(switch say); 4188 + 4189 +no if $] >= 5.018, warnings => "experimental::smartmatch"; 4190 + 4191 +# Tagging modules 4192 +use MP3::Tag; 4193 +use Audio::FLAC::Header; 4194 +use Audio::Scan; 4195 + 4196 +# CDDB module 4197 +use CDDB_get qw(get_cddb); 4198 + 4199 +# non-encoder/decoder related options 4200 +my 4201 +( 4202 + $to, 4203 + $recursive, 4204 + $preserve, 4205 + $rip, 4206 + $help, 4207 + $longhelp, 4208 + $verbose, 4209 + $verinfo, 4210 + $dryrun, 4211 + $delete, 4212 + $keep, 4213 + $overwrite, 4214 + $formats, 4215 + $topdir, 4216 + $only, 4217 + $first_run, 4218 + 4219 + @file, 4220 + @dir, 4221 + 4222 + %run, 4223 + %lang, 4224 +); 4225 + 4226 +my $silent = "> /dev/null 2>&1"; 4227 + 4228 +# tagging options 4229 +my 4230 +( 4231 + $title, 4232 + $track, 4233 + $artist, 4234 + $album, 4235 + $comment, 4236 + $year, 4237 + $genre, 4238 + $taginfo, 4239 +); 4240 + 4241 +# name, version & icon information 4242 +my $name = "Perl Audio Converter"; 4243 +my $version = "5.1.0"; 4244 +my $icon_path = "/etc/pacpl/pacpl.png"; 4245 + 4246 +# If these options are toggled, messages/errors will be displayed 4247 +# via kdialog or zenity/notify-send (depending on environment) 4248 +my ($gui, $kde, $gnome); 4249 + 4250 +# Debugging (for developer use only) 4251 +my $debug = 0; 4252 + 4253 +# default configuration. 4254 +my %config = ( 4255 + 4256 + IMPORTM => 0, 4257 + JOBS => 4, 4258 + 4259 + DEFOPTS => 1, 4260 + EOPTS => '', 4261 + DOPTS => '', 4262 + NOPTS => '', 4263 + 4264 + BITRATE => 128, 4265 + FREQ => 44100, 4266 + CHANNELS => 2, 4267 + EFFECT => '', 4268 + FCOMP => 2, 4269 + PCOMP => 3, 4270 + ACOMP => 3000, 4271 + OGGQUAL => 3, 4272 + SPXQUAL => 8, 4273 + AACQUAL => 100, 4274 + MPCQUAL => 'radio', 4275 + OFMODE => 'normal', 4276 + OFOPT => 'fast', 4277 + BRATIO => 2, 4278 + BQUANL => 1.0, 4279 + BPSIZE => 128, 4280 + 4281 + USE_CDDB => 1, 4282 + CDDB_HOST => 'freedb.freedb.org', 4283 + CDDB_PORT => 8880, 4284 + CDDB_MODE => 'cddb', 4285 + CDDB_INPUT => 1, 4286 + DEVICE => '/dev/dvd', 4287 + NSCHEME => '%ar - %ti', 4288 + 4289 + ZEN_DIR => 1, 4290 + ZEN_OPTS => 1, 4291 + KDE_DIR => 1, 4292 + KDE_OPTS => 1, 4293 + 4294 + ); 4295 + 4296 +# location of configuration file 4297 +my $conf_path = "@sysconfdir@/pacpl"; 4298 +my $po_dir = "@pkgdatadir@/locale"; 4299 +my $mod_dir = "$conf_path/modules"; 4300 + 4301 +my $conf_file; 4302 + 4303 +# load the appropriate locale file 4304 +load_lang(); 4305 + 4306 +# try to load configuration file in this order... 4307 +my @conf_locations = ( 4308 + "$ENV{HOME}/.pacplrc", # Local 4309 + "$conf_path/pacpl.conf", # Global 4310 + "$ENV{PWD}/pacpl.conf", # Current Directory 4311 + ); 4312 + 4313 +# try to load conf file from one of the above locations 4314 +foreach my $i (@conf_locations) { 4315 + if (not $conf_file and -e $i) { 4316 + $conf_file = $i; 4317 + say "$lang{debug} $lang{loaded_config} $conf_file" if $debug == 1; 4318 + } 4319 +} 4320 + 4321 +say "$lang{no_config}" if not $conf_file; 4322 + 4323 +# open config file. 4324 +if ($conf_file and -e $conf_file) { 4325 + 4326 + open(CONF, "$conf_file") or die "$lang{opening_file} $conf_file - $!\n"; 4327 + 4328 + my @conf_opts = <CONF>; 4329 + @conf_opts = grep(!/^#|^$/, @conf_opts); 4330 + 4331 + close(CONF); 4332 + 4333 + # now read config file options and change default values accordingly. 4334 + foreach (@conf_opts) { 4335 + chomp; 4336 + my ($k, $v) = split(/\s*=\s*/); 4337 + $config{$k} = $v if exists($config{$k}) and $v; 4338 + say "$lang{debug} $k = $v" if $debug == 1 and exists($config{$k}); 4339 + } 4340 +} 4341 + 4342 +my $codecs_conf = "$conf_path/codecs.conf"; 4343 + 4344 +# set default encoders/decoders 4345 +sub load_codecs { 4346 + 4347 + open(CODECS, "$codecs_conf") or die "$lang{opening_file} $codecs_conf - $!\n"; 4348 + 4349 + my @codecs = <CODECS>; 4350 + @codecs = grep(!/^$|^#/, @codecs); 4351 + @codecs = grep(s/^\s*|\s*$//, @codecs); 4352 + 4353 + close(CODECS); 4354 + 4355 + foreach (@codecs) { 4356 + 4357 + chomp; 4358 + my ($k, $v) = split(/\s*=\s*/); 4359 + my ($e, $d) = split(/,/, $v); 4360 + 4361 + $k =~ tr/A-Z/a-z/; 4362 + 4363 + $run{$k}{DEFAULT_ENCODER} = $e if (exists($run{$k}{DEFAULT_ENCODER})); 4364 + $run{$k}{DEFAULT_DECODER} = $d if (exists($run{$k}{DEFAULT_DECODER})); 4365 + } 4366 +} 4367 + 4368 +# load po file and store in %lang hash 4369 +sub load_lang { 4370 + 4371 + my $po = "$po_dir/$ENV{LANG}.po"; 4372 + $po =~ s/\.UTF-8//i if $po =~ /UTF-8/i; 4373 + $po =~ s/\.utf8//i if $po =~ /utf8/i; 4374 + $po =~ s/_\w+// if not -e $po; 4375 + $po = "$po_dir/en_US.po" if not -e $po; 4376 + 4377 + open(LANG, "< $po") or die "error: could not open - $po\n$!\n"; 4378 + 4379 + my @data = <LANG>; 4380 + @data = grep(!/^#|^$/, @data); 4381 + 4382 + close(LANG); 4383 + 4384 + foreach (@data) { 4385 + chomp; 4386 + s/=/__EQ__/; 4387 + my ($k, $v) = split(/\s*__EQ__\s*/, $_); 4388 + $lang{$k} = $v; 4389 + } 4390 + 4391 +} 4392 + 4393 +my $banner = 1; 4394 + 4395 +# print error messages 4396 +sub perror { 4397 + my ($key, $msg) = @_; 4398 + say "$name - $version\n"; 4399 + say "$lang{error}: $lang{$key} $msg" . "\n"; 4400 + system("kdialog --title \"$name\" --error \"$lang{error}: $lang{$key} $msg\" &") if $gui and $kde; 4401 + system("zenity --title \"$name\" --error \"$lang{error}: $lang{$key} $msg\" &") if $gui and $gnome; 4402 + die "$lang{seek_help}\n"; 4403 +} 4404 + 4405 +# print notices/warnings 4406 +sub pnotice { 4407 + 4408 + my ($key, $msg, $nm) = @_; 4409 + 4410 + say "$name - $version\n" if $banner == 1; 4411 + print "$lang{$key} $msg"; 4412 + say '' if $nm == 1; 4413 + say "\n" if $nm == 2; 4414 + 4415 + $banner = 0; 4416 +} 4417 + 4418 +# defaults for user variables. 4419 +my $outfile; 4420 +my $outdir; 4421 +my $defopts = $config{DEFOPTS}; 4422 +my $eopts = $config{EOPTS}; 4423 +my $dopts = $config{DOPTS}; 4424 +my $nopts = $config{NOPTS}; 4425 +my $normalize = $config{NOPTS}; 4426 +my $bitrate = $config{BITRATE}; 4427 +my $freq = $config{FREQ}; 4428 +my $channels = $config{CHANNELS}; 4429 +my $effect = $config{EFFECT}; 4430 +my $fcomp = $config{FCOMP}; 4431 +my $acomp = $config{ACOMP}; 4432 +my $oggqual = $config{OGGQUAL}; 4433 +my $spxqual = $config{SPXQUAL}; 4434 +my $aacqual = $config{AACQUAL}; 4435 +my $mpcqual = $config{MPCQUAL}; 4436 +my $ofmode = $config{OFMODE}; 4437 +my $ofopt = $config{OFOPT}; 4438 +my $bratio = $config{BRATIO}; 4439 +my $bquanl = $config{BQUANL}; 4440 +my $bpsize = $config{BPSIZE}; 4441 + 4442 +my $cdinfo; 4443 +my $nocddb; 4444 +my $noinput; 4445 +my $device = $config{DEVICE}; 4446 +my $nscheme = $config{NSCHEME}; 4447 +my $my_encoder; 4448 +my $my_decoder; 4449 +my $encoder; 4450 +my $decoder; 4451 + 4452 +my $jobs = $config{JOBS}; 4453 + 4454 +# command line options 4455 +GetOptions 4456 +( 4457 + 't|to=s' => \$to, 4458 + 'r|recursive' => \$recursive, 4459 + 'p|preserve' => \$preserve, 4460 + 'h|help' => \$help, 4461 + 'l|longhelp' => \$longhelp, 4462 + 'v|verbose' => \$verbose, 4463 + 'f|formats' => \$formats, 4464 + 'o|only=s' => \$only, 4465 + 'k|keep' => \$keep, 4466 + 'j|jobs=n' => \$jobs, 4467 + 4468 + 'taginfo' => \$taginfo, 4469 + 4470 + 'version' => \$verinfo, 4471 + 'dryrun' => \$dryrun, 4472 + 'delete' => \$delete, 4473 + 'overwrite' => \$overwrite, 4474 + 'normalize' => \$normalize, 4475 + 'encoder=s' => \$my_encoder, 4476 + 'decoder=s' => \$my_decoder, 4477 + 4478 + 'title=s' => \$title, 4479 + 'track=n' => \$track, 4480 + 'artist=s' => \$artist, 4481 + 'album=s' => \$album, 4482 + 'comment=s' => \$comment, 4483 + 'year=n' => \$year, 4484 + 'genre=s' => \$genre, 4485 + 4486 + 'gui' => \$gui, 4487 + 'kde' => \$kde, 4488 + 'gnome' => \$gnome, 4489 + 4490 + 'eopts=s' => \$eopts, 4491 + 'dopts=s' => \$dopts, 4492 + 'defopts=n' => \$defopts, 4493 + 'nopts=s' => \$nopts, 4494 + 'outfile=s' => \$outfile, 4495 + 'outdir=s' => \$outdir, 4496 + 4497 + 'bitrate=n' => \$bitrate, 4498 + 'freq=n' => \$freq, 4499 + 'channels=n' => \$channels, 4500 + 'effect=s' => \$effect, 4501 + 'fcomp=n' => \$fcomp, 4502 + 'acomp=n' => \$acomp, 4503 + 'oggqual=n' => \$oggqual, 4504 + 'spxqual=n' => \$spxqual, 4505 + 'aacqual=n' => \$aacqual, 4506 + 'mpcqual=s' => \$mpcqual, 4507 + 'ofmode=s' => \$ofmode, 4508 + 'ofopt=s' => \$ofopt, 4509 + 'bratio=n' => \$bratio, 4510 + 'bquanl=n' => \$bquanl, 4511 + 'bpsize=n' => \$bpsize, 4512 + 4513 + 'rip=s' => \$rip, 4514 + 'nocddb' => \$nocddb, 4515 + 'noinput' => \$noinput, 4516 + 'device=s' => \$device, 4517 + 'nscheme=s' => \$nscheme, 4518 + 'cdinfo' => \$cdinfo, 4519 +); 4520 + 4521 +if (defined($preserve) && !defined($outdir)) { 4522 + die "You must specify --outdir when you use --preserve option. See man page.\n"; 4523 +} 4524 + 4525 +$silent = '' if $verbose; 4526 + 4527 +my $opts; 4528 +my $total_converted = 0; 4529 +my $total_failed = 0; 4530 + 4531 +# Initialize the fork manager with a count set through pacpl.conf or via the command line 4532 +my $pm = Parallel::ForkManager->new($jobs); 4533 + 4534 +# conversion options. when adding a new format, 4535 +# wild card %i = input file and %o = output file 4536 +%run = ( 4537 + 4538 + '3g2' => { 4539 + 4540 + DEFAULT_ENCODER => 'ffmpeg', 4541 + DEFAULT_DECODER => 'ffmpeg', 4542 + 4543 + ENCODER => { 4544 + ffmpeg => { 4545 + NAME => 'ffmpeg', 4546 + ESTR => sub { 4547 + $opts = "-ar 8000 -ac 1" if $defopts == 1; 4548 + $opts = '' if $defopts == 0; 4549 + "-y -i %i $eopts $opts %o" 4550 + }, 4551 + 4552 + PROMPT => { NONE => 0, }, 4553 + }, 4554 + 4555 + avconv => { 4556 + NAME => 'avconv', 4557 + ESTR => sub { 4558 + $opts = "-ar 8000 -ac 1" if $defopts == 1; 4559 + $opts = '' if $defopts == 0; 4560 + "-y -i %i $eopts $opts %o" 4561 + }, 4562 + 4563 + PROMPT => { NONE => 0, }, 4564 + }, 4565 + 4566 + }, 4567 + 4568 + DECODER => { 4569 + ffmpeg => { 4570 + NAME => 'ffmpeg', 4571 + DSTR => sub { "-y -i %o $dopts %o" }, 4572 + }, 4573 + 4574 + avconv => { 4575 + NAME => 'avconv', 4576 + DSTR => sub { "-y -i %o %dopts %o" }, 4577 + }, 4578 + }, 4579 + 4580 + TAGS => { 4581 + READ => 0, 4582 + WRITE => 0, 4583 + MODULE => undef, 4584 + }, 4585 + 4586 + }, 4587 + 4588 + '3gp' => { 4589 + 4590 + DEFAULT_ENCODER => 'ffmpeg', 4591 + DEFAULT_DECODER => 'ffmpeg', 4592 + 4593 + ENCODER => { 4594 + ffmpeg => { 4595 + NAME => 'ffmpeg', 4596 + ESTR => sub { 4597 + $opts = "-ar 8000 -ac 1" if $defopts == 1; 4598 + $opts = '' if $defopts == 0; 4599 + "-y -i %i $eopts $opts %o" 4600 + }, 4601 + 4602 + PROMPT => { NONE => 0, }, 4603 + }, 4604 + 4605 + avconv => { 4606 + NAME => 'avconv', 4607 + ESTR => sub { 4608 + $opts = "-ar 8000 -ac 1" if $defopts == 1; 4609 + $opts = '' if $defopts == 0; 4610 + "-y -i %i $eopts $opts %o" 4611 + }, 4612 + 4613 + PROMPT => { NONE => 0, }, 4614 + }, 4615 + 4616 + }, 4617 + 4618 + DECODER => { 4619 + ffmpeg => { 4620 + NAME => 'ffmpeg', 4621 + DSTR => sub { "-y -i %o $dopts %o" }, 4622 + }, 4623 + 4624 + avconv => { 4625 + NAME => 'avconv', 4626 + DSTR => sub { "-y -i %o %dopts %o" }, 4627 + }, 4628 + }, 4629 + 4630 + TAGS => { 4631 + READ => 0, 4632 + WRITE => 0, 4633 + MODULE => undef, 4634 + }, 4635 + 4636 + }, 4637 + 4638 + aac => { 4639 + 4640 + DEFAULT_ENCODER => "faac", 4641 + DEFAULT_DECODER => "faad", 4642 + 4643 + ENCODER => { 4644 + faac => { 4645 + NAME => "faac", 4646 + ESTR => sub { 4647 + $opts = "-q $aacqual" if $defopts == 1; 4648 + $opts = '' if $defopts == 0; 4649 + "$eopts $opts %i -o %o" 4650 + }, 4651 + PROMPT => { AACQUAL => 1 }, 4652 + }, 4653 + 4654 + ffmpeg => { 4655 + NAME => 'ffmpeg', 4656 + ESTR => sub { 4657 + $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 4658 + $opts = '' if $defopts == 0; 4659 + "-y -i %i $eopts $opts %o" 4660 + }, 4661 + 4662 + PROMPT => { 4663 + BITRATE => 1, 4664 + FREQ => 1, 4665 + CHANNELS => 1, 4666 + }, 4667 + }, 4668 + 4669 + avconv => { 4670 + NAME => 'avconv', 4671 + ESTR => sub { 4672 + $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 4673 + $opts = '' if $defopts == 1, 4674 + }, 4675 + 4676 + PROMPT => { 4677 + BITRATE => 1, 4678 + FREQ => 1, 4679 + CHANNELS => 1, 4680 + }, 4681 + }, 4682 + }, 4683 + 4684 + DECODER => { 4685 + faad => { 4686 + NAME => "faad", 4687 + DSTR => sub { "$dopts -o %i %o" }, 4688 + }, 4689 + 4690 + ffmpeg => { 4691 + NAME => "ffmpeg", 4692 + DSTR => sub { "$dopts -y -i %i %o" }, 4693 + }, 4694 + 4695 + avconv => { 4696 + NAME => 'avconv', 4697 + DSTR => sub { "$dopts -y -i %i %o" }, 4698 + }, 4699 + 4700 + mplayer => { 4701 + NAME => "mplayer", 4702 + DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 4703 + }, 4704 + }, 4705 + 4706 + TAGS => { 4707 + READ => 0, 4708 + WRITE => 0, 4709 + MODULE => undef, 4710 + }, 4711 + }, 4712 + 4713 + ac3 => { 4714 + 4715 + DEFAULT_ENCODER => "ffmpeg", 4716 + DEFAULT_DECODER => "ffmpeg", 4717 + 4718 + ENCODER => { 4719 + ffmpeg => { 4720 + NAME => "ffmpeg", 4721 + ESTR => sub { 4722 + $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 4723 + $opts = '' if $defopts == 0; 4724 + "-y -i %i $eopts $opts %o" 4725 + }, 4726 + 4727 + PROMPT => { 4728 + BITRATE => 1, 4729 + FREQ => 1, 4730 + CHANNELS => 1, 4731 + }, 4732 + }, 4733 + 4734 + avconv => { 4735 + NAME => "avconv", 4736 + ESTR => sub { 4737 + $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 4738 + $opts = '' if $defopts == 0; 4739 + "-y -i %i $eopts $opts %o" 4740 + }, 4741 + PROMPT => { 4742 + BITRATE => 1, 4743 + FREQ => 1, 4744 + CHANNELS => 1, 4745 + }, 4746 + }, 4747 + 4748 + aften => { 4749 + NAME => "aften", 4750 + ESTR => sub { 4751 + $opts = "-v 1 -q $bitrate -2" if $defopts == 1; 4752 + $opts = '' if $defopts == 0; 4753 + "$eopts $opts %i %o" 4754 + }, 4755 + 4756 + PROMPT => { 4757 + BITRATE => 1, 4758 + }, 4759 + }, 4760 + 4761 + }, 4762 + 4763 + DECODER => { 4764 + mplayer => { 4765 + NAME => "mplayer", 4766 + DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 4767 + }, 4768 + 4769 + ffmpeg => { 4770 + NAME => "ffmpeg", 4771 + DSTR => sub { "$dopts -y -i %i %o" }, 4772 + }, 4773 + 4774 + avconv => { 4775 + NAME => "avconv", 4776 + DSTR => sub { "$dopts -y -i %i %o" }, 4777 + }, 4778 + }, 4779 + 4780 + TAGS => { 4781 + READ => 0, 4782 + WRITE => 0, 4783 + MODULE => undef, 4784 + }, 4785 + }, 4786 + 4787 + adts => { 4788 + 4789 + DEFAULT_ENCODER => 'ffmpeg', 4790 + DEFAULT_DECODER => 'ffmpeg', 4791 + 4792 + ENCODER => { 4793 + ffmpeg => { 4794 + NAME => 'ffmpeg', 4795 + ESTR => sub { 4796 + $opts = "-ab $bitrate.k -ar $freq -ac $channels -codec:a libfaac" if $defopts == 1; 4797 + $opts = '' if $defopts == 0; 4798 + "-y -i %i $opts $eopts -strict -2 %o" 4799 + }, 4800 + PROMPT => { 4801 + BITRATE => 1, 4802 + FREQ => 1, 4803 + CHANNELS => 1, 4804 + }, 4805 + }, 4806 + 4807 + avconv => { 4808 + NAME => 'avconv', 4809 + ESTR => sub { 4810 + $opts = "-ab $bitrate.k -ar $freq -ac $channels -codec:a libfaac" if $defopts == 1; 4811 + $opts = '' if $defopts == 0; 4812 + "-y -i %i $opts $eopts %o" 4813 + }, 4814 + 4815 + PROMPT => { 4816 + BITRATE => 1, 4817 + FREQ => 1, 4818 + CHANNELS => 1, 4819 + }, 4820 + }, 4821 + }, 4822 + 4823 + DECODER => { 4824 + ffmpeg => { 4825 + NAME => 'ffmpeg', 4826 + DSTR => "$dopts -y -i %i %o", 4827 + }, 4828 + 4829 + avconv => { 4830 + NAME => 'avconv', 4831 + DSTR => "$dopts -y -i %i %o", 4832 + }, 4833 + }, 4834 + 4835 + TAGS => { 4836 + READ => 0, 4837 + WRITE => 0, 4838 + MODULE => undef, 4839 + }, 4840 + }, 4841 + 4842 + ape => { 4843 + 4844 + DEFAULT_ENCODER => "mac", 4845 + DEFAULT_DECODER => "mac", 4846 + 4847 + ENCODER => { 4848 + mac => { 4849 + NAME => "mac", 4850 + ESTR => sub { 4851 + $opts = "-c$acomp" if $defopts == 1; 4852 + $opts = '' if $defopts == 0; 4853 + "%i %o $opts $eopts" 4854 + }, 4855 + 4856 + PROMPT => { ACOMP => 1 }, 4857 + }, 4858 + }, 4859 + 4860 + DECODER => { 4861 + mac => { 4862 + NAME => "mac", 4863 + DSTR => sub { "%i %o -d $dopts" }, 4864 + }, 4865 + 4866 + ffmpeg => { 4867 + NAME => 'ffmpeg', 4868 + DSTR => sub { "-y -i %i %dopts %o" }, 4869 + }, 4870 + 4871 + avconv => { 4872 + NAME => 'avconv', 4873 + DSTR => sub { "-y -i %i $dopts %o" }, 4874 + }, 4875 + }, 4876 + 4877 + TAGS => { 4878 + READ => 1, 4879 + WRITE => 0, 4880 + MODULE => "Audio::Scan", 4881 + }, 4882 + }, 4883 + 4884 + amr => { 4885 + 4886 + DEFAULT_ENCODER => "ffmpeg", 4887 + DEFAULT_DECODER => "ffmpeg", 4888 + 4889 + ENCODER => { 4890 + ffmpeg => { 4891 + NAME => "ffmpeg", 4892 + ESTR => sub { 4893 + $opts = "-ar 8000 -ac 1" if $defopts == 1; 4894 + $opts = '' if $defopts == 0; 4895 + "-y -i %i $eopts $opts %o" 4896 + }, 4897 + 4898 + PROMPT => { NONE => 0, }, 4899 + }, 4900 + 4901 + avconv => { 4902 + NAME => "avconv", 4903 + ESTR => sub { 4904 + $opts = "-ar 8000 -ac 1" if $defopts == 1; 4905 + $opts = '' if $defopts == 0; 4906 + "-y -i %i $eopts $opts %o" 4907 + }, 4908 + 4909 + PROMPT => { NONE => 0, }, 4910 + }, 4911 + 4912 + }, 4913 + 4914 + DECODER => { 4915 + ffmpeg => { 4916 + NAME => 'ffmpeg', 4917 + DSTR => sub { "-y -i %i $dopts %o" }, 4918 + }, 4919 + 4920 + avconv => { 4921 + NAME => 'ffmpeg', 4922 + DSTR => sub { "-y -i %i %dopts %o" }, 4923 + }, 4924 + }, 4925 + 4926 + TAGS => { 4927 + READ => 0, 4928 + WRITE => 0, 4929 + MODULE => undef, 4930 + }, 4931 + 4932 + }, 4933 + 4934 + bonk => { 4935 + 4936 + DEFAULT_ENCODER => "bonk", 4937 + DEFAULT_DECODER => "bonk", 4938 + 4939 + ENCODER => { 4940 + bonk => { 4941 + NAME => "bonk", 4942 + ESTR => sub { 4943 + $opts = "-q $bquanl -b $bratio -s $bpsize" if $defopts == 1; 4944 + $opts = '' if $defopts == 0; 4945 + "encode $eopts $opts %i -o %o" 4946 + }, 4947 + 4948 + PROMPT => { 4949 + BQUANL => 1, 4950 + BRATIO => 1, 4951 + BPSIZE => 1, 4952 + }, 4953 + }, 4954 + }, 4955 + 4956 + DECODER => { 4957 + bonk => { 4958 + NAME => "bonk", 4959 + DSTR => sub { "decode %i -o %o" }, 4960 + }, 4961 + }, 4962 + 4963 + TAGS => { 4964 + READ => 0, 4965 + WRITE => 0, 4966 + MODULE => undef, 4967 + }, 4968 + }, 4969 + 4970 + dts => { 4971 + 4972 + DEFAULT_ENCODER => 'ffmpeg', 4973 + DEFAULT_DECODER => 'ffmpeg', 4974 + 4975 + ENCODER => { 4976 + ffmpeg => { 4977 + NAME => 'ffmpeg', 4978 + ESTR => sub { 4979 + $opts = '' if $defopts == 1; 4980 + $opts = '' if $defopts == 0; 4981 + "-y -i %i $opts $eopts -strict -2 -codec:a libfaac %o" 4982 + }, 4983 + 4984 + PROMPT => { NONE => 0, }, 4985 + }, 4986 + 4987 + avconv => { 4988 + NAME => 'avconv', 4989 + ESTR => sub { 4990 + $opts = '' if $defopts == 1 or $defopts == 0; 4991 + "-y -i %i $opts $eopts -codec:a libfaac %o", 4992 + }, 4993 + PROMPT => { NONE => 0, }, 4994 + }, 4995 + 4996 + dcaenc => { 4997 + NAME => 'dcaenc', 4998 + ESTR => sub { 4999 + $opts = "$bitrate" if $defopts == 0; 5000 + $opts = '' if $defopts == 1; 5001 + "%i %o $opts" 5002 + }, 5003 + 5004 + PROMPT => { NONE => 0, }, 5005 + }, 5006 + }, 5007 + 5008 + DECODER => { 5009 + ffmpeg => { 5010 + NAME => 'ffmpeg', 5011 + DSTR => "$dopts -y -i %i %o", 5012 + }, 5013 + 5014 + avconv => { 5015 + NAME => 'avconv', 5016 + DSTR => "$dopts -y -i %i %o", 5017 + }, 5018 + }, 5019 + 5020 + TAGS => { 5021 + READ => 0, 5022 + WRITE => 0, 5023 + MODULE => undef, 5024 + }, 5025 + }, 5026 + 5027 + flac => { 5028 + 5029 + DEFAULT_ENCODER => "flac", 5030 + DEFAULT_DECODER => "flac", 5031 + 5032 + ENCODER => { 5033 + flac => { 5034 + NAME => "flac", 5035 + ESTR => sub { 5036 + $opts = "-$fcomp" if $defopts == 1; 5037 + $opts = '' if $defopts == 0; 5038 + "$eopts -f $opts %i -o %o" 5039 + }, 5040 + PROMPT => { FCOMP => 1 }, 5041 + }, 5042 + 5043 + flake => { 5044 + NAME => "flake", 5045 + ESTR => sub { 5046 + $opts = "-$fcomp" if $defopts == 1; 5047 + $opts = '' if $defopts == 0; 5048 + "$eopts $opts %i -o %o" 5049 + }, 5050 + PROMPT => { FCOMP => 1 }, 5051 + }, 5052 + 5053 + ffmpeg => { 5054 + NAME => "ffmpeg", 5055 + ESTR => sub { 5056 + $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 5057 + $opts = '' if $defopts == 0; 5058 + "-y -i %i $eopts $opts %o" 5059 + }, 5060 + 5061 + PROMPT => { 5062 + BITRATE => 1, 5063 + FREQ => 1, 5064 + CHANNELS => 1, 5065 + }, 5066 + }, 5067 + 5068 + avconv => { 5069 + NAME => 'avconv', 5070 + ESTR => sub { 5071 + $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 5072 + $opts = '' if $defopts == 1; 5073 + "-y -i %i $eopts $opts %o" 5074 + }, 5075 + PROMPT => { 5076 + BITRATE => 1, 5077 + FREQ => 1, 5078 + CHANNELS => 1, 5079 + }, 5080 + }, 5081 + }, 5082 + 5083 + DECODER => { 5084 + flac => { 5085 + NAME => "flac", 5086 + DSTR => sub { "$dopts -f -d %i -o %o" }, 5087 + }, 5088 + 5089 + ffmpeg => { 5090 + NAME => "ffmpeg", 5091 + DSTR => sub { "$dopts -y -i %i %o" }, 5092 + }, 5093 + 5094 + avconv => { 5095 + NAME => 'avconv', 5096 + DSTR => sub { "$dopts -y -i %i %o" }, 5097 + }, 5098 + 5099 + mplayer => { 5100 + NAME => "mplayer", 5101 + DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 5102 + }, 5103 + }, 5104 + 5105 + TAGS => { 5106 + READ => 1, 5107 + WRITE => 1, 5108 + MODULE => "Audio::FLAC::Header", 5109 + }, 5110 + }, 5111 + 5112 + fla => { 5113 + 5114 + DEFAULT_ENCODER => "flac", 5115 + DEFAULT_DECODER => "flac", 5116 + 5117 + ENCODER => { 5118 + flac => { 5119 + NAME => "flac", 5120 + ESTR => sub { 5121 + $opts = "-$fcomp" if $defopts == 1; 5122 + $opts = '' if $defopts == 0; 5123 + "$eopts -f $opts %i -o %o" 5124 + }, 5125 + PROMPT => { FCOMP => 1 }, 5126 + }, 5127 + }, 5128 + 5129 + DECODER => { 5130 + flac => { 5131 + NAME => "flac", 5132 + DSTR => sub { "$dopts -f -d %i -o %o" }, 5133 + }, 5134 + 5135 + mplayer => { 5136 + NAME => "mplayer", 5137 + DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 5138 + }, 5139 + }, 5140 + 5141 + TAGS => { 5142 + READ => 1, 5143 + WRITE => 1, 5144 + MODULE => "Audio::FLAC::Header", 5145 + }, 5146 + }, 5147 + 5148 + la => { 5149 + 5150 + DEFAULT_ENCODER => "la", 5151 + DEFAULT_DECODER => "la", 5152 + 5153 + ENCODER => { 5154 + la => { 5155 + NAME => "la", 5156 + ESTR => sub { "-overwrite $eopts %i %o" }, 5157 + PROMPT => { NONE => 0, }, 5158 + }, 5159 + }, 5160 + 5161 + DECODER => { 5162 + la => { 5163 + NAME => "la", 5164 + ESTR => sub { "-console $dopts %i > %o" }, 5165 + }, 5166 + }, 5167 + 5168 + TAGS => { 5169 + READ => 0, 5170 + WRITE => 0, 5171 + MODULE => undef, 5172 + }, 5173 + }, 5174 + 5175 + mp2 => { 5176 + 5177 + DEFAULT_ENCODER => "ffmpeg", 5178 + DEFAULT_DECODER => "ffmpeg", 5179 + 5180 + ENCODER => { 5181 + ffmpeg => { 5182 + NAME => 'ffmpeg', 5183 + ESTR => sub { 5184 + $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 5185 + $opts = '' if $defopts == 0; 5186 + "-y -i %i $eopts $opts %o" 5187 + }, 5188 + 5189 + PROMPT => { 5190 + BITRATE => 1, 5191 + FREQ => 1, 5192 + CHANNELS => 1, 5193 + }, 5194 + }, 5195 + 5196 + avconv => { 5197 + NAME => 'avconv', 5198 + ESTR => sub { 5199 + $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 5200 + $opts = '' if $defopts == 0; 5201 + "-y -i %i $eopts $opts %o" 5202 + }, 5203 + PROMPT => { 5204 + BITRATE => 1, 5205 + FREQ => 1, 5206 + CHANNELS => 1, 5207 + }, 5208 + }, 5209 + 5210 + toolame => { 5211 + NAME => 'toolame', 5212 + ESTR => sub { 5213 + $opts = "-b $bitrate" if $defopts == 1; 5214 + $opts = '' if $defopts == 0; 5215 + "$eopts $opts %i %o" 5216 + }, 5217 + 5218 + PROMPT => { 5219 + BITRATE => 1, 5220 + }, 5221 + }, 5222 + 5223 + twolame => { 5224 + NAME => 'twolame', 5225 + ESTR => sub { 5226 + $opts = "-b $bitrate -s $freq" if $defopts == 1; 5227 + $opts = '' if $defopts == 0; 5228 + "$eopts $opts %i %o" 5229 + }, 5230 + 5231 + PROMPT => { 5232 + BITRATE => 1, 5233 + FREQ => 1, 5234 + }, 5235 + }, 5236 + 5237 + sox => { 5238 + NAME => 'sox', 5239 + ESTR => sub { 5240 + $opts = "-c $channels -r $bitrate" if $defopts == 1; 5241 + $opts = '' if $defopts == 0; 5242 + "%i $eopts $opts %o" 5243 + }, 5244 + 5245 + PROMPT => { 5246 + BITRATE => 1, 5247 + CHANNELS => 1, 5248 + }, 5249 + }, 5250 + }, 5251 + 5252 + DECODER => { 5253 + 5254 + ffmpeg => { 5255 + NAME => 'ffmpeg', 5256 + DSTR => "$dopts -y -i %i %o", 5257 + }, 5258 + 5259 + avconv => { 5260 + NAME => 'avconv', 5261 + DSTR => "%dopts -y -i %i %o", 5262 + }, 5263 + 5264 + mplayer => { 5265 + NAME => 'mplayer', 5266 + DSTR => "-vc null -vo null -ao pcm:file=%o %i", 5267 + }, 5268 + }, 5269 + 5270 + TAGS => { 5271 + READ => 0, 5272 + WRITE => 0, 5273 + MODULE => undef, 5274 + }, 5275 + }, 5276 + 5277 + mp3 => { 5278 + 5279 + DEFAULT_ENCODER => "lame", 5280 + DEFAULT_DECODER => "lame", 5281 + 5282 + ENCODER => { 5283 + lame => { 5284 + NAME => "lame", 5285 + ESTR => sub { 5286 + $opts = "--resample $freq -b $bitrate -h" if $defopts == 1; 5287 + $opts = '' if $defopts == 0; 5288 + "$eopts $opts %i %o" 5289 + }, 5290 + 5291 + PROMPT => { 5292 + BITRATE => 1, 5293 + FREQ => 1, 5294 + }, 5295 + }, 5296 + 5297 + bladeenc => { 5298 + NAME => "bladeenc", 5299 + ESTR => sub { 5300 + $opts = "-br $bitrate" if $defopts == 1; 5301 + $opts = '' if $defopts == 0; 5302 + "$eopts $opts %i %o" 5303 + }, 5304 + PROMPT => { BITRATE => 1 }, 5305 + }, 5306 + 5307 + ffmpeg => { 5308 + NAME => "ffmpeg", 5309 + ESTR => sub { 5310 + $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 5311 + $opts = '' if $defopts == 0; 5312 + "$eopts -y -i %i $opts %o" 5313 + }, 5314 + 5315 + PROMPT => { 5316 + BITRATE => 1, 5317 + FREQ => 1, 5318 + CHANNELS => 1, 5319 + }, 5320 + }, 5321 + 5322 + avconv => { 5323 + NAME => 'avconv', 5324 + ESTR => sub { 5325 + $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 5326 + $opts = '' if $defopts == 0; 5327 + "-y -i %i $eopts $opts %o" 5328 + }, 5329 + PROMPT => { 5330 + BITRATE => 1, 5331 + FREQ => 1, 5332 + CHANNELS => 1, 5333 + }, 5334 + }, 5335 + 5336 + sox => { 5337 + NAME => "sox", 5338 + ESTR => sub { 5339 + $opts = "-r $freq -c $channels" if $defopts == 1; 5340 + $opts = '' if $defopts == 0; 5341 + "%i $eopts $opts %o" 5342 + }, 5343 + 5344 + PROMPT => { 5345 + FREQ => 1, 5346 + CHANNELS => 1, 5347 + }, 5348 + }, 5349 + }, 5350 + 5351 + DECODER => { 5352 + lame => { 5353 + NAME => "lame", 5354 + DSTR => sub { "$dopts --decode %i %o" }, 5355 + }, 5356 + 5357 + ffmpeg => { 5358 + NAME => "ffmpeg", 5359 + DSTR => sub { "$dopts -y -i %i %o" }, 5360 + }, 5361 + 5362 + avconv => { 5363 + NAME => 'avconv', 5364 + DSTR => sub { "$dopts -y -i %i %O" }, 5365 + }, 5366 + 5367 + mplayer => { 5368 + NAME => "mplayer", 5369 + DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 5370 + }, 5371 + 5372 + sox => { 5373 + NAME => "sox", 5374 + DSTR => sub { "%i $dopts %o" }, 5375 + }, 5376 + }, 5377 + 5378 + TAGS => { 5379 + READ => 1, 5380 + WRITE => 1, 5381 + MODULE => "MP3::Tag", 5382 + }, 5383 + }, 5384 + 5385 + mp3hd => { 5386 + 5387 + DEFAULT_ENCODER => "mp3hdEncoder", 5388 + DEFAULT_DECODER => "mp3hdDecoder", 5389 + 5390 + ENCODER => { 5391 + mp3hdEncoder => { 5392 + NAME => "mp3hdEncoder", 5393 + ESTR => sub { 5394 + $opts = "-br $bitrate" if $defopts == 1; 5395 + $opts = '' if $defopts == 0; 5396 + "$eopts $opts -if %i -of %o" 5397 + }, 5398 + PROMPT => { BITRATE => 1 }, 5399 + }, 5400 + }, 5401 + 5402 + DECODER => { 5403 + mp3hdDecoder => { 5404 + NAME => "mp3hdDecoder", 5405 + DSTR => sub { "$dopts -if %i -of %o" }, 5406 + }, 5407 + }, 5408 + 5409 + TAGS => { 5410 + WRITE => 1, 5411 + READ => 1, 5412 + MODULE => "MP3::Tag", 5413 + }, 5414 + }, 5415 + 5416 + mp4 => { 5417 + 5418 + DEFAULT_ENCODER => "faac", 5419 + DEFAULT_DECODER => "faad", 5420 + 5421 + ENCODER => { 5422 + 5423 + faac => { 5424 + NAME => "faac", 5425 + ESTR => sub { 5426 + $opts = "-q $aacqual" if $defopts == 1; 5427 + $opts = '' if $defopts == 0; 5428 + "$eopts -w $opts %i -o %o" 5429 + }, 5430 + PROMPT => { AACQUAL => 1 }, 5431 + }, 5432 + 5433 + ffmpeg => { 5434 + NAME => "ffmpeg", 5435 + ESTR => sub { 5436 + $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 5437 + $opts = '' if $defopts == 0; 5438 + "-y -i %i $eopts $opts %o" 5439 + }, 5440 + 5441 + PRIMPT => { 5442 + BITRATE => 1, 5443 + FREQ => 1, 5444 + CHANNELS => 1, 5445 + }, 5446 + }, 5447 + 5448 + avconv => { 5449 + NAME => 'avconv', 5450 + ESTR => sub { 5451 + $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 5452 + $opts = '' if $defopts == 0; 5453 + "-y -i %i $eopts $opts %o" 5454 + }, 5455 + 5456 + PROMPT => { 5457 + BITRATE => 1, 5458 + FREQ => 1, 5459 + CHANNELS => 1, 5460 + }, 5461 + }, 5462 + }, 5463 + 5464 + DECODER => { 5465 + 5466 + faad => { 5467 + NAME => "faad", 5468 + DSTR => sub { "$dopts -o %o %i" }, 5469 + }, 5470 + 5471 + ffmpeg => { 5472 + NAME => "ffmpeg", 5473 + DSTR => sub { "$dopts -y -i %i %o" }, 5474 + }, 5475 + 5476 + avconv => { 5477 + NAME => 'avconv', 5478 + DSTR => sub { "$dopts -y -i %i %o" }, 5479 + }, 5480 + 5481 + mplayer => { 5482 + NAME => "mplayer", 5483 + DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 5484 + }, 5485 + }, 5486 + 5487 + TAGS => { 5488 + READ => 1, 5489 + WRITE => 1, 5490 + MODULE => "Audio::Scan", 5491 + }, 5492 + }, 5493 + 5494 + m4a => { 5495 + 5496 + DEFAULT_ENCODER => "faac", 5497 + DEFAULT_DECODER => "faad", 5498 + 5499 + ENCODER => { 5500 + 5501 + faac => { 5502 + NAME => "faac", 5503 + ESTR => sub { 5504 + $opts = "-q $aacqual" if $defopts == 1; 5505 + $opts = '' if $defopts == 0; 5506 + "$eopts -w $opts %i -o %o" 5507 + }, 5508 + PROMPT => { AACQUAL => 1 }, 5509 + }, 5510 + 5511 + ffmpeg => { 5512 + NAME => "ffmpeg", 5513 + ESTR => sub { 5514 + $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 5515 + $opts = '' if $defopts == 0; 5516 + "$eopts -y -i %i $opts %o" 5517 + }, 5518 + 5519 + PROMPT => { 5520 + BITRATE => 1, 5521 + FREQ => 1, 5522 + CHANNELS => 1, 5523 + }, 5524 + }, 5525 + 5526 + avconv => { 5527 + NAME => 'avconv', 5528 + ESTR => sub { 5529 + $opts = "-ab $bitrate.k -ar $freq -ac $channels" if $defopts == 1; 5530 + $opts = '' if $defopts == 0; 5531 + "-y -i %i $eopts $opts %o" 5532 + }, 5533 + 5534 + PROMPT => { 5535 + BITRATE => 1, 5536 + FREQ => 1, 5537 + CHANNELS => 1, 5538 + }, 5539 + }, 5540 + }, 5541 + 5542 + DECODER => { 5543 + 5544 + faad => { 5545 + NAME => "faad", 5546 + DSTR => sub { "$dopts -o %o %i" }, 5547 + }, 5548 + 5549 + ffmpeg => { 5550 + NAME => "ffmpeg", 5551 + DSTR => sub { "$dopts -y -i %i %o" }, 5552 + }, 5553 + 5554 + avconv => { 5555 + NAME => 'avconv', 5556 + DSTR => sub { "$dopts -y -i %i %o" }, 5557 + }, 5558 + 5559 + mplayer => { 5560 + NAME => "mplayer", 5561 + DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 5562 + }, 5563 + 5564 + }, 5565 + 5566 + ESTR => sub { "$eopts -w -q $aacqual %i -o %o" }, 5567 + 5568 + TAGS => { 5569 + READ => 1, 5570 + WRITE => 1, 5571 + MODULE => "Audio::Scan", 5572 + }, 5573 + }, 5574 + 5575 + m4b => { 5576 + 5577 + DEFAULT_ENCODER => undef, 5578 + DEFAULT_DECODER => "faad", 5579 + 5580 + DECODER => { 5581 + faad => { 5582 + NAME => "faad", 5583 + DSTR => sub { "$dopts -o %o %i" }, 5584 + }, 5585 + 5586 + mplayer => { 5587 + NAME => "mplayer", 5588 + DSTR => sub { "$dopts -vc null -vo null -ao pcm:file=%o %i" }, 5589 + }, 5590 + 5591 + ffmpeg => { 5592 + NAME => 'ffmpeg', 5593 + DSTR => sub { "$dopts -y -i %i %o" }, 5594 + }, 5595 + 5596 + avconv => { 5597 + NAME => 'avconv', 5598 + DSTR => sub { "$dopts -y -i %i %o" }, 5599 + }, 5600 + }, 5601 + 5602 + TAGS => { 5603 + READ => 0, 5604 + WRITE => 1, 5605 + MODULE => undef, 5606 + }, 5607 + }, 5608 + 5609 + mpc => { 5610 + 5611 + DEFAULT_ENCODER => "mpcenc", 5612 + DEFAULT_DECODER => "mpcdec", 5613 + 5614 + ENCODER => { 5615 + 5616 + mpcenc => { 5617 + NAME => "mpcenc", 5618 + ESTR => sub { 5619 + $opts = "--$mpcqual" if $defopts == 1; 5620 + $opts = '' if $defopts == 0; 5621 + "$eopts --overwrite $opts %i %o" 5622 + }, 5623 + PROMPT => { MPCQUAL => 1 }, 5624 + }, 5625 + }, 5626 + 5627 + DECODER => { 5628 + 5629 + mpcdec => { 5630 + NAME => "mpcdec", 5631 + DSTR => sub { "$dopts %i %o" }, 5632 + }, 5633 + 5634 + ffmpeg => { 5635 + NAME => 'ffmpeg', 5636 + DSTR => sub { "$dopts -y -i %i %o" }, 5637 + }, 5638 + 5639 + avconv => { 5640 + NAME => 'avconv', 5641 + DSTR => sub { "$dopts -y -i %i %o" }, 5642 + }, 5643 + 5644 + mplayer => { 5645 + NAME => "mplayer", 5646 + DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 5647 + }, 5648 + }, 5649 + 5650 + TAGS => { 5651 + READ => 1, 5652 + WRITE => 1, 5653 + MODULE => "Audio::Scan", 5654 + }, 5655 + 5656 + PROMPT => { 5657 + MPCQUAL => 1, 5658 + }, 5659 + }, 5660 + 5661 + mpp => { 5662 + 5663 + DEFAULT_ENCODER => "mpcenc", 5664 + DEFAULT_DECODER => "mpcdec", 5665 + 5666 + ENCODER => { 5667 + 5668 + mpcenc => { 5669 + NAME => "mpcenc", 5670 + ESTR => sub { 5671 + $opts = "--$mpcqual" if $defopts == 1; 5672 + $opts = '' if $defopts == 0; 5673 + "$eopts --overwrite $opts %i %o" 5674 + }, 5675 + PROMPT => { MPCQUAL => 1 }, 5676 + }, 5677 + }, 5678 + 5679 + DECODER => { 5680 + 5681 + mpcdec => { 5682 + NAME => "mpcdec", 5683 + DSTR => sub { "$dopts %i %o" }, 5684 + }, 5685 + 5686 + ffmpeg => { 5687 + NAME => 'ffmpeg', 5688 + DSTR => sub { "$dopts -y -i %i %o" }, 5689 + }, 5690 + 5691 + avconv => { 5692 + NAME => 'avconv', 5693 + DSTR => sub { "$dopts -y -i %i %o" }, 5694 + }, 5695 + 5696 + mplayer => { 5697 + NAME => "mplayer", 5698 + DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 5699 + }, 5700 + }, 5701 + 5702 + TAGS => { 5703 + READ => 1, 5704 + WRITE => 1, 5705 + MODULE => "Audio::Scan", 5706 + }, 5707 + }, 5708 + 5709 + off => { 5710 + DEFAULT_ENCODER => 'off', 5711 + DEFAULT_DECODER => 'off', 5712 + 5713 + ENCODER => { 5714 + off => { 5715 + NAME => 'off', 5716 + ESTR => sub { 5717 + $opts = "--mode $ofmode --optimize $ofopt" if $defopts == 1; 5718 + $opts = '' if $defopts == 0; 5719 + "$eopts --overwrite $opts %i --output %o" 5720 + }, 5721 + 5722 + PROMPT => { 5723 + OFMODE => 1, 5724 + OFOPT => 1, 5725 + }, 5726 + }, 5727 + }, 5728 + 5729 + DECODER => { 5730 + off => { 5731 + NAME => 'off', 5732 + DSTR => sub { "$dopts --overwrite --decode %i --output %o" }, 5733 + }, 5734 + }, 5735 + 5736 + TAGS => { 5737 + READ => 0, 5738 + WRITE => 0, 5739 + MODULE => undef, 5740 + }, 5741 + }, 5742 + 5743 + ofr => { 5744 + 5745 + DEFAULT_ENCODER => "ofr", 5746 + DEFAULT_DECODER => "ofr", 5747 + 5748 + ENCODER => { 5749 + ofr => { 5750 + NAME => "ofr", 5751 + ESTR => sub { 5752 + $opts = "--mode $ofmode --optimize $ofopt" if $defopts == 1; 5753 + $opts = '' if $defopts == 0; 5754 + "$eopts --overwrite $opts %i --output %o" 5755 + }, 5756 + 5757 + PROMPT => { 5758 + OFMODE => 1, 5759 + OFOPT => 1, 5760 + }, 5761 + }, 5762 + }, 5763 + 5764 + DECODER => { 5765 + ofr => { 5766 + NAME => "ofr", 5767 + DSTR => sub { "$dopts --overwrite --decode %i --output %o" }, 5768 + }, 5769 + }, 5770 + 5771 + TAGS => { 5772 + READ => 0, 5773 + WRITE => 0, 5774 + MODULE => undef, 5775 + }, 5776 + }, 5777 + 5778 + ofs => { 5779 + 5780 + DEFAULT_ENCODER => "ofs", 5781 + DEFAULT_DECODER => "ofs", 5782 + 5783 + ENCODER => { 5784 + ofs => { 5785 + NAME => "ofs", 5786 + ESTR => sub { 5787 + $opts = "--mode $ofmode --optimize $ofopt" if $defopts == 1; 5788 + $opts = '' if $defopts == 0; 5789 + "$eopts --overwrite $opts %i --output %o" 5790 + }, 5791 + 5792 + PROMPT => { 5793 + OFMODE => 1, 5794 + OFOPT => 1, 5795 + }, 5796 + }, 5797 + }, 5798 + 5799 + DECODER => { 5800 + ofs => { 5801 + NAME => "ofs", 5802 + DSTR => sub { "$dopts --overwrite --decode %i --output %o" }, 5803 + }, 5804 + }, 5805 + 5806 + TAGS => { 5807 + READ => 0, 5808 + WRITE => 0, 5809 + MODULE => undef, 5810 + }, 5811 + }, 5812 + 5813 + 5814 + oga => { 5815 + DEFAULT_ENCODER => 'oggenc', 5816 + DEFAULT_DECODER => 'oggdec', 5817 + 5818 + ENCODER => { 5819 + oggenc => { 5820 + NAME => 'oggenc', 5821 + ESTR => sub { 5822 + $opts = "--resample $freq -q $oggqual" if $defopts == 1; 5823 + $opts = '' if $defopts == 0; 5824 + "$eopts $opts %i %o" 5825 + }, 5826 + PROMPT => { 5827 + FREQ => 1, 5828 + OGGQUAL => 1, 5829 + }, 5830 + }, 5831 + 5832 + ffmpeg => { 5833 + NAME => "ffmpeg", 5834 + ESTR => sub { 5835 + $opts = "-ab $bitrate.k -ar $freq -ac $channels -codec:a libvorbis" if $defopts == 1; 5836 + $opts = '' if $defopts == 0; 5837 + "-y -i %i $eopts $opts %o" 5838 + }, 5839 + 5840 + PROMPT => { 5841 + BITRATE => 1, 5842 + FREQ => 1, 5843 + CHANNELS => 1, 5844 + }, 5845 + }, 5846 + 5847 + avconv => { 5848 + NAME => 'avconv', 5849 + ESTR => sub { 5850 + $opts = "-ab $bitrate.k -ar $freq -ac $channels -codec:a libvorbis" if $defopts == 1; 5851 + $opts = '' if $defopts == 0; 5852 + "-y -i %i $eopts $opts %o" 5853 + }, 5854 + 5855 + PROMPT => { 5856 + BITRATE => 1, 5857 + FREQ => 1, 5858 + CHANNELS => 1, 5859 + }, 5860 + }, 5861 + 5862 + sox => { 5863 + NAME => "sox", 5864 + ESTR => sub { 5865 + $opts = "-r $freq -c $channels" if $defopts == 1; 5866 + $opts = '' if $defopts == 0; 5867 + "%i $eopts $opts %o" 5868 + }, 5869 + 5870 + PROMPT => { 5871 + FREQ => 1, 5872 + CHANNELS => 1, 5873 + }, 5874 + }, 5875 + }, 5876 + 5877 + DECODER => { 5878 + oggdec => { 5879 + NAME => "oggdec", 5880 + DSTR => sub { "$dopts %i --output %o" }, 5881 + }, 5882 + 5883 + ffmpeg => { 5884 + NAME => "ffmpeg", 5885 + DSTR => sub { "$dopts -y -i %i %o" }, 5886 + }, 5887 + 5888 + avconv => { 5889 + NAME => 'avconv', 5890 + DSTR => sub { "$dopts -y -i %i %o" }, 5891 + }, 5892 + 5893 + mplayer => { 5894 + NAME => "mplayer", 5895 + DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 5896 + }, 5897 + 5898 + sox => { 5899 + NAME => "sox", 5900 + DSTR => sub { "%i $dopts %o" }, 5901 + }, 5902 + }, 5903 + 5904 + TAGS => { 5905 + READ => 1, 5906 + WRITE => 1, 5907 + MODULE => "vorbiscomment", 5908 + }, 5909 + }, 5910 + 5911 + ogg => { 5912 + 5913 + DEFAULT_ENCODER => "oggenc", 5914 + DEFAULT_DECODER => "oggdec", 5915 + 5916 + ENCODER => { 5917 + oggenc => { 5918 + NAME => "oggenc", 5919 + ESTR => sub { 5920 + $opts = "--resample $freq -q $oggqual" if $defopts == 1; 5921 + $opts = '' if $defopts == 0; 5922 + "$eopts $opts %i -o %o" 5923 + }, 5924 + 5925 + PROMPT => { 5926 + FREQ => 1, 5927 + OGGQUAL => 1, 5928 + }, 5929 + }, 5930 + 5931 + ffmpeg => { 5932 + NAME => "ffmpeg", 5933 + ESTR => sub { 5934 + $opts = "-ab $bitrate.k -ar $freq -ac $channels -codec:a libvorbis" if $defopts == 1; 5935 + $opts = '' if $defopts == 0; 5936 + "-y -i %i $eopts $opts %o" 5937 + }, 5938 + 5939 + PROMPT => { 5940 + BITRATE => 1, 5941 + FREQ => 1, 5942 + CHANNELS => 1, 5943 + }, 5944 + }, 5945 + 5946 + avconv => { 5947 + NAME => 'avconv', 5948 + ESTR => sub { 5949 + $opts = "-ab $bitrate.k -ar $freq -ac $channels -codec:a libvorbis" if $defopts == 1; 5950 + $opts = '' if $defopts == 0; 5951 + "-y -i %i $eopts $opts %o" 5952 + }, 5953 + 5954 + PROMPT => { 5955 + BITRATE => 1, 5956 + FREQ => 1, 5957 + CHANNELS => 1, 5958 + }, 5959 + }, 5960 + 5961 + sox => { 5962 + NAME => "sox", 5963 + ESTR => sub { 5964 + $opts = "-r $freq -c $channels" if $defopts == 1; 5965 + $opts = '' if $defopts == 0; 5966 + "%i $eopts $opts %o" 5967 + }, 5968 + 5969 + PROMPT => { 5970 + FREQ => 1, 5971 + CHANNELS => 1, 5972 + }, 5973 + }, 5974 + }, 5975 + 5976 + DECODER => { 5977 + oggdec => { 5978 + NAME => "oggdec", 5979 + DSTR => sub { "$dopts %i --output %o" }, 5980 + }, 5981 + 5982 + ffmpeg => { 5983 + NAME => "ffmpeg", 5984 + DSTR => sub { "$dopts -y -i %i %o" }, 5985 + }, 5986 + 5987 + avconv => { 5988 + NAME => 'avconv', 5989 + DSTR => sub { "$dopts -y -i %i %o" }, 5990 + }, 5991 + 5992 + mplayer => { 5993 + NAME => "mplayer", 5994 + DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 5995 + }, 5996 + 5997 + sox => { 5998 + NAME => "sox", 5999 + DSTR => sub { "%i $dopts %o" }, 6000 + }, 6001 + }, 6002 + 6003 + TAGS => { 6004 + READ => 1, 6005 + WRITE => 1, 6006 + MODULE => "vorbiscomment", 6007 + }, 6008 + }, 6009 + 6010 + opus => { 6011 + 6012 + DEFAULT_ENCODER => "opusenc", 6013 + DEFAULT_DECODER => "opusdec", 6014 + 6015 + ENCODER => { 6016 + opusenc => { 6017 + NAME => 'opusenc', 6018 + ESTR => sub { 6019 + $opts = "--bitrate $bitrate" if $defopts == 1; 6020 + $opts = '' if $defopts == 0; 6021 + "$eopts $opts %i %o" 6022 + }, 6023 + PROMTP => { 6024 + BITRATE => 1, 6025 + }, 6026 + }, 6027 + }, 6028 + 6029 + DECODER => { 6030 + opusdec => { 6031 + NAME => 'opusdec', 6032 + DSTR => sub { "--force-wav %i %o" }, 6033 + PROMPT => { NONE => 0 }, 6034 + }, 6035 + }, 6036 + 6037 + TAGS => { 6038 + READ => 0, 6039 + WRITE => 0, 6040 + MODULE => undef, 6041 + }, 6042 + }, 6043 + 6044 + raw => { 6045 + 6046 + DEFAULT_ENCODER => "sox", 6047 + DEFAULT_DECODER => "sox", 6048 + 6049 + ENCODER => { 6050 + sox => { 6051 + NAME => 'sox', 6052 + ESTR => sub { 6053 + $opts = "-r $freq -c $channels" if $defopts == 1; 6054 + $opts = '' if $defopts == 0; 6055 + "%i $opts $eopts %o $effect" 6056 + }, 6057 + 6058 + PROMPT => { 6059 + FREQ => 1, 6060 + CHANNELS => 1, 6061 + }, 6062 + }, 6063 + }, 6064 + 6065 + DECODER => { 6066 + sox => { 6067 + NAME => 'sox', 6068 + DSTR => sub { "-w -s -r $freq -c $channels $dopts %i %o" }, 6069 + }, 6070 + }, 6071 + 6072 + TAGS => { 6073 + READ => 0, 6074 + WRITE => 0, 6075 + MODULE => undef, 6076 + }, 6077 + }, 6078 + 6079 + rm => { 6080 + 6081 + DEFAULT_ENCODER => 'ffmpeg', 6082 + DEFAULT_DECODER => 'ffmpeg', 6083 + 6084 + ENCODER => { 6085 + ffmpeg => { 6086 + NAME => 'ffmpeg', 6087 + ESTR => sub { 6088 + $opts = "-ar $freq -ac $channels" if $defopts == 1; 6089 + $opts = '' if $defopts == 0; 6090 + "-y -i %i $eopts $opts %o" 6091 + }, 6092 + 6093 + PROMPT => { 6094 + FREQ => 1, 6095 + CHANNELS => 1, 6096 + }, 6097 + }, 6098 + 6099 + avconv => { 6100 + NAME => 'avconv', 6101 + ESTR => sub { 6102 + $opts = "-ar $freq -ac $channels" if $defopts == 1; 6103 + $opts = '' if $defopts == 0; 6104 + "-y -i %i $eopts $opts %o" 6105 + }, 6106 + 6107 + PROMPT => { 6108 + FREQ => 1, 6109 + CHANNELS => 1, 6110 + }, 6111 + }, 6112 + }, 6113 + 6114 + DECODER => { 6115 + mplayer => { 6116 + NAME => 'mplayer', 6117 + DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 6118 + }, 6119 + 6120 + ffmpeg => { 6121 + NAME => 'ffmpeg', 6122 + DSTR => sub { "$dopts -y -i %i %o" }, 6123 + }, 6124 + 6125 + avconv => { 6126 + NAME => 'avconv', 6127 + DSTR => sub { "$dopts -y -i %i %o" }, 6128 + }, 6129 + }, 6130 + 6131 + TAGS => { 6132 + READ => 0, 6133 + WRITE => 0, 6134 + MODULE => undef, 6135 + }, 6136 + }, 6137 + 6138 + shn => { 6139 + 6140 + DEFAULT_ENCODER => "shorten", 6141 + DEFAULT_DECODER => "shorten", 6142 + 6143 + ENCODER => { 6144 + shorten => { 6145 + NAME => "shorten", 6146 + ESTR => sub { 6147 + $opts = "-c $channels" if $defopts == 1; 6148 + $opts = '' if $defopts == 0; 6149 + "$eopts $opts %i %o" 6150 + }, 6151 + PROMPT => { CHANNELS => 1 }, 6152 + }, 6153 + }, 6154 + 6155 + DECODER => { 6156 + shorten => { 6157 + NAME => "shorten", 6158 + DSTR => sub { "-x %i %o" }, 6159 + }, 6160 + }, 6161 + 6162 + TAGS => { 6163 + READ => 0, 6164 + WRITE => 0, 6165 + MODULE => undef, 6166 + }, 6167 + }, 6168 + 6169 + spx => { 6170 + 6171 + DEFAULT_ENCODER => "speexenc", 6172 + DEFAULT_DECODER => "speexdec", 6173 + 6174 + ENCODER => { 6175 + speexenc => { 6176 + NAME => "speexenc", 6177 + ESTR => sub { 6178 + $opts = "--quality $spxqual" if $defopts == 1; 6179 + $opts = '' if $defopts == 0; 6180 + "$eopts $opts %i %o" 6181 + }, 6182 + PROMPT => { SPXQUAL => 1 }, 6183 + }, 6184 + 6185 + ffmpeg => { 6186 + NAME => 'ffmpeg', 6187 + ESTR => sub { 6188 + $opts = "--bitrate $bitrate.k" if $defopts == 1; 6189 + $opts = '' if $defopts == 0; 6190 + "-y -i %i $eopts $opts %o" 6191 + }, 6192 + 6193 + PROMPT => { 6194 + BITRATE => 1, 6195 + }, 6196 + }, 6197 + 6198 + avconv => { 6199 + NAME => 'avconv', 6200 + ESTR => sub { 6201 + $opts = "--bitrate $bitrate.k" if $defopts == 1; 6202 + $opts = '' if $defopts == 0; 6203 + "-y -i $eopts $opts %o" 6204 + }, 6205 + PROMPT => { 6206 + BITRATE => 1, 6207 + }, 6208 + }, 6209 + }, 6210 + 6211 + DECODER => { 6212 + speexdec => { 6213 + NAME => "speexdec", 6214 + DSTR => sub { "$dopts %i %o" }, 6215 + }, 6216 + 6217 + ffmpeg => { 6218 + NAME => 'ffmpeg', 6219 + DSTR => sub { "$dopts -y -i %i %o" }, 6220 + }, 6221 + 6222 + avconv => { 6223 + NAME => 'avconv', 6224 + DSTR => sub { "$dopts -y -i %i %o" }, 6225 + }, 6226 + }, 6227 + 6228 + TAGS => { 6229 + READ => 1, 6230 + WRITE => 1, 6231 + MODULE => undef, 6232 + }, 6233 + }, 6234 + 6235 + tta => { 6236 + 6237 + DEFAULT_ENCODER => "ttaenc", 6238 + DEFAULT_DECODER => "ttaenc", 6239 + 6240 + ENCODER => { 6241 + ttaenc => { 6242 + NAME => "ttaenc", 6243 + ESTR => sub { "$eopts -e %i -o %o" }, 6244 + PROMPT => { NONE => 0, }, 6245 + }, 6246 + }, 6247 + 6248 + DECODER => { 6249 + ttaenc => { 6250 + NAME => "ttaenc", 6251 + DSTR => sub { "$dopts -d %i -o %o" }, 6252 + }, 6253 + 6254 + ffmpeg => { 6255 + NAME => "ffmpeg", 6256 + DSTR => sub { "$dopts -y -i %i %o" }, 6257 + }, 6258 + 6259 + avconv => { 6260 + NAME => 'avconv', 6261 + DSTR => sub { "$dopts -y -i %i %o" }, 6262 + }, 6263 + 6264 + mplayer => { 6265 + NAME => "mplayer", 6266 + DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 6267 + }, 6268 + }, 6269 + 6270 + TAGS => { 6271 + READ => 0, 6272 + WRITE => 0, 6273 + MODULE => undef, 6274 + }, 6275 + }, 6276 + 6277 + wav => { 6278 + 6279 + DEFAULT_ENCODER => "mv", 6280 + DEFAULT_DECODER => "cp", 6281 + 6282 + ENCODER => { 6283 + mv => { 6284 + NAME => "mv", 6285 + ESTR => sub { "%i %o" }, 6286 + PROMPT => { NONE => 0, }, 6287 + }, 6288 + }, 6289 + 6290 + DECODER => { 6291 + cp => { 6292 + NAME => "cp", 6293 + DSTR => sub { "%i %o" }, 6294 + } 6295 + }, 6296 + 6297 + TAGS => { 6298 + READ => 0, 6299 + WRITE => 0, 6300 + MODULE => undef, 6301 + }, 6302 + }, 6303 + 6304 + wv => { 6305 + 6306 + DEFAULT_ENCODER => "wavpack", 6307 + DEFAULT_DECODER => "wvunpack", 6308 + 6309 + ENCODER => { 6310 + wavpack => { 6311 + NAME => "wavpack", 6312 + ESTR => sub { "$eopts -h -y %i -o %o" }, 6313 + PROMPT => { NONE => 0, }, 6314 + }, 6315 + 6316 + ffmpeg => { 6317 + NAME => 'ffmpeg', 6318 + ESTR => sub { "-y -i %i $eopts %o" }, 6319 + PROMPT => { NONE => 0, }, 6320 + }, 6321 + 6322 + avconv => { 6323 + NAME => 'avconv', 6324 + ESTR => sub { "-y -i %i $eopts %o" }, 6325 + PROMPT => { NONE => 0, }, 6326 + }, 6327 + }, 6328 + 6329 + DECODER => { 6330 + wvunpack => { 6331 + NAME => "wvunpack", 6332 + DSTR => sub { "$dopts -y %i -o %o" }, 6333 + }, 6334 + 6335 + ffmpeg => { 6336 + NAME => "ffmpeg", 6337 + DSTR => sub { "$dopts -y -i %i %o" }, 6338 + }, 6339 + 6340 + avconv => { 6341 + NAME => 'avconv', 6342 + DSTR => sub { "$dopts -y -i %i %o" }, 6343 + }, 6344 + 6345 + mplayer => { 6346 + NAME => "mplayer", 6347 + DSTR => sub { "-vc null -vo null -ao pcm:file=%o %i" }, 6348 + }, 6349 + }, 6350 + 6351 + TAGS => { 6352 + READ => 1, 6353 + WRITE => 1, 6354 + MODULE => "Audio::Scan", 6355 + }, 6356 + }, 6357 +); 6358 + 6359 +# supported ffmpeg/avconv formats (decode only) 6360 +my @ffmpeg_codecs = ( "mmf", "ra", "wma" ); 6361 +my @ffmpeg_forks = ( "avconv", "ffmpeg" ); 6362 + 6363 +foreach my $fork (@ffmpeg_forks) { 6364 + 6365 + foreach my $codec (@ffmpeg_codecs) { 6366 + 6367 + $run{$codec}{DEFAULT_ENCODER} = $fork; 6368 + $run{$codec}{DEFAULT_DECODER} = $fork; 6369 + $run{$codec}{ENCODER}{$fork}{NAME} = $fork; 6370 + $run{$codec}{DECODER}{$fork}{NAME} = $fork; 6371 + $run{$codec}{DECODER}{$fork}{DSTR} = sub {"-y %i $dopts %o"}; 6372 + $run{$codec}{ENCODER}{$fork}{ESTR} = sub {"-y -i %i $eopts -ab $bitrate.k -ar $freq -ac $channels %o"}; 6373 + $run{$codec}{TAGS}{READ} = 0; 6374 + $run{$codec}{TAGS}{WRITE} = 0; 6375 + $run{$codec}{TAGS}{MODULE} = undef; 6376 + } 6377 + 6378 +} 6379 + 6380 +# support reading of WMA tags via Audio::Scan 6381 +$run{wma}{TAGS}{READ} = 1; 6382 +$run{wma}{TAGS}{MODULE} = "Audio::Scan"; 6383 + 6384 +# supported video to audio types 6385 +my @movie_codecs = ( 6386 + "rv", "asf", "avi", "divx", 6387 + "mkv", "mpg", "mpeg", "mov", 6388 + "ogm", "qt", "vcd", "vob", 6389 + "wmv", "flv", "svcd", "m4v", 6390 + "nsv", "nuv", "psp", "smk", 6391 + "ogv", "webm", 6392 + 6393 + # decode only audio formats 6394 + "vqf", "tak", 6395 + ); 6396 + 6397 +foreach (@movie_codecs) { 6398 + $run{$_}{DEFAULT_ENCODER} = undef; 6399 + $run{$_}{DEFAULT_DECODER} = "ffmpeg"; 6400 + $run{$_}{DECODER}{mplayer}{NAME} = "mplayer"; 6401 + $run{$_}{DECODER}{ffmpeg}{NAME} = "ffmpeg"; 6402 + $run{$_}{DECODER}{mplayer}{DSTR} = sub { "$dopts -vc null -vo null -ao pcm:file=%o %i" }; 6403 + $run{$_}{DECODER}{ffmpeg}{DSTR} = sub { "$dopts -i %i %o"; }; 6404 + $run{$_}{TAGS}{READ} = 0; 6405 + $run{$_}{TAGS}{WRITE} = 0; 6406 + $run{$_}{TAGS}{MODULE} = undef; 6407 +} 6408 + 6409 +# supported sndfile-convert formats 6410 +my @sndfile = ( 6411 + "pvf", "caf", "sf", "paf", "fap", "sd2", 6412 + "mat4", "mat5", "mat", "ircam", "w64", "nist", 6413 + "rf64", 6414 + ); 6415 + 6416 +foreach (@sndfile) { 6417 + 6418 + $run{$_}{DEFAULT_ENCODER} = "sndfile-convert"; 6419 + $run{$_}{DEFAULT_DECODER} = "sndfile-convert"; 6420 + $run{$_}{ENCODER}{"sndfile-convert"}{NAME} = "sndfile-convert"; 6421 + $run{$_}{DECODER}{"sndfile-convert"}{NAME} = "sndfile-convert"; 6422 + $run{$_}{ENCODER}{"sndfile-convert"}{ESTR} = sub { "$eopts %i %o" }; 6423 + $run{$_}{DECODER}{"sndfile-convert"}{DSTR} = sub { "$dopts %i %o" }; 6424 + $run{$_}{TAGS}{READ} = 0; 6425 + $run{$_}{TAGS}{WRITE} = 0; 6426 + $run{$_}{TAGS}{MODULE} = undef; 6427 +} 6428 + 6429 +# supported sox formats 6430 +my @sox_codecs = ( 6431 + "aiff", "aif", "au", "snd", "voc", 6432 + "smp", "avr", "cdr", "8svx", "amb", 6433 + "dat", "dvms", "f32", "f64", "fssd", 6434 + "gsrt", "hcom", "txw", "vms", "al", 6435 + "sou", "ima", "prc", "cvu", 6436 + "maud", 6437 + ); 6438 + 6439 +foreach (@sox_codecs) { 6440 + 6441 + $run{$_}{DEFAULT_ENCODER} = "sox"; 6442 + $run{$_}{DEFAULT_DECODER} = "sox"; 6443 + $run{$_}{ENCODER}{sox}{NAME} = "sox"; 6444 + $run{$_}{DECODER}{sox}{NAME} = "sox"; 6445 + $run{$_}{ENCODER}{sox}{ESTR} = sub { "%i -r $freq -c $channels $eopts %o $effect" }; 6446 + $run{$_}{DECODER}{sox}{DSTR} = sub { "%i $dopts %o" }; 6447 + $run{$_}{TAGS}{READ} = 0; 6448 + $run{$_}{TAGS}{WRITE} = 0; 6449 + $run{$_}{TAGS}{MODULE} = undef; 6450 + 6451 + $run{$_}{ENCODER}{sox}{PROMPT}{FREQ} = 1; 6452 + $run{$_}{ENCODER}{sox}{PROMPT}{CHANNELS} = 1; 6453 + 6454 +} 6455 + 6456 +# load codecs.conf file 6457 +load_codecs() if -e $codecs_conf; 6458 + 6459 +my $out_name = $outfile; 6460 +my $out_dir = $outdir; 6461 +my $first_message = 1; 6462 +my %files; 6463 +my $number = 0; 6464 + 6465 +# process all files and directories 6466 +sub proc_input { 6467 + 6468 + $to =~ tr/A-Z/a-z/; 6469 + 6470 + perror("bad_input","") unless(exists($run{$to})); 6471 + 6472 + proc_preserve_dir($dir[0]) if @dir and $preserve; # process recursive directory preservation (sends to proc_files 6473 + proc_dirs() if @dir and not $preserve; # process directories including recursively (sends to proc_files) 6474 + proc_files() if @file; # process all files 6475 + fork_files(); # start the conversion process. 6476 +} 6477 + 6478 +# process all files (all roads lead to rome) 6479 +sub proc_files { 6480 + 6481 + if (@file) { 6482 + 6483 + foreach my $i (sort(@file)) { 6484 + 6485 + my ($file, $dir, $ext) = fileparse("$i", qr/\.[^.]*/); 6486 + 6487 + $ext =~ s/^\.//; 6488 + $dir = rel2abs($dir); 6489 + $outdir = $dir if not defined($out_dir) and not $preserve; 6490 + $outdir = $out_dir if $preserve; 6491 + 6492 + my $if = $ext; 6493 + $if =~ tr/A-Z/a-z/; 6494 + 6495 + $only =~ tr/A-Z/a-z/ if $only; 6496 + 6497 + next if $only and $if ne $only; 6498 + 6499 + $encoder = $my_encoder if defined($my_encoder); 6500 + $decoder = $my_decoder if defined($my_decoder); 6501 + 6502 + $encoder = $run{$to}{DEFAULT_ENCODER} if not $my_encoder; 6503 + $decoder = $run{$if}{DEFAULT_DECODER} if not $my_decoder; 6504 + 6505 + if (-e "$file.$to" and not $overwrite) { 6506 + pnotice("overwrite","$file.$to",1); 6507 + $total_failed++; 6508 + next; 6509 + } 6510 + 6511 + if (check_input($file,$dir,$if) == 0) { 6512 + 6513 + pnotice("unk_encoder","$file.$ext",1), next unless(exists($run{$to}{ENCODER}{$encoder})); 6514 + pnotice("unk_decoder","$file.$ext",1), next unless(exists($run{$if}{DECODER}{$decoder})); 6515 + 6516 + get_visual_opts($to,$outdir) if $gui and not defined($first_run); 6517 + 6518 + $first_run = 1; 6519 + 6520 + perror("multi_out","") if (defined($out_name) and $#file gt 0 or defined($out_name) and @dir); 6521 + perror("no_outdir","") if (not -e $outdir and not -d $outdir); 6522 + 6523 + $outfile = "$file" if not $out_name; 6524 + 6525 + if ($keep and $if eq $to) { 6526 + system("cp -v \"$dir/$file.$ext\" \"$outdir/$outfile.$ext\"") if $outdir ne $dir and not -e "$outdir/$outfile.$ext"; 6527 + next if $outdir eq $dir; 6528 + } 6529 + 6530 + else { 6531 + $files{"FILE$number"}{FILE} = "$dir/$file"; 6532 + $files{"FILE$number"}{OUTF} = "$outdir/$outfile"; 6533 + $files{"FILE$number"}{EXT} = "$ext"; 6534 + $files{"FILE$number"}{NAME} = "$file"; 6535 + $files{"FILE$number"}{OUTD} = "$outfile"; 6536 + $files{"FILE$number"}{DECODER} = "$decoder"; 6537 + 6538 + $number++; 6539 + } 6540 + 6541 + } 6542 + } 6543 + } 6544 + undef(@file); 6545 +} 6546 + 6547 +# process directories and push all to @file arrary 6548 +sub proc_dirs { 6549 + 6550 + if (@dir) { 6551 + 6552 + my @tmp_dir = @dir; 6553 + undef(@dir); 6554 + $topdir = $tmp_dir[0]; 6555 + 6556 + if (not $recursive) { 6557 + 6558 + undef(@file); 6559 + 6560 + foreach my $d (@tmp_dir) { 6561 + 6562 + opendir(DIR, "$d") or perror("opening_dir","$d: $!"); 6563 + my @dir_files = readdir(DIR); 6564 + closedir(DIR); 6565 + perror("empty_dir","$d") if $#dir_files <= 1; 6566 + 6567 + foreach my $f (@dir_files) { 6568 + 6569 + if (not -d $f and not -d "$d/$f") { 6570 + push(@file, "$d/$f"); 6571 + undef($out_name); 6572 + } 6573 + } 6574 + } 6575 + 6576 + proc_files(); 6577 + return 0; 6578 + 6579 + } 6580 + 6581 + elsif ($recursive) { 6582 + 6583 + if (not $preserve) { 6584 + 6585 + undef(@file); 6586 + 6587 + foreach my $r (@tmp_dir) { 6588 + 6589 + $r = rel2abs($r); 6590 + 6591 + find ( sub { 6592 + my $rfile = $File::Find::name; 6593 + push(@file, $rfile) if not -d $rfile; 6594 + }, $r 6595 + ); 6596 + } 6597 + 6598 + proc_files(); 6599 + return 0; 6600 + 6601 + } 6602 + } 6603 + 6604 + } 6605 +} 6606 + 6607 +# preserve directory structuer (revised 10-7-2013) 6608 +my $out_dir_original = rel2abs($outdir) if $outdir and -d $outdir; 6609 + 6610 +sub proc_preserve_dir { 6611 + 6612 +$topdir = rel2abs($dir[0]); 6613 + 6614 +perror("no_outdir","") if not defined($out_dir_original); 6615 +perror("no_outdir","") if not -d $out_dir_original; 6616 + 6617 +undef(@file); # clear the array before we begin. 6618 + 6619 +find ( sub { 6620 + my $val = $File::Find::name; 6621 + $val =~ s/(\$)/\\\$/g; 6622 + 6623 + if ($val ne $topdir) { 6624 + 6625 + $val =~ s/$topdir\///; 6626 + 6627 + # create mirrored directories in output directory 6628 + if (not -f fileparse("$topdir/$val") and not -d "$out_dir_original/$val") { 6629 + say "creating directory $out_dir_original/$val" if not -f "$topdir/$val" and $verbose; 6630 + mkdir("$out_dir_original/$val", 0755) if not -f "$topdir/$val"; 6631 + } 6632 + 6633 + # this will list all files in their original directories 6634 + if (-f "$topdir/$val") { 6635 + say "$lang{debug} pushing to \@file: $topdir/$val" if $debug == 1; 6636 + push(@file, "$topdir/$val"); 6637 + } 6638 + 6639 + # set $out_dir to the 6640 + $out_dir = "$out_dir_original/" . dirname($val) if -f "$topdir/$val"; 6641 + 6642 + # send file, and output dir to proc_files(); 6643 + proc_files(); 6644 + } 6645 + 6646 + }, $topdir 6647 + ); 6648 +} 6649 + 6650 +# convert input to destination format 6651 +sub convert { 6652 + 6653 + my ($inf, $outf, $infmt, $iname, $oname, $dec) = @_; 6654 + 6655 + my $if = $infmt; 6656 + $if =~ tr/A-Z/a-z/; 6657 + 6658 + clear_tag_hash() if not $rip; 6659 + 6660 + # catch ^C. will have to be pressed repeatedly to exit the process. 6661 + $SIG{INT} = sub { 6662 + unlink("$outf.$$.wav"); 6663 + kill 9, $$; 6664 + }; 6665 + 6666 + # check to see if encoder/decoder exists. if not, see if we have one 6667 + # that supports the desired input/output formats. 6668 + $decoder = $dec; 6669 + check_encoder(); 6670 + check_decoder($infmt); 6671 + 6672 + my $decode_string = $run{$if}{DECODER}{$decoder}{DSTR}->(); 6673 + $decode_string =~ s/%i/\"$inf.$infmt\"/; 6674 + $decode_string =~ s/%o/\"$outf.$$.wav\"/; 6675 + $decode_string =~ s/(\$|\\)/\\$1/g; 6676 + 6677 + pnotice("debug","\n$run{$if}{DECODER}{$decoder}{NAME} $decode_string", 2) if $dryrun; 6678 + 6679 + # decode input file to temporary wav 6680 + system("$run{$if}{DECODER}{$decoder}{NAME} $decode_string $silent") if not $dryrun; 6681 + 6682 + # remove temporary wav file and die if decode fails 6683 + if ($? > 0) { 6684 + unlink("$outf.$$.wav") if -e "$outf.$$.wav"; 6685 + say ""; 6686 + $banner = 0; 6687 + pnotice("decode_failed","$inf.$infmt: try with --verbose",1); 6688 + return 1; 6689 + } 6690 + 6691 + # normalize wav file before encoding to output format 6692 + perror("no_app","normalize") if $normalize and not `which normalize 2>/dev/null`; 6693 + system("normalize $nopts \"$outf.$$.wav\"") if $normalize; 6694 + 6695 + # copy meta-data from input file to %tag_name 6696 + read_tags("$inf.$infmt", "$if") if $run{$if}{TAGS}{READ} == 1 and not $dryrun; 6697 + 6698 + my $tag_opts = format_tags($to); # tag options for mp4/m4a/m4b/mpc/mpp/bonk/spx/wv 6699 + 6700 + my $encode_string = $run{$to}{ENCODER}{$encoder}{ESTR}->(); 6701 + $encode_string =~ s/%i/$tag_opts \"$outf.$$.wav\"/ if $to =~ /mpc|mpp|mp4|m4a/ and $encoder eq "faac" or $encoder eq "mpcenc"; 6702 + $encode_string =~ s/%i/\"$outf.$$.wav\" $tag_opts/ if $to =~ /mpc|mpp|mp4|m4a/ and $encoder eq "ffmpeg" or $encoder eq "avconv"; 6703 + $encode_string =~ s/%i/\"$outf.$$.wav\"/ if $to !~ /mpc|mpp|mp4|m4a/; 6704 + $encode_string =~ s/%o/$tag_opts \"$outf.$to\"/ if $tag_opts ne " " and $to !~ /mpc|mpp|mp4|m4a/; 6705 + $encode_string =~ s/%o/\"$outf.$to\"/ if $tag_opts eq " " or $to =~ /mpc|mpp|mp4|m4a/; 6706 + $encode_string =~ s/(\$|\\)/\\$1/g; 6707 + 6708 + # read tag options from command line if present 6709 + get_user_tags(); 6710 + 6711 + pnotice("debug","\n$run{$to}{ENCODER}{$encoder}{NAME} $encode_string", 2) if $dryrun; 6712 + 6713 + # encode temporary WAV to desired output format. 6714 + system("$run{$to}{ENCODER}{$encoder}{NAME} $encode_string $silent") if not $dryrun; 6715 + 6716 + # remove partially encoded output file and temporary wav if encoding fails 6717 + if ($? > 0) { 6718 + unlink("$outf.$to") if -e "$outf.$to"; 6719 + unlink("$outf.$$.wav") if -e "$outf.$$.wav"; 6720 + say ""; 6721 + $banner = 0; 6722 + pnotice("encode_failed","$outf.$to: $?",1); 6723 + return 1; 6724 + } 6725 + 6726 + # write meta-data to output file from %tag_name hash 6727 + write_tags("$outf.$to", "$to") if $run{$to}{TAGS}{WRITE} == 1 and $tag_opts eq " " and not $dryrun; 6728 + 6729 + unlink("$outf.$$.wav") if not $dryrun; 6730 + unlink("$inf.$infmt") if $delete and not $dryrun; 6731 + 6732 + pnotice("removed_tmp","$outf.$$.wav","2") if $verbose; 6733 + pnotice("removed_src","$inf.$infmt", "2") if $delete and $verbose; 6734 +} 6735 + 6736 +$pm->run_on_finish 6737 +( sub { 6738 + my $pid = shift; 6739 + my $exit_code = shift; 6740 + my $ident = shift; 6741 + 6742 + if (-e "$ident.$to") { 6743 + $total_converted++; 6744 + } 6745 + say "$lang{debug} PID: $pid EXIT_CODE: $exit_code IDENTITY: \"$ident.$to\"" if $debug == 1; 6746 + } 6747 +); 6748 + 6749 +# convert all files that have been placed in the %files hash through various procs* 6750 +sub fork_files { 6751 + 6752 + say "\n$name - $version\n" if not $gui and $banner == 1; 6753 + 6754 + foreach (sort(keys(%files))) 6755 + { 6756 + $pm->start($files{$_}{OUTF}) and next; 6757 + my $msg = "$lang{converting}" . " " . basename($files{$_}{FILE}) . ".$files{$_}{EXT} -> $to"; 6758 + say "$msg" if not $gui; 6759 + system("kdialog --icon $icon_path --title \"$name\" --passivepopup \"$msg\" 10 &") if $gui and $kde; 6760 + system("notify-send \"$name\" \"$msg\" -t 35 -i $icon_path &") if $gui and $gnome; 6761 + convert("$files{$_}{FILE}","$files{$_}{OUTF}","$files{$_}{EXT}","$files{$_}{NAME}","$files{$_}{OUTD}","$files{$_}{DECODER}"); 6762 + $pm->finish; 6763 + } 6764 + 6765 + $pm->wait_all_children; 6766 + $total_failed = $number - $total_converted if $total_converted < $number; 6767 + 6768 + my $finished_msg = "\n$lang{total_converted} $total_converted, $lang{failed} $total_failed\n"; 6769 + 6770 + say "$finished_msg" if not $gui; 6771 + system("kdialog --icon $icon_path --title \"$name\" --passivepopup \"$finished_msg\" 10 &") if $gui and $kde; 6772 + system("notify-send \"$name\" \"$finished_msg\" -t 35 -i $icon_path &") if $gui and $gnome; 6773 + 6774 +} 6775 + 6776 +# if the default encoder does not exist, cycle through the supported 6777 +# encoders until we find one that does. 6778 +sub check_encoder { 6779 + 6780 + if (not `which $encoder 2>/dev/null`) { 6781 + my $first_encoder = $encoder; 6782 + foreach (keys %{$run{$to}{ENCODER}}) { $encoder = $_ and return if `which $_ 2>/dev/null`; } 6783 + perror("no_encode_app","$to") if $encoder eq $first_encoder; 6784 + } 6785 + 6786 + else { return 0; } 6787 +} 6788 + 6789 +# if the default decoder does not exist, cycle through the supported 6790 +# decoders until we find one that does. 6791 +sub check_decoder { 6792 + 6793 + my $from = shift; 6794 + 6795 + if (not `which $decoder 2>/dev/null`) { 6796 + my $first_decoder = $decoder; 6797 + foreach (keys %{$run{$from}{DECODER}}) { $decoder = $_ and return if `which $_ 2>/dev/null`; } 6798 + perror("no_decode_app","$from") if $decoder eq $first_decoder; 6799 + } 6800 + 6801 + else { return 0; } 6802 +} 6803 + 6804 +# make sure encoding/decoding is supported. 6805 +sub check_input { 6806 + 6807 + my $file = shift; 6808 + my $dir = shift; 6809 + my $ext = shift; 6810 + 6811 + perror("no_encoder","$to") unless(defined($run{$to}{ENCODER})); 6812 + 6813 + unless(defined($run{$ext}{DECODER})) { 6814 + pnotice("no_decoder","$ext",2) if $verbose or not $only; 6815 + $total_failed++; 6816 + return 1; 6817 + } 6818 + 6819 + return 0; 6820 +} 6821 + 6822 +######################################## 6823 +# GUI options for KDE & Gnome Plugins # 6824 +######################################## 6825 + 6826 +my $kdialog = "kdialog --title \"$name\""; 6827 +my $zenity = "zenity --title \"$name\" --list --radiolist --width 100 --height 300 --column '' --column "; 6828 + 6829 +sub get_visual_opts { 6830 + 6831 + my ($to_fmt,$od) = @_; 6832 + 6833 + # escape illegal characters in output directory name 6834 + $od =~ s/('|\(|\)|"|\\)/\\$1/g; 6835 + 6836 + $outdir = `kdialog --getexistingdirectory $od` if $config{KDE_DIR} == 1 and $kde; 6837 + $outdir = `zenity --title \"$lang{gui_outdir}\" --file-selection --directory --filename=\`pwd\`` if $config{ZEN_DIR} == 1 and $gnome; 6838 + 6839 + chomp($outdir); 6840 + $out_dir = $outdir; 6841 + exit(1) if not $outdir; 6842 + 6843 + if ($config{KDE_OPTS} == 1 or $config{ZEN_OPTS} == 1) { 6844 + foreach (keys %{$run{$to_fmt}{ENCODER}{$encoder}{PROMPT}}) { 6845 + prompt_user($_); 6846 + } 6847 + } 6848 +} 6849 + 6850 +sub prompt_user { 6851 + 6852 + my $opt = shift; 6853 + 6854 + given ($opt) { 6855 + 6856 + when (/^BITRATE/) { 6857 + $bitrate = `$kdialog --default $bitrate --combobox \"$lang{gui_bitrate}\" 56 112 128 160 192 256 320` if $kde; 6858 + $bitrate = `$zenity \"$lang{gui_bitrate}\" FALSE 56 FALSE 112 FALSE 128 FALSE 160 TRUE 192 FALSE 256 FALSE 320` if $gnome; 6859 + chomp($bitrate); 6860 + exit(1) if not $bitrate; 6861 + } 6862 + 6863 + when (/^FREQ/) { 6864 + $freq = `$kdialog --default $freq --combobox \"$lang{gui_freq}\" 32000 44100 48000` if $kde; 6865 + $freq = `$zenity \"$lang{gui_freq}\" FALSE 32000 TRUE 44100 FALSE 48000` if $gnome; 6866 + chomp($freq); 6867 + exit(1) if not $freq; 6868 + } 6869 + 6870 + when (/^CHANNELS/) { 6871 + $channels = `$kdialog --default $channels --combobox \"$lang{gui_chans}\" 1 2` if $kde; 6872 + $channels = `$zenity \"$lang{gui_chans}\" FALSE 1 TRUE 2` if $gnome; 6873 + chomp($channels); 6874 + exit(1) if not $channels; 6875 + } 6876 + 6877 + when (/^FCOMP/) { 6878 + $fcomp = `$kdialog --default $fcomp --combobox \"$lang{gui_fcomp}\" 0 1 2 3 4 5 6 7 8` if $kde; 6879 + $fcomp = `$zenity \"$lang{gui_fcomp}\" FALSE 0 FALSE 1 TRUE 2 FALSE 3 FALSE 4 FALSE 5 FALSE 6 FALSE 7 FALSE 8` if $gnome; 6880 + chomp($fcomp); 6881 + exit(1) if not $fcomp; 6882 + } 6883 + 6884 + when (/^ACOMP/) { 6885 + $acomp = `$kdialog --default $acomp --combobox \"$lang{gui_acomp}\" 1000 2000 3000 4000 5000` if $kde; 6886 + $acomp = `$zenity \"$lang{gui_acomp}\" FALSE 1000 FALSE 2000 TRUE 3000 FALSE 4000 FALSE 5000` if $gnome; 6887 + chomp($acomp); 6888 + exit(1) if not $acomp; 6889 + } 6890 + 6891 + when (/^OGGQUAL/) { 6892 + $oggqual = `$kdialog --default $oggqual --combobox \"$lang{gui_oggqual}\" 0 1 2 3 4 5 6 7 8 9 10` if $kde; 6893 + $oggqual = `$zenity \"$lang{gui_oggqual}\" FALSE 0 FALSE 1 FALSE 2 TRUE 3 FALSE 4 FALSE 5 FALSE 6 FALSE 7 FALSE 8 FALSE 9 FALSE 10` if $gnome; 6894 + chomp($oggqual); 6895 + exit(1) if not $oggqual; 6896 + } 6897 + 6898 + when (/^SPXQUAL/) { 6899 + $spxqual = `$kdialog --default $spxqual --combobox \"$lang{gui_spxqual}\" 0 1 2 3 4 5 6 7 8 9 10` if $kde; 6900 + $spxqual = `$zenity \"$lang{gui_spxqual}\" FALSE 0 FALSE 1 FALSE 2 FALSE 3 FALSE 4 FALSE 5 FALSE 6 FALSE 7 TRUE 8 FALSE 9 FALSE 10` if $gnome; 6901 + chomp($spxqual); 6902 + exit(1) if not $spxqual; 6903 + } 6904 + 6905 + when (/^AACQUAL/) { 6906 + $aacqual = `$kdialog --default $aacqual --combobox \"$lang{gui_aacqual}\" 100 200 300 400 500` if $kde; 6907 + $aacqual = `$zenity \"$lang{gui_aacqual}\" TRUE 100 FALSE 200 FALSE 300 FALSE 400 FALSE 500` if $gnome; 6908 + chomp($aacqual); 6909 + exit(1) if not $aacqual; 6910 + } 6911 + 6912 + when (/^MPCQUAL/) { 6913 + $mpcqual = `$kdialog --default $mpcqual --combobox \"$lang{gui_mpcqual}\" thumb radio standard xtreme insane braindead` if $kde; 6914 + $mpcqual = `$zenity \"$lang{gui_mpcqual}\" FALSE thumb TRUE radio FALSE standard FALSE xtreme FALSE insane FALSE braindead` if $gnome; 6915 + chomp($mpcqual); 6916 + exit(1) if not $mpcqual; 6917 + } 6918 + 6919 + when (/^OFMODE/ ) { 6920 + $ofmode = `$kdialog --default $ofmode --combobox \"$lang{gui_ofmode}\" fast normal high extra best highnew extranew bestnew` if $kde; 6921 + $ofmode = `$zenity \"$lang{gui_ofmode}\" FALSE fast TRUE normal FALSE high FALSE extra FALSE best FALSE highnew FALSE extranew FALSE bestnew` if $gnome; 6922 + chomp($ofmode); 6923 + exit(1) if not $ofmode; 6924 + } 6925 + 6926 + when (/^OFOPT/) { 6927 + $ofopt = `$kdialog --default $ofopt --combobox \"$lang{gui_ofopt}\" none fast normal high best` if $kde; 6928 + $ofopt = `$zenity \"$lang{gui_ofopt}\" FALSE none TRUE fast FALSE normal FALSE high FALSE best` if $gnome; 6929 + chomp($ofopt); 6930 + exit(1) if not $ofopt; 6931 + } 6932 + 6933 + when (/^BRATIO/) { 6934 + $bratio = `$kdialog --default $bratio --combobox \"$lang{gui_bratio}\" 1 2 3 4 5` if $kde; 6935 + $bratio = `$zenity \"$lang{gui_bratio}\" FALSE 1 TRUE 2 FALSE 3 FALSE 4 FALSE 5` if $gnome; 6936 + chomp($bratio); 6937 + exit(1) if not $bratio; 6938 + } 6939 + 6940 + when (/^BQUANL/) { 6941 + $bquanl = `$kdialog --default $bquanl --combobox \"$lang{gui_bquanl}\" 1.00 1.25 1.50 1.75 2.00` if $kde; 6942 + $bquanl = `$zenity \"$lang{gui_bquanl}\" TRUE 1.00 FALSE 1.25 FALSE 1.50 FALSE 1.75 FALSE 2.00` if $gnome; 6943 + chomp($bquanl); 6944 + exit(1) if not $bquanl; 6945 + } 6946 + 6947 + when (/^BPSIZE/) { 6948 + $bpsize = `$kdialog --default $bpsize --combobox \"$lang{gui_bpsize}\" 10 128` if $kde; 6949 + $bpsize = `$zenity \"$lang{gui_bpsize}\" FALSE 10 TRUE 128` if $gnome; 6950 + chomp($bpsize); 6951 + exit(1) if not $bpsize; 6952 + } 6953 + 6954 + default { return 0; } 6955 + } 6956 + 6957 +} 6958 + 6959 +# all copied tags will be stored here for furture use 6960 +my %tag_name = 6961 +( 6962 + title => undef, 6963 + track => undef, 6964 + artist => undef, 6965 + album => undef, 6966 + comment => undef, 6967 + year => undef, 6968 + genre => undef, 6969 +); 6970 + 6971 +# override tags read from input file if any of the tagging 6972 +# options are specified by the user during conversion. 6973 +sub get_user_tags 6974 +{ 6975 + $tag_name{title} = $title if $title; 6976 + $tag_name{track} = $track if $track; 6977 + $tag_name{artist} = $artist if $artist; 6978 + $tag_name{album} = $album if $album; 6979 + $tag_name{comment} = $comment if $comment; 6980 + $tag_name{year} = $year if $year; 6981 + $tag_name{genre} = $genre if $genre; 6982 +} 6983 + 6984 +# the formats MP4/M4A/M4B/MPC/MPP/WV/BONK have no tag writing module. 6985 +# tags therefore have to be written during encode via various 6986 +# command line args. 6987 +sub format_tags { 6988 + 6989 + my $type = shift; 6990 + 6991 + given ($type) { 6992 + 6993 + when (/^mp4$|^m4a$|^m4b$/) { 6994 + 6995 + if ($run{$to}{ENCODER}{$encoder}{NAME} eq "ffmpeg" or $run{$to}{ENCODER}{$encoder}{NAME} eq "avconv") { 6996 + 6997 + $tag_name{track} = 0 if not $tag_name{track}; 6998 + $tag_name{year} = 0 if not $tag_name{year}; 6999 + 7000 + return "-metadata TITLE=\"$tag_name{title}\" -metadata TRACK=\"$tag_name{track}\" -metadata ARTIST=\"$tag_name{artist}\" -metadata ALBUM=\"$tag_name{album}\" -metadata COMMENT=\"$tag_name{comment}\" -metadata YEAR=\"$tag_name{year}\" -metadata GENRE=\"$tag_name{genre}\""; 7001 + 7002 + } else { 7003 + 7004 + return "--title \"$tag_name{title}\" --track \"$tag_name{track}\" --artist \"$tag_name{artist}\" --album \"$tag_name{album}\" --comment \"$tag_name{comment}\" --year \"$tag_name{year}\" --genre \"$tag_name{genre}\""; 7005 + 7006 + } 7007 + } 7008 + 7009 + when (/^mpc$|^mpp$/) { return "--artist \"$tag_name{artist}\" --title \"$tag_name{title}\" --album \"$tag_name{album}\" --track \"$tag_name{track}\" --genre \"$tag_name{genre}\" --year \"$tag_name{year}\" --comment \"$tag_name{comment}\""; } 7010 + when (/^wv$/) { return "-w \"Title=$tag_name{title}\" -w \"Track=$tag_name{track}\" -w \"Artist=$tag_name{artist}\" -w \"Album=$tag_name{album}\" -w \"Comment=$tag_name{comment}\" -w \"Year=$tag_name{year}\" -w \"Genre=$tag_name{genre}\""; } 7011 + when (/^bonk$/) { return "-t \"$tag_name{title}\" -a \"$tag_name{artist}\" -c \"$tag_name{comment}\""; } 7012 + when (/^spx$/) { return "--author \"$tag_name{artist}\" --title \"$tag_name{title}\" --comment \"year=$tag_name{year}\" --comment \"tracknumber=$tag_name{track}\" --comment \"album=$tag_name{album}\" --comment \"genre=$tag_name{genre}\" --comment \"comment=$tag_name{comment}\""; } 7013 + 7014 + default { return " "; } 7015 + } 7016 +} 7017 + 7018 +# meta-data is read based on input file extension. 7019 +# all tags which are present will be copied to 7020 +# the %tag_name hash. 7021 +sub read_tags { 7022 + 7023 + my $in_file = shift; 7024 + my $in_format = shift; 7025 + 7026 + my $tag_module = $run{$in_format}{TAGS}{MODULE}; 7027 + 7028 + given ($in_format) { 7029 + 7030 + when (/^mp3$|^mp3hd$/) { 7031 + my $mp3tag = $tag_module->new($in_file); 7032 + my @tags = $mp3tag->autoinfo(); 7033 + 7034 + $tag_name{title} = "$tags[0]" if $tags[0]; 7035 + $tag_name{track} = "$tags[1]" if $tags[1]; 7036 + $tag_name{artist} = "$tags[2]" if $tags[2]; 7037 + $tag_name{album} = "$tags[3]" if $tags[3]; 7038 + $tag_name{comment} = "$tags[4]" if $tags[4]; 7039 + $tag_name{year} = "$tags[5]" if $tags[5]; 7040 + $tag_name{genre} = "$tags[6]" if $tags[6]; 7041 + 7042 + return 0; 7043 + } 7044 + 7045 + when (/^ogg$|^oga$/) { 7046 + my $ogg_tag = Audio::Scan->scan_tags($in_file)->{tags}; 7047 + 7048 + $tag_name{title} = $ogg_tag->{TITLE} if $ogg_tag->{TITLE}; 7049 + $tag_name{track} = $ogg_tag->{TRACKNUMBER} if $ogg_tag->{TRACKNUMBER}; 7050 + $tag_name{artist} = $ogg_tag->{ARTIST} if $ogg_tag->{ARTIST}; 7051 + $tag_name{album} = $ogg_tag->{ALBUM} if $ogg_tag->{ALBUM}; 7052 + $tag_name{comment} = $ogg_tag->{COMMENT} if $ogg_tag->{COMMENT}; 7053 + $tag_name{year} = $ogg_tag->{YEAR} if $ogg_tag->{YEAR}; 7054 + $tag_name{genre} = $ogg_tag->{GENRE} if $ogg_tag->{GENRE}; 7055 + 7056 + return 0; 7057 + } 7058 + 7059 + when (/^spx$/) { 7060 + my $pid = open(SPX, "speexdec \"$in_file\" tmp1-$$.wav 2>&1 |") or perror("opening_file","$in_file"); 7061 + my @data = <SPX>; 7062 + @data = grep(!/^$|^#/, @data); 7063 + 7064 + close(SPX); 7065 + 7066 + foreach (@data) { 7067 + 7068 + next unless /=/; 7069 + chomp; 7070 + 7071 + my ($k, $v) = split /=/; 7072 + $k =~ tr/A-Z/a-z/; 7073 + $tag_name{$k} = $v if exists($tag_name{$k}); 7074 + $tag_name{artist} = $v if $k =~ /^author/i; 7075 + $tag_name{track} = $v if $k =~ /^tracknumber/i; 7076 + } 7077 + 7078 + unlink("tmp-$$.wav"); 7079 + return 0; 7080 + } 7081 + 7082 + when (/^flac$|^fla$/) { 7083 + my $flac_tag = Audio::Scan->scan_tags($in_file)->{tags}; 7084 +