執行
virsh net-start default
分類
彙整
- 2023 年 10 月 (3)
- 2021 年 4 月 (1)
- 2021 年 2 月 (13)
- 2021 年 1 月 (5)
- 2020 年 12 月 (63)
- 2020 年 6 月 (1)
執行
virsh net-start default
#!/usr/bin/perl -w # Filename: ogg2mp3 # Author: David Ljung Madison <DaveSource.com> # See License: http://MarginalHacks.com/License # Description: Converts ogg to mp3, with artist/title/info # Ideas from: Joseph E. O'Doherty <odoherty.net> # id3v2 from: Javier Salazar Loyola <jsalazar cern ch> use strict; use File::Spec; ################################################## # Setup the variables ################################################## my $PROGNAME = $0; $PROGNAME =~ s|.*/||; my $TMPFILE = File::Spec->catfile( File::Spec->tmpdir(), "$PROGNAME.$$.wav" ); ######################### # Ogg decoder ######################### # Different versions of ogg123 handle files differently! Argh! #my $OGGDEC = "ogg123 -d wav -o file:$TMPFILE"; #my $OGGDEC = "ogg123 -d wav -f $TMPFILE"; # Just use oggdec instead. # Add -Q for quiet.. my $OGGDEC = "oggdec -o $TMPFILE"; ######################### # MP3 encoder # Choose your favorite.. ######################### my $MP3ENC = "lame"; #my $MP3ENC = "notlame"; my $OGGINFO = "ogginfo"; my $ID3TOOL = "id3tool"; my $ID3V2 = "id3v2"; ################################################## # Usage ################################################## sub usage { foreach my $msg (@_) { print STDERR "ERROR: $msg\n"; } print <<USAGE; Usage:\t$PROGNAME [-d] [-o <dir>] [<playlist.m3u> | <ogg> ..] Converts ogg to mp3 -d Set debug mode -o <dir> Specify output directory -id3v2 Use id3v2 instead of id3tool for tagging -keepdir Keep directory structure inside specified -o directory -f Force rewriting of mp3 if it already exists --enc_opts .. -- Options for encoding tool --dec_opts .. -- Options for decoding tool Example: $PROGNAME --enc_opts -b 64 -- *.ogg USAGE exit -1; } sub get_dashdash { my @dash; while ($#ARGV>=0) { my $arg=shift(@ARGV); last if $arg eq "--"; push(@dash,$arg); } @dash; } sub contents { my ($f) = @_; open(F,"<$f") || usage("Couldn't read playlist [$f]"); my @f = <F>; close F; chomp @f; @f; } sub parse_args { my $opt = {}; my $outdir; my @oggs; while (my $arg=shift(@ARGV)) { if ($arg =~ /^-h$/) { usage(); } if ($arg =~ /^-d$/) { $MAIN::DEBUG=1; next; } if ($arg =~ /^-o$/) { $opt->{out}=shift @ARGV; next; } if ($arg =~ /^-id3v2$/) { $opt->{id3v2}=1; next; } if ($arg =~ /^-keepdir$/) { $opt->{keepdir}=1; next; } if ($arg =~ /^-f$/) { $opt->{force}=1; next; } if ($arg =~ /^--enc_opts$/) { push(@{$opt->{enc_opts}}, get_dashdash()); next; } if ($arg =~ /^--dec_opts$/) { push(@{$opt->{dec_opts}}, get_dashdash()); next; } if ($arg =~ /^-/) { usage("Unknown option: $arg"); } push(@oggs, ($arg =~ /\.m3u$/) ? contents($arg) : $arg); } usage("No oggs specified") unless @oggs; ($opt,@oggs); } sub debug { return unless $MAIN::DEBUG; foreach my $msg (@_) { print STDERR "[$PROGNAME] $msg\n"; } } ################################################## # Genre code ################################################## my @GENRES; sub get_genres() { return if @GENRES; open(G,"$ID3TOOL -l|") || die("[$PROGNAME] Can't get genre info: [$ID3TOOL -l]\n"); while (<G>) { push(@GENRES,$1) if (/^(\S.*\S)\s+\|/); } close G; } sub get_genre { my ($genre) = @_; return undef unless $genre; get_genres; my @g = grep(/^$genre$/i, @GENRES); return $g[0] if @g; @g = grep(/$genre/i, @GENRES); print STDERR "[$PROGNAME] Multiple genre matches [$genre -> @g]\n" if $#g>0; return $g[0] if @g; # No match print STDERR "[$PROGNAME] Unknown genre [$genre]\n"; return undef; } ################################################## # Main code ################################################## sub ogginfo { my ($ogg) = @_; # Get ogg tags open(TAGS,"$OGGINFO \Q$ogg\E |") || die("[$PROGNAME] Couldn't run ogginfo [$ogg]\n"); my %i; while(<TAGS>) { chomp; next if /^\s*$/; ## The old way: # die("[$PROGNAME] Bad ogginfo: [$_]") unless /^\s*(\S+)=(.*)$/; # $i{$1} .= $2; ## Old ogginfo: ## "key=value" ## ## New ogginfo: ## "Some comment stuff..." ## " key=value" ## ## I suppose I could parse the entire output to see if it's new or ## old, but it looks like the comments never have '=' in them, and who ## cares if it does anyways? So, we'll just use a loose regexp: if (/^\s*(\S+)=(.*)$/) { my ($tag,$val) = (lc($1),$2); $i{$tag} .= $val } } close(TAGS); \%i; } sub dir { my ($path) = @_; return undef unless $path =~ m|/|; $path =~ s|/+$||; $path =~ s|/[^/]+$||; $path; } sub mkdirOf { my ($path) = @_; return if !defined $path || -d $path; mkdirOf(dir($path)); mkdir($path) } sub set_mp3info { my ($opt,$mp3,$info) = @_; my $tool = $opt->{id3v2} ? $ID3V2 : $ID3TOOL; # Flags that are different my $trackFlag = $opt->{id3v2} ? 'T' : 'c'; my $albumFlag = $opt->{id3v2} ? 'A' : 'a'; my $artistFlag = $opt->{id3v2} ? 'a' : 'r'; my $commentFlag = $opt->{id3v2} ? 'c' : 'n'; my $genreFlag = $opt->{id3v2} ? 'g' : 'G'; my $legitDate = $opt->{id3v2} ? '^[\d+-\/]$' : '^\d+$'; my $set; # Newer id3tool supports setting track #$set .= " -n \QTrack $info->{tracknumber}\E" if $info->{tracknumber} && !$info->{comment}; $set .= " -$trackFlag \Q$info->{tracknumber}\E" if $info->{tracknumber}; $set .= " -t \Q$info->{title}\E" if $info->{title}; $set .= " -$albumFlag \Q$info->{album}\E" if $info->{album}; $set .= " -$artistFlag \Q$info->{artist}\E" if $info->{artist}; $set .= " -$commentFlag \Q$info->{comment}\E" if $info->{comment}; my $genre = $opt->{id3v2} ? $info->{genre} : get_genre($info->{genre}); $set .= " -$genreFlag \Q$genre\E" if $genre; $set .= " -y \Q$info->{date}\E" if $info->{date} && $info->{date} =~ /$legitDate/; return print STDERR "[$PROGNAME] No tag info for [$mp3]\n" unless $set; system("$tool $set \Q$mp3\E"); print STDERR "[$PROGNAME] Errors from:\n $tool $set $mp3\n $!\n" if $?; } sub ogg2mp3 { my ($opt,$ogg) = @_; my $mp3 = $ogg; $mp3 =~ s/(\.ogg)?$/.mp3/i; # Handle outdir if specified if ($opt->{out}) { $mp3 =~ s|.*/||g unless $opt->{keepdir}; $mp3 = "$opt->{out}/$mp3"; } return print STDERR "[$PROGNAME] Skipping mp3 (already exists) [$mp3]\n" if !$opt->{force} && -f $mp3; # Make sure the directory exists mkdirOf(dir($mp3)); my $dec_opts = $opt->{dec_opts} ? join(' ',@{$opt->{dec_opts}}) : ""; my $enc_opts = $opt->{enc_opts} ? join(' ',@{$opt->{enc_opts}}) : ""; print "$ogg -> $mp3\n"; # Decode # system("$OGGDEC \Q$ogg\E | $MP3ENC - \Q$mp3\E"); # print STDERR "[$PROGNAME] Errors from:\n $OGGDEC \Q$ogg\E | $MP3ENC - \Q$mp3\E\n $!\n" # if $?; system("$OGGDEC $dec_opts \Q$ogg\E"); print STDERR "[$PROGNAME] Errors from:\n $OGGDEC \Q$ogg\E\n $!\n" if $?; # Encode system("$MP3ENC $enc_opts $TMPFILE \Q$mp3\E"); print STDERR "[$PROGNAME] Errors from:\n $MP3ENC $TMPFILE \Q$mp3\E\n $!\n" if $?; unlink $TMPFILE; my $info = ogginfo($ogg); set_mp3info($opt,$mp3,$info); } sub main { my ($opt,@oggs) = parse_args(); map(ogg2mp3($opt,$_), @oggs); } main();