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