Perl 小品集 ─ mplay2
#!/usr/bin/perl
# multi-media player
# needs mpg123, timidity, mtvp
# global value @list, $sum, $root, $pages
# 現在のディレクトリとそのファイル情報を得る
($root) = `pwd`;
chomp $root;
&get_list;
# ディレクトリとファイルを表示し、選択を待つ
$page = 1;
&select_media ($page);
exit 0;
# 指定したディレクトリのファイル情報を得る
sub get_list {
local (@p_list, @file_list, $entry);
@file_list = glob "$root/*";
@p_list [0] = "..";
$sum = 1;
# ディレクトリの場合
foreach $entry (@file_list) {
if (-d $entry) {
$entry =~ /([^\/]+)$/;
@p_list [$sum] = &check_name ($1);
$sum++;
}
}
# 音楽ファイルの場合
foreach $entry (@file_list) {
if (($entry =~ /\.mid/i) or ($entry =~ /\.rmi/i) or ($entry =~ /\.mp3/i)) {
$entry =~ /([^\/]+)$/;
@p_list [$sum] = &check_name ($1);
$sum++;
}
}
# 動画ファイルの場合
foreach $entry (@file_list) {
if (($entry =~ /\.mpeg/i) or ($entry =~ /\.mpg/i)) {
$entry =~ /([^\/]+)$/;
@p_list [$sum] = &check_name ($1);
$sum++;
}
}
# ファイルのリストが多い場合、複数ページにわける
if ($sum > 40){
$pages = int ($sum / 40);
if ($sum % 40 > 0) {
$pages = $pages + 1;
}
}
else {
$pages = 1;
}
# リストの初期化
@list = @p_list;
}
# ファイル名に空白があるかどうかチェックする
sub check_name {
local $temp;
local ($name) = @_;
# ファイル名に空白があるばあいアンダースコアで置き換える
if ($name =~ / /) {
$temp = $name;
$name =~ tr/ /_/;
# ファイル名の変更をこころみ、失敗した場合もとにもどす
if ((system "mv '$root/$temp' '$root/$name'") != 0) {
$name = $temp;
}
}
return $name;
}
# ディレクトリの移動、ファイルの再生などを選択する
sub select_media {
local ($input, $file, @selected, @randfiles, @entries, $entry, $i, $number, $number_2, $start, $end);
local ($page) = @_;
&show_list ($page);
print "Input (#,a,r,n,p,q) => ";
$input = <STDIN>;
chomp $input;
# 終了
if ($input eq "q") {
exit 0;
}
# 次のページ
elsif ($input eq "n") {
$page = $page + ($page < $pages);
}
# 前のページ
elsif ($input eq "p") {
$page = $page - ($page > 1);
}
# すべてのファイルの再生
elsif ($input eq "a") {
foreach $file (@list) {
if ($file ne "..") {
&play_media ("$file");
}
}
}
# すべてのファイルのランダム再生
elsif ($input eq "r") {
$i = 0;
while ($i < $sum) {
$randfiles [$i] = " ";
$i++;
}
# ランダムデータの作成
foreach $file (@list) {
while(1){
# 乱数発生 0<=$number<$sum
$number = int (rand $sum);
if($randfiles [$number] eq " "){
$randfiles [$number] = $file;
last;
}
}
}
# ランダムデータの再生
foreach $file (@randfiles) {
if ($file ne "..") {
&play_media ("$file");
}
$i++;
}
}
# 上位ディレクトリへの移動
elsif ($input eq ".." or $input eq "0" or $input eq "") {
@entries = split /\//, $root;
$max = scalar (@entries) -1;
$i = 0;
foreach $entry (@entries) {
if ($i == $max) {
last;
}
elsif ($i == 0) {
$root = $entry;
}
else {
$root = "$root/$entry";
}
$i++;
}
&get_list;
$page = 1;
}
# 下位ディレクトリへの移動
elsif (-d "$root/$input") {
$root = "$root/$input";
&get_list;
$page = 1;
}
# 複数ファイルの再生
elsif ($input =~ /,/){
@selected = split /,/, $input;
foreach $number (@selected) {
# 複数ファイルの中の連続ファイルの再生
if ($number =~ /-/) {
($start, $end) = split /-/, $number;
if ($end eq "") {
$end = $sum;
}
$number_2 = $start;
while ($number_2 <= $end) {
$file = @list [$number_2];
&play_media ("$file");
$number_2++;
}
}
else {
$file = @list [$number];
&play_media ("$file");
}
}
}
# 連続ファイルの再生
elsif ($input =~ /-/) {
($start, $end) = split /-/, $input;
if ($end eq "") {
$end = $sum;
}
$number_2 = $start;
while ($number_2 <= $end) {
$file = @list [$number_2];
&play_media ("$file");
$number_2++;
}
}
# 単一ファイル、またはディレクトリの再生
else {
$file = @list [$input];
if ($file ne "..") {
&play_media ("$file");
}
}
# 選択メニューにもどる
&select_media ($page);
}
# ディレクトリ、ファイルのページごとのリスト
sub show_list {
local ($line, $i, $row, $col, $number, $p_sum, $p_root, $title_name, $name, $last);
local ($page) = @_;
# 二列に表示するため、最初の列の長さを計算
if ($page < $pages) {
$p_sum = 40 * $page;
$last = $p_sum - 20;
}
else {
$p_sum = $sum;
if ($p_sum % 2 == 0) {
$last = 40 * ($page -1) + int (($p_sum - 40 * ($page -1)) / 2);
}
else {
$last = 40 * ($page -1) + int (($p_sum - 40 * ($page -1)) / 2) + 1;
}
}
# スクリーンの初期化とタイトルの表示
if ($root eq "") {
$p_root = "/";
}
else {
$p_root = $root;
}
if ($pages > 1) {
$title_name = " MutiMedia Player ($p_root) $page/$pages ";
}
else {
$title_name = " MutiMedia Player ($p_root) ";
}
print "\033[2J\033[1;0H";
$line = int((80 - length ($title_name)) / 2);
$i = 0;
while ($i < $line){
print '=';
$i++;
}
print $title_name;
$i = $i + length ($title_name);
while ($i < 80){
print '=';
$i++;
}
# 左のリストの表示
$i = 40 * ($page -1);
$row = 2;
$col = 0;
while ($i < $last){
if($i < 10){
$number = " [0$i] ";}else{
$number = " [$i] ";
}
($name) = &print_name (@list [$i]);
print "\033[$row;$col\H$number$name";
$row++;
$i++;
}
# 右リストの表示
$row = 2;
$col = 40;
while ($i < $p_sum){
if($i < 10){
$number = " [0$i] ";}else{
$number = " [$i] ";
}
$name = &print_name (@list [$i]);
print "\033[$row;$col\H$number$name";
$row++;
$i++;
}
if($p_sum % 2 == 0){
print "\n";}else{
print "\n\n";
}
}
# 表示名の調整
sub print_name {
local (@letters, $i, $p_name);
local ($name) = @_;
# ファイル名が長い場合、それを短くして表示する
if ((length ($name)) > 30) {
@letters = split //, $name;
$p_name = "";
$i = 0;
while ($i < 30){
$p_name = "$p_name$letters[$i++]";
}
$p_name = "$p_name...";
}
else {
$p_name = $name;
}
# ターゲットファイルのカラー表示
if (($name =~ /\.mid/i) or ($name =~ /\.rmi/i) or ($name =~ /\.mp3/i)) {
$p_name = "\033[34m$p_name\033[0m";
}
elsif (($name =~ /\.mpeg/i) or ($name =~ /\.mpg/i)) {
$p_name = "\033[32m$p_name\033[0m";
}
return $p_name;
}
# ファイルまたはディレクトリの再生
sub play_media {
local @entries;
local ($file) = @_;
# ディレクトリーを指定した場合、そのファイルをすべて再生
if (-d "$root/$file") {
@entries = glob "$root/$file/*";
foreach $file (@entries) {
&play_one ("$file");
}
}
else {
&play_one ("$root/$file");
}
}
# 再生プログラムの選択
sub play_one {
local ($file) = @_;
if (($file =~ /\.mpg/i) or ($file =~ /\.mpeg/i)) {
system "mtvp '$file'";
}
elsif ($file =~ /\.mp3/i){
system "mpg123 '$file'";
}
elsif (($file =~ /\.mid/i) or ($file =~ /\.rmi/i)) {
system "timidity '$file'";
}
}