Skip to content

Instantly share code, notes, and snippets.

@jberger
Last active August 29, 2015 14:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jberger/5224c5c09ee56eeaa99e to your computer and use it in GitHub Desktop.
Save jberger/5224c5c09ee56eeaa99e to your computer and use it in GitHub Desktop.
First cut at a streaming audio player using Mojolicious
#!/usr/bin/env perl
use Mojolicious::Lite;
use experimental qw'signatures postderef';
use Cwd;
app->attr( 'music_root' => sub { return $ENV{MUSIC_ROOT} || Cwd::cwd() } );
push app->static->paths->@*, app->music_root;
sub as_music {
my $x = $a->[2];
my $y = $b->[2];
$x->artist cmp $y->artist ||
$x->album cmp $y->album ||
$x->track <=> $y->track
}
helper 'all_audio' => sub ($c) {
my $root = $c->app->music_root;
require AudioFile::Find;
my $find = AudioFile::Find->new($root);
my %found = $find->search;
my @files;
for my $full (keys %found) {
my $obj = $found{$full};
my (undef, undef, $file) = File::Spec->splitpath($full);
my $rel = File::Spec->abs2rel($full, $root);
push @files, [$file, $rel, $obj];
}
return [ sort as_music @files ];
};
any '/' => 'music';
app->start;
__DATA__
@@ music.html.ep
<!DOCTYPE html>
% use experimental 'postderef';
% my $files = all_audio;
<html>
<head>
%= stylesheet '//cdnjs.cloudflare.com/ajax/libs/semantic-ui/0.16.1/css/semantic.min.css'
</head>
<body>
<audio id="player" style="width:100%;" controls></audio>
<table class="ui table segment">
<thead>
<tr>
<th>Artist</th><th>Title</th><th>Album</th><th>Track</th>
</tr>
</thead>
<tbody id="song_list">
% foreach my $file ($files->@*) {
% my $obj = $file->[2];
<tr onclick="playFile(this, '<%= $file->[1] %>')">
%= t td => $obj->artist
%= t td => $obj->title
%= t td => $obj->album
%= t td => $obj->track
</tr>
% }
</tbody>
</table>
%= javascript '//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js'
%= javascript '//cdnjs.cloudflare.com/ajax/libs/semantic-ui/0.16.1/javascript/semantic.min.js'
%= javascript begin
function playFile(row, path) {
var player = $('#player')[0];
player.pause();
player.src=path;
$('#song_list tr').removeClass('active');
$(row).addClass('active');
player.play();
}
% end
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment