インタネット上には色々な音声ファイルがころがっている。Linuxでも、Windowsでもデフォルト状態では再生できないものも多い。Linuxでの再生方法を少し整理してみたい。
拡張子 | コーデック | 素性 | コマンドライン | XMMS |
.wav | WAVE | PCM | play | default |
.mp3 | MPEG audio layer3 | MPEG2音声。広く使われている。 | mpg321 | xmms-mp3 |
.ogg | vorbis | フリーのmp3代替として作られた。 | ogg123 | xmms-vorbis |
.aac | AAC | MPEG4音声 | faad | xmms-aac |
.wma | WindowsMedia Audio | マイクロソフト製のプロプライエタリなコーデック。 | mplayer | xmms-wma |
.m4a | AAC | 大抵AACだが、中身は色々。 | faad | xmms-aac |
.m4a | Apple Lossless Codec | アップル社製プロプライエタリなロスレスコーデック | alac | NA |
.mp4 | AAC | 大抵AACだが、中身は色々。 | faad | libmp4 |
.flac | Free Lossless Codec | 一番広く使われているロスレスコーデック。 | flac | xmms-flac |
.ape | Monkey' Audio | flacより圧縮率が高いロスレスコーデックであるが、エンコードは勿論、デコードですら重い。 | mac | libxmms-mac |
.tta | The True Audio | フリーなロスレスコーデック。最近良く見る。 | ttaenc | libxmms-tta |
.wv | Wavpack | フリーなロスレスコーデック。最近登場。 | wvunpack | xmms-wavpack |
.mpc | Musepack | 一時期良く見たが、最近は見ない。ロッシー。 | mppdec | xmms-musepack |
.ra | Realplay | 今はもう見ない。realplay/helixplayで再生可。 | mplayer | NA |
.shn | Shorten | 今はもう見ない | ? | xmms-shn |
.mid | MIDI | 通常の意味で圧縮ではないが…。 | timidity | NA |
因みに、ffplayでは大抵再生できるようだ。
コマンドライン再生には、wav用の/usr/bin/playというのがあるが、それに習って、上記のフォーマットを再生できるようにしたplay.plを使っているので、お見せする。出力がoss決め打ちだったり、WAVを吐いたりするデコーダをラップしている。また、m4aフォーマットは、ファイルの頭(magic+α)を読んで判別しているが、仕様書は確認していない。
#!/usr/bin/perl
$Usage = "$0 [-h] [-o (oss|alsa|esd)] files_to_play_back\n";
$DefaultOutput="esd";
#--- interpret the command-line arguments
while (defined($ARGV[0])) {
if ($ARGV[0] =~ /^-o/) {
shift(@ARGV);
$soutput = $ARGV[0];
} elsif ($ARGV[0] =~ /^-D/) {
$Debug = 1;
} elsif ($ARGV[0] =~ /^-.*/) {
print STDERR "$Usage";
exit 0;
} else {
last;
}
shift(@ARGV);
}
#print "$#a : @a\n";
#--- DebugPrint function
#$Debug = 1;
sub Dprint { if ($Debug) { printf STDERR "ERR: @_"; } return 0; }
#--- checking to set the necessary variables.
if (! ($#ARGV >= 0)) {
print STDERR "$Usage";
exit 0;
}
if (!defined($soutput)) {
$soutput = $DefaultOutput;
}
#--- change file names.
foreach (@ARGV) {
m/\.([^.]*)/;
$tail = $1;
if (/^(.*)\[([0-9]*)-([0-9]*)\](.*)/) {
# Dprint "$_\n";
$head = $1;
$start = $2;
$end = $3;
$tail = $4;
$width = (length($start) > length($end)) ?
length($start) : length($end);
for ($n = $start; $n <= $end; $n++) {
$ns = sprintf(($width == 0) ? "%d" : "%0${width}d",
$n);
# Dprint "$width $ns $body $b\n";
$b = $head . $ns . $tail;
# Dprint "doplay $b\n";
doplay($b);
}
} else {
doplay($_);
}
}
exit 0;
sub doplay {
my $player, $play_command, $sout;
if ($soutput eq "esd") {
$sout = "esdcat";
} elsif ($soutput eq "alsa") {
$sout = "aplay -";
} else {
$sout = "sox -t wav - -t ossdsp /dev/dsp";
}
$args = "";
$sfile = "$[0]";
$[0] =~ m/\.([^.]*)$/;
$tl = $1;
# Dprint "doplay : $_[0]\n";
if ($tl =~ /mp3/i) {
if ($soutput eq "esd") {
$args = "-d esd";
}
$player = "mpg123 " . $args;
} elsif ($tl =~ /ogg/i) {
if ($soutput eq "esd") {
$args = "-d esd";
}
$player = "ogg123 " . $args;
} elsif ($tl =~ /mid/i) {
if ($soutput eq "esd") {
$player = "TIMIDITY_OUTPUT_ID=e timidity";
} else {
$player = "timidity";
}
} elsif ($tl =~ /mpc/i) {
$player = "mppdec";
} elsif ($tl =~ /ra|ram/) {
$player = "mplayer";
} elsif ($tl =~ /m4a/i) {
open(IN, "hexdump \"$sfile\" | head -1 |") ||
die("Can't open $sfile");
while (<IN>) {
@h = split();
}
close(IN);
Dprint "$h[1] $h[2] $h[3] $h[4] $h[5] $h[6]\n";
if ($h[1] eq "0000" && $h[2] eq "1800" &&
$h[3] == "7466" && $h[4] == "7079" &&
$h[5] == "706d" && $h[6] == "3234") {
$play_command = "faad -q -w \"$sfile\" | $sout";
} else {
$play_command = "alac \"$sfile\" | $sout";
}
} elsif ($tl =~ /wma|wmv|asf/i) {
$player = "mplayer";
} elsif ($tl =~ /ape/i) {
$play_command = "mac \"$sfile\" - -d | $sout";
} elsif ($tl =~ /flac/i) {
$play_command = "flac -d -c \"$sfile\" | $sout";
} elsif ($tl =~ /tta/i) {
$play_command = "ttaenc -d -o - \"$sfile\" | $sout";
} elsif ($tl =~ /mp4|aac/i) {
$play_command = "faad -o - \"$sfile\"
2>/dev/null | $sout";
} elsif ($tl =~ /wv/i) {
$play_command = "wvunpack -o - \"$sfile\"
2>/dev/null | $sout";
} else {
$player = "play";
}
# Dprint "$player : @a\n";
if (defined($play_command)) {
system("$play_command");
} else {
system("$player \"$sfile\"");
}
}