File: mp3extract.pl

package info (click to toggle)
magicrescue 1.1.9-4
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 812 kB
  • ctags: 530
  • sloc: ansic: 1,939; perl: 1,649; sh: 316; makefile: 65
file content (68 lines) | stat: -rwxr-xr-x 1,572 bytes parent folder | download
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
#!/usr/bin/env perl
use strict;

# This script tries to decode the first part of the mp3 with mpg123, and if
# that fails it will truncate the mp3 at that failure point.
# I could also use mp3_check, perhaps it is more correct. However, users are
# not likely to have it installed.

my $max_bytes     = 40*1024*1024;
my $min_bytes     = 1024;
my $min_pcm       = 11000;

my $ofile = $ARGV[0] or die;

if (-f "$ofile.pcm" and (-s _) < $min_pcm) {
    unlink $ofile;
    exit 1;
}

copy_out_file();
my $size = find_size();
if ($size) {
    eval { truncate($ofile, $size + 128) };
    if ($@) {
	print STDERR "\n\n\ntruncate() failed: $!\nKilling output\n\n\n\n";
	unlink($ofile);
    }
} else {
    print STDERR "Invalid mp3 file\n";
    unlink($ofile);
}

sub copy_out_file {
    my ($read_now, $read_total) = (0, 0);

    open my $fd, ">>", $ofile or die;
    while ($read_total < $max_bytes
	    and $read_now = read STDIN, my $buf, 10240) {
	$read_total += $read_now;
	print {$fd} $buf or die;
    }
    close $fd;
}

sub find_size {
    my $pid = open my $mpg123, "-|" or mpg123();

    while (<$mpg123>) {
	if (/at offset (0x[a-zA-Z0-9]+)\.$/) {
	    kill TERM => $pid; #TODO: mpg123 could already be dead
	    wait;
	    close $mpg123;

	    my $offset = oct $1;
	    return ($offset < $min_bytes or $offset > $max_bytes)
		?  0 : $offset;
	}
    }

    return (-s $ofile < $max_bytes ? (-s _) - 128 : 0);
}

sub mpg123 {
    open STDERR, ">&STDOUT" or die;
    open STDOUT, ">/dev/null" or die;
    exec qw(mpg123 -s -c), $ofile;
    die "Executing mpg123: $!\n";
}