You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
3.0 KiB

9 years ago
package Text::Playlist::M3U;
10 years ago
use strict;
use warnings;
9 years ago
use base 'Text::Playlist';
our $VERSION = '0.02';
10 years ago
sub new {
my ($class) = @_;
return bless({ attrs => {}, }, $class);
10 years ago
}
9 years ago
sub parse {
my ($self, $text) = @_;
10 years ago
9 years ago
my @lines = split /\r?\n/, $text;
my @items = ();
10 years ago
# safeguard
return "Not looks like playlist"
unless grep { $_ =~ m/^#EXTM3U/o } @lines;
my $item = undef;
foreach my $line (@lines) {
# header
if ($line =~ m/#EXTM3U(\s+\S+?=\S+)*/oi) {
return "Multiple EXTM3U lines found"
if (scalar keys($self->{attrs}));
$self->{attrs} = $self->_parse_attrs($1);
}
# standart tags
if ($line =~ m/^\s*#EXTINF:(-?\d+(?:\.\d+)?)(\s+\S+?=\S+)*,\s*(.*)/oi) {
10 years ago
$item //= {
duration => $1,
attrs => $self->_parse_attrs($2),
title => $3,
};
}
# extended tags
if ($line =~ m/^\s*#EXT-X-\S+?:(\s*\S+?=\S+)/oi) {
# ignore
}
# comments
if ($line =~ m/^\s*#/) {
next;
}
# path / url
if ($line) {
$item->{file} = $line;
push @items, $item;
10 years ago
undef $item;
}
}
return wantarray ? @items : [ @items ];
10 years ago
}
sub _parse_attrs {
my ($self, $str) = @_;
return {} unless $str;
my %attrs = ();
$str =~ s/(^\s+|\s+$)//oi;
foreach my $token (split /\s+/, $str) {
my ($key, $value) = split("=", $token, 2);
$attrs{$key} = $value;
}
return \%attrs;
}
sub _dump_attrs {
my ($self, $attrs) = @_;
my @parts = ('');
while (my ($key, $value) = each %{$attrs}) {
push @parts, sprintf("%s=%s", $key, $value);
}
return @parts ? join(" ", @parts) : "";
}
sub dump {
my ($self, @items) = @_;
my @lines = ();
push @lines, sprintf('#EXTM3U%s', $self->_dump_attrs($self->{attrs}));
foreach my $item (@items) {
push @lines, sprintf("#EXTINF:%s%s,%s", $item->{duration},
$self->_dump_attrs($item->{attrs}), $item->{title});
push @lines, $item->{file};
}
push @lines, '';
return join("\n", @lines);
}
10 years ago
1;
9 years ago
__END__
=pod
=head1 NAME
Text::Playlist::M3U - parser for 'm3u' format
=head1 SYNOPSIS
my $m3u = Text::Playlist::M3U->new;
my @items = $m3u->load('/path/to/playlist.m3u');
foreach my $item (@items) {
# <work with playlist items>
}
$m3u->save('/path/to/new-playlist.m3u', @items);
9 years ago
=head1 DESCRIPTION
Lightweight parser and generator for m3u playlists.
Will be usefull if you're just want to read playlist, or convert playlist
to another format, or change playlist items by some way.
9 years ago
=head1 Methods
9 years ago
=head2 C<load>
9 years ago
9 years ago
=head2 C<parse>
9 years ago
9 years ago
=head2 C<save>
9 years ago
9 years ago
=head2 C<dump>
For description of these methods see description in base class L<Text::Playlist>
=head1 Item format
Each parsed item has the following keys in hashref:
9 years ago
* file -- path or url, required
* title -- title for given item, required
* duration -- item duration in seconds, or -1 if not unknown
* attrs -- hashref with attributes for given item, optional
9 years ago
=head1 SEE ALSO
9 years ago
L<MP3::M3U::Parser> -- full-featured parser
9 years ago
=head1 AUTHORS
9 years ago
* Alex 'AdUser' Z <aduser@cpan.org>
9 years ago
=cut