summaryrefslogtreecommitdiff
path: root/mpskip
blob: 5caa8d811f9e3eee98d354c45b4042f839296688 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/usr/bin/perl
use strict;
use warnings;
use Audio::MPD q{0.19.0};
use Time::HiRes qw(usleep);

=head1 NAME

mpskip - emulate a skipping record

=head1 SYNOPSIS

mpskip [num_skips] [duration] [skippos] [host]

=head1 DESCRIPTION

B<mpskip> makes mpd emulate a skipping record.

If B<num_skips> is not specified (or is 0), it will skip forever (or until
someone manually seeks past the "bad" part of the song, or changes songs).

The B<duration> is how long the skip should be, in seconds. Floating point
values can be used.

The B<skippos> is the number of seconds into the song to place the skip point.
Default is the current play position.

If the hostname is omitted, the MPD_HOST environment variable will be used.

=head1 LIMITATIONS

Doesn't insert the pop you hear on a real record player when the needle
skips.

If run against a remote host, it may not skip at exactly the same place
each time due to network issues.

=head1 AUTHOR

Copyright 2007 Joey Hess <joey@kitenet.net>

Licensed under the GNU GPL version 2 or higher.

http://kitenet.net/~joey/code/mpdtoys

=cut

my $num_skips=0;
if (@ARGV && $ARGV[0] =~ /^[0-9]+$/) {
	$num_skips=shift;
}

my $duration=1;
if (@ARGV && $ARGV[0] =~ /^[0-9.]+$/) {
	$duration=shift;
}

my $skippos;
if (@ARGV && $ARGV[0] =~ /^[0-9]+$/) {
	$skippos=shift;
}

if (@ARGV) {
	$ENV{MPD_HOST}=shift;
}

my $mpd=Audio::MPD->new(conntype => "reuse");
if ($mpd->status->state ne 'play') {
	die "error: mpd has to be playing first\n";
}

my $songid=$mpd->current->id;
$skippos=$mpd->status->time->seconds_sofar unless defined $skippos;

print "skipping".($num_skips ? " $num_skips times" : "").
	" at position $skippos for $duration seconds\n";

while (usleep $duration * 1000000 / 2 ) {
	my $status=$mpd->status;
	my $pos=$status->time->seconds_sofar;
	exit if $status->state ne 'play';
	exit if $mpd->current->id ne $songid;
	exit if $pos > $skippos + $duration + 1;
	next if $pos <= $skippos;
	$mpd->seek($skippos);
	if ($num_skips) {
		$num_skips--;
		exit unless $num_skips;
	}
}