File Coverage

blib/lib/MP3/Merge.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             #=Copyright Infomation
2             #==========================================================
3             #Module Name : MP3::Merge
4             #Program Author : Dr. Ahmed Amin Elsheshtawy, Ph.D. Physics, E.E.
5             #Home Page : http://www.mewsoft.com
6             #Contact Email : support@mewsoft.com
7             #Copyrights (c) 2013 Mewsoft. All rights reserved.
8             #==========================================================
9             package MP3::Merge;
10              
11 1     1   22103 use Carp;
  1         3  
  1         86  
12 1     1   5 use strict;
  1         2  
  1         29  
13 1     1   5 use warnings;
  1         5  
  1         24  
14 1     1   4 use File::Basename;
  1         1  
  1         239  
15 1     1   445 use MPEG::Audio::Frame;
  0            
  0            
16             use Archive::Zip qw(:ERROR_CODES :CONSTANTS);
17              
18             our $VERSION = '1.01';
19             #==========================================================
20             sub new {
21             my ($class) = @_;
22             my $self = bless {}, $class;
23             $self->clear();
24             return $self;
25             }
26             #==========================================================
27             sub clear {
28             my ($self) = @_;
29             $self->{frames} = 0;
30             $self->{length} = 0;
31             $self->{size} = 0;
32             $self->{files} = undef;
33             $self->{counter} = 0;
34             return $self;
35             }
36             #==========================================================
37             sub add {
38             my ($self, @files) = @_;
39             push @{$self->{files}}, @files;
40             return $self;
41             }
42             #==========================================================
43             sub files {
44             my ($self) = @_;
45             return @{$self->{files}};
46             }
47             #==========================================================
48             sub length {
49             my ($self) = @_;
50             return $self->{length};
51             }
52             #==========================================================
53             sub size {
54             my ($self) = @_;
55             return $self->{size};
56             }
57             #==========================================================
58             sub frames {
59             my ($self) = @_;
60             return $self->{frames};
61             }
62             #==========================================================
63             sub stream {
64             my ($self, $outfh) = @_;
65             my ($file, $frame, $fh);
66            
67             $self->{frames} = 0;
68             $self->{length} = 0;
69             $self->{size} = 0;
70              
71             foreach $file (@{$self->{files}}) {
72             open ($fh, $file) || croak("Error reading file $file: $!.");
73             binmode ($fh);
74             while ($frame = MPEG::Audio::Frame->read($fh)) {
75             $self->{length} += $frame->seconds;
76             $self->{size} += $frame->length;
77             $self->{frames}++;
78             print $outfh $frame->asbin();
79             $frame = undef;
80             }
81             close ($fh);
82             }
83              
84             return $self;
85             }
86             #==========================================================
87             sub save {
88             my ($self, $out) = @_;
89             my ($fh);
90             open ($fh, ">$out") || croak("Error wrtiting file $out: $!.");
91             binmode ($fh);
92             $self->stream($fh);
93             close ($fh);
94             return $self;
95             }
96             #==========================================================
97             sub echo {
98             my ($self, $filename) = @_;
99              
100             $filename ||= @{$self->{files}}[0];
101             print "Content-Disposition: attachment; filename=$filename\n";
102             print "Content-type: audio/mp3\n\n";
103             binmode STDOUT;
104             binmode STDERR;
105             $self->stream(\*STDOUT);
106             return $self;
107             }
108             #==========================================================
109             sub echo_zip {
110             my ($self, $filename) = @_;
111             my ($zip, $file, $name, $dir, $ext, $member);
112              
113             $filename ||= @{$self->{files}}[0];
114              
115             $zip = Archive::Zip->new();
116              
117             foreach $file (@{$self->{files}}) {
118             ($name, $dir, $ext) = fileparse($file, qr/\.[^.]*/);
119             $member = $zip->addFile($file, "$name.$ext");
120             $member->desiredCompressionMethod(COMPRESSION_STORED);
121             }
122            
123             print "Content-Disposition: attachment; filename=$filename\n";
124             print "Content-type: application/x-zip-compressed\n\n";
125             binmode STDOUT;
126             binmode STDERR;
127             $zip->writeToFileHandle(\*STDOUT, 0);
128             return $self;
129             }
130             #==========================================================
131              
132             1;
133              
134             =encoding utf-8
135              
136             =head1 NAME
137              
138             MP3::Merge - MP3 files merger and streamer to web browser
139              
140             =head1 SYNOPSIS
141              
142             use MP3::Merge;
143              
144             #create new object
145             my $mp = MP3::Merge->new();
146            
147             # add mp3 files
148             $mp->add("file.mp3");
149             $mp->add("file1.mp3", "file2.mp3", "file3.mp3");
150             $mp->add(@mp3files);
151            
152             # save to file
153             $mp->save("merged.mp3");
154            
155             # or stream merged files to the browser as a single mp3 file
156             # correct headers will be automatically sent first to the browser
157             $mp->echo("output.mp3");
158            
159             # or stream all files as single zipped file uncompressed to the browser
160             # correct headers will be automatically sent first to the browser
161             $mp->echo_zip("audio.zip");
162            
163             # merged file information after save or echo calls
164             #print "Total seconds: ", $mp->length(), ", Total frames: ", $mp->frames(), ", Total size:", $mp->size(), "\n";
165              
166             =head1 DESCRIPTION
167              
168             This module merges MP3 files into a single MP3 file and also can stream directly the merged files to the web browser.
169              
170             It can also stream the merged MP3 files as a single zipped file with no compression to the web browser.
171              
172             =head1 PREREQUESTS
173              
174             L
175              
176             =head1 AUTHOR
177              
178             Ahmed Amin Elsheshtawy,
179             Website: L
180              
181             =head1 COPYRIGHT AND LICENSE
182              
183             Copyright (C) 2013 by Dr. Ahmed Amin Elsheshtawy د أحمد أمين الششتاوى جودة , Ph.D. EE support[ at ]mewsoft.com
184             L
185              
186             This library is free software; you can redistribute it and/or modify
187             it under the same terms as Perl itself.
188              
189             =cut
190