source: flacrip/trunk/flacplay @ 1

Last change on this file since 1 was 1, checked in by peter, 12 years ago

initial import of current flacrip files into the trunk

  • Property svn:executable set to *
File size: 3.7 KB
Line 
1#!/usr/bin/perl -w
2use strict;
3
4use IPC::Open2;
5use IO::Prompt;
6
7my $FLAC_FILE = shift;
8my $TRACK = shift || 1;
9
10
11# get the track start positions from the embedded cuesheet
12open my $CUESHEET, "metaflac --export-cuesheet-to - $FLAC_FILE |";
13
14my @position_for_track;
15my $i = 1;
16while (<$CUESHEET>) {
17    if (my ($m,$s,$f) = /INDEX 01 (\d\d):(\d\d):(\d\d)/) {
18        $position_for_track[$i] = ($m * 60) + $s + ($f / 75);
19        $i++;
20    }
21}
22
23close $CUESHEET;
24
25
26my $track_count = scalar @position_for_track - 1;
27print "$track_count tracks\n";
28
29die "There is no track $TRACK" if $TRACK < 1 or $TRACK > $track_count;
30
31   
32# launch the flac123 player as a daemon
33my $flac123_pid = open2(my $PLAYER_OUT, my $PLAYER_IN, qw{flac123 -R});
34
35print "flac123 PID = $flac123_pid\n";
36
37my $current_track = $TRACK;
38my $next_track_start = $position_for_track[$current_track + 1];
39
40print "Track $current_track\n";
41
42my %commands = (
43    z => sub {
44        return if $current_track <= 1;
45        $current_track--;
46        my $position = $position_for_track[$current_track];
47        print $PLAYER_IN "JUMP $position\n";
48        print "Track $current_track\n";
49    },
50    x => sub {},
51    c => sub {},
52    v => sub {},
53    b => sub {
54        return if $current_track >= $track_count;
55        # note, don't increment or print $current_track here,
56        # since it will be automatically detected by the other
57        # process watching the output of flac123
58        my $position = $position_for_track[$current_track + 1];
59        print $PLAYER_IN "JUMP $position\n";
60    },
61    q => sub {
62        print $PLAYER_IN "QUIT\n";
63        exit;
64    },
65);
66
67# track has advanced automatically
68$SIG{USR1} = sub {
69    # detect track change
70    my $time = read_time();
71    if (defined $next_track_start && $time >= $next_track_start) {
72        $current_track++;
73        $next_track_start = $position_for_track[$current_track + 1];
74        print "Track $current_track\n";
75    }
76};
77
78my $parent_pid = $$;
79my $pid = fork;
80
81
82if ($pid) {
83    # parent
84    while (my $cmd = prompt('', -one_char, -echo => '')) {
85        if (exists $commands{$cmd}) {
86            $commands{$cmd}->();
87        }
88    }
89       
90} elsif (defined $pid) {
91    # child
92
93    print $PLAYER_IN "LOAD $FLAC_FILE\n";
94    print $PLAYER_IN "JUMP $position_for_track[$TRACK]\n";
95
96    while (<$PLAYER_OUT>) {
97        if (/\@F (\d+) (\d+) (\d+\.\d\d) (\d+\.\d\d)/) {
98            my ($frame, $frames_left, $time, $time_left) = ($1, $2, $3, $4);
99            # note the current time and alert the parent
100            write_time($time);
101            kill 'USR1', $parent_pid;
102        }
103    }
104    waitpid $flac123_pid, 0;
105
106} else {
107    die "Unable to fork: $!";
108}
109
110sub write_time {
111    my ($time) = @_;
112    open my $TIME, '>', 'current_time';
113    print $TIME "$time\n";
114    close $TIME;
115}
116
117sub read_time {
118    open my $TIME, '<', 'current_time';
119    my $time = <$TIME>;
120    close $TIME;
121    chomp $time;
122    return $time;
123}
124
125=begin flac123 -R outputs
126
127@R FLAC123
128flac123 tagline. Output at startup.
129
130@I ID3:<a><b><c><d><e><f>
131Prints out the metadata information after loading the flac file.
132a = title (30 chars)
133b = artist (30 chars)
134c = album (30 chars)
135d = year (4 chars)
136e = comment (30 chars)
137f = genre (30 chars)
138
139@I filename
140Prints out the filename of the flac file, minus the extension. Happens after
141a flac file has been loaded and there is no metadata available.
142
143@F <current-frame> <frames-remaining> <current-time> <time-remaining>
144Frame decoding status updates (once per frame).
145Current-frame and frames-remaining are integers; current-time and
146time-remaining floating point numbers with two decimal places.
147
148@P {0, 1, 2}
149Stop/pause status.
1500 - playing has stopped. When 'STOP' is entered, or the flac file is finished.
1511 - Playing is paused. Enter 'PAUSE' or 'P' to continue.
1522 - Playing has begun again.
153
154=cut
Note: See TracBrowser for help on using the repository browser.