#!/usr/bin/perl use POSIX; use List::Util 'shuffle'; use strict; use constant USAGE => q{ Usage: sshcast.pl HOST PLAYLIST [-s] scp's files listed in PLAYLIST from HOST one at a time and plays them and deletes them after they've played. The next file is downloaded while the current one is playing to minimize pauses. If -s is supplied then the playlist is shuffled. Use the username@host format to specify a different user name and the computer this script is operating on must be in allowed_keys or you will have to enter your password for each file. Requirements: * Perl * mpg321 * ogg123 Known bugs: * Filenames with spaces or special characters (e.g. &, international characters, etc.) may break scp and/or the players. * At present there isn't really a clean way to exist this script. Pressing ^C twice is sure to end it but may leave up to two downloaded files on the system. * Pauses between songs -- This isn't so much a bug as a limitation of this *very simple* script. If the next file takes longer to download than the current one does to play you will get a pause. Author: Daniel Casner www.danielcasner.org }; my $host = $ARGV[0]; if((!defined $host) or ($host eq '-h') or ($host eq '--help')) { print USAGE; exit(2); } if($ARGV[1] !~ /\.pls$/) { print STDERR "You must specify a .pls file\n -h for help\n"; exit(2); } unless(open(PLS, $ARGV[1])) { print STDERR "Couldn't open playlist file\n"; exit(1); } my @playlist = ; close(PLS); @playlist = shuffle(@playlist) if $ARGV[2] eq '-s'; my $downloaded = undef; foreach (@playlist) { next if $_ !~ /^File\d+=(.*\.(mp3|ogg))$/; # Ignore lines that aren't files or types my $file = $1; my $pid = fork(); if(!defined $pid) { # Check that spawn was successful. print STDERR "Couldn't spawn dowload thread\n"; exit(1); } elsif($pid == 0) { # Child process, does download... my $scp_file = '"' . $file . '"'; #$scp_file =~ s/ /\\ /g; # Replace all spaces with escaped spaces exec('scp', "$host:$scp_file", './'); # If code exicution ever gets here the exec didn't work die "Couldn't exicute scp download command\n"; } else { # Parent process, plays music. if(defined $downloaded) { my $player = undef; $player = 'mpg321' if($downloaded =~ /\.mp3$/); $player = 'ogg123' if($downloaded =~ /\.ogg$/); if(system($player, $downloaded)) { print STDERR "Error playing file $downloaded\n"; } system('rm', $downloaded); } else { print "Please wait for the first file to download...\n"; } waitpid($pid,0); if($? != 0) { print STDERR "Error downloading next file skipping.\n"; $downloaded = undef; next; } else { my @file = split(/[\/\\]/, $file); # Split on a forward of backward slash $downloaded = pop(@file); } } }