1#!/usr/bin/env perl 2 3# Hacked by Thomas Orgis, use at your leisure. 4 5use strict; 6use locale; 7 8use File::Basename qw(basename dirname); 9 10my @mpg123_command = qw(mpg123 --continue -Cv --rva-album); 11my $listfile = "conplay.m3u"; 12my $glob = '*.mp[123]'; 13 14my $dir = shift; 15 16unless(defined $dir) 17{ 18 print STDERR "\nThis little wrapper runs $mpg123_command[0] on a given directory (hand in '.' for the current one), playing all $glob files therein in terminal control mode. The extra trick is that a playlist file ($listfile by default) is read and updated (created) with the position you left playback at (via 'q' key), to return on next invokation.\n"; 19 print STDERR "\nIf you give an existing file instead of a directory, or some non-existing path, as first and only paramter, it is used as playlist name and the directory part is used as the base directory for playback.\n"; 20 print STDERR "\nThe name stands for CONtinued PLAYback. What did you think?;-)\n\n"; 21 exit; 22} 23 24if(-f $dir or (not -e $dir)) 25{ 26 $listfile = basename($dir); 27 $dir = dirname($dir); 28} 29 30 31chdir($dir) or die "Cannot enter $dir ($!)!\n"; 32 33print STDERR "Playing things in: $dir\n"; 34 35my @files; 36my $entry = 1; 37my $frame = 0; 38 39if(-e $listfile) 40{ 41 open(LIST, '<', $listfile) or die "Cannot read playlist ($!)!\n"; 42 while(<LIST>) 43 { 44 chomp; 45 unless(/^#/) 46 { 47 push(@files, $_); 48 } 49 elsif(/^#\s*current entry:\s*(\d+)$/) 50 { 51 $entry = $1; 52 } 53 elsif(/^#\s*current frame:\s*(\d+)$/) 54 { 55 $frame = $1; 56 } 57 } 58 close(LIST); 59} 60else 61{ 62 @files = get_files($glob); 63 write_list(); 64} 65 66unless(@files) 67{ 68 print STDERR "There are no files to play.\n"; 69 exit; 70} 71 72if($entry < 0 or $entry > @files or $frame < 0) 73{ 74 die "You got bad data in your playlist file (mismatch between current entry and total count, bad frame index). Clean that up.\n"; 75} 76 77push(@mpg123_command, '-k', $frame, '--listentry', $entry, '-@', $listfile); 78print STDERR "running player:\n\t@mpg123_command\n\n"; 79 80open(MPG123, '-|', @mpg123_command) or die "Cannot run mpg123!"; 81while(<MPG123>) 82{ 83 print STDOUT $_; 84 if(/^\[CONTINUE\]\s+track\s+(\d+)\s+frame\s+(\d+)/) 85 { 86 $entry = $1; 87 $frame = $2; 88 } 89 if(/^\[BOOKMARK\]\s+track\s+(\d+)\s+frame\s+(\d+)/) 90 { 91 print STDERR "\nGot bookmark at track $1, frame $2; not yet doing anything with that, besides storing.\n"; 92 $entry = $1; 93 $frame = $2; 94 } 95} 96close(MPG123); 97 98if($entry > @files) 99{ 100 $entry = 0; 101 $frame = 0; 102} 103print STDERR "Continue point is in track $entry, frame $frame.\n"; 104write_list(); 105 106sub write_list 107{ 108 unless(@files) 109 { 110 print STDERR "Refusing to write empty playlist.\n"; 111 return; 112 } 113 open(LIST, '>', $listfile) or die "Cannot write Playlist"; 114 print LIST "#M3U\n"; 115 print LIST "#current entry: $entry\n"; 116 print LIST "#current frame: $frame\n"; 117 for my $f (@files) 118 { 119 print LIST "$f\n"; 120 } 121 close(LIST); 122} 123 124sub get_files 125{ 126 my $glob = shift; 127 my @files; 128 open(FIND, '-|', 'find', '.', '-type', 'f', '-name', $glob) or die "Cannot exec find to find files: ($!)\n"; 129 @files = <FIND>; 130 close(FIND); 131 chomp(@files); 132 return sort @files; 133} 134