Audio-M4P
view release on metacpan or search on metacpan
lib/Audio/M4P/Decrypt.pm view on Meta::CPAN
sub DeDRMS {
my ( $self, $infile, $outfile ) = @_;
$self->{QTStream}->ReadFile($infile);
$self->{QTStream}->ParseBuffer();
my $sampleTable = $self->{QTStream}->GetSampleTable();
my $userKey = $self->GetUserKey( $self->{QTStream}->{userID},
$self->{QTStream}->{keyID} )
|| $self->GetSCInfoUserKey();
if ( !$userKey ) {
carp "Cannot find user key for $infile";
return;
}
else {
print "User key is $userKey\n" if $self->{DEBUG};
}
my $md5 = new Digest::MD5;
$md5->add( $self->{QTStream}->{name}, $self->{QTStream}->{iviv} );
my $alg = new Crypt::Rijndael( $userKey, Crypt::Rijndael::MODE_CBC );
$alg->set_iv( $md5->digest );
$self->Decrypt(
\$self->{QTStream}->{priv}, 0,
length( $self->{QTStream}->{priv} ), $alg
);
if ( $self->{QTStream}->{priv} !~ /^itun/ ) {
carp "Priv decryption if $infile failed.";
return;
}
my $key = substr( $self->{QTStream}->{priv}, 24, 16 );
$alg = new Crypt::Rijndael( $key, Crypt::Rijndael::MODE_CBC );
$alg->set_iv( substr( $self->{QTStream}->{priv}, 48, 16 ) );
my $mdata = $self->{QTStream}->FindAtom('mdat');
my $posit = $mdata->start + 8;
foreach my $samplesize ( @{$sampleTable} ) {
$self->Decrypt( $mdata->rbuf, $posit, $samplesize, $alg );
$posit += $samplesize;
}
$self->{QTStream}->ConvertDrmsToMp4a();
if ( $self->{forceclean} ) {
$self->{QTStream}
->CleanAppleM4aPersonalData( force => 1, zero_free_atoms => 1 );
}
$self->{QTStream}->WriteFile($outfile);
}
# DeDRMS is aliased to DecryptFile
sub DecryptFile { DeDRMS(@_) }
=head1 NAME
Audio::M4P::Decrypt -- DRMS decryption of Apple iTunes style MP4 player files
=head1 DESCRIPTION
Originally derived from the DeDRMS.cs program by Jon Lech Johansen
=head1 SYNOPSIS
use Audio::M4P::Decrypt;
my $outfile = 'mydecodedfile';
my $deDRMS = new Audio::M4P::Decrypt;
$deDRMS->DeDRMS($mp4file, $outfile);
=head1 METHODS
=over 4
=item B<new>
my $cs = new Audio::M4P::Decrypt;
my $cs_conparam = Audio::M4P::Decrypt->new(
strHome => '~', sPfix => '.', dirSep => '/' );
Optional arguments: strHome is the directory containing the keyfile directory.
After running VLC on a .m4p file under Windows, MacOS X, and Linux, this should
be found by the module automatically (APPDATA dir under Win32, ~/ under OS X and
Linux). sPfix is '.' for MacOS/*nix, nil with Windows. dirSep is the char that
separates directories, often /.
For debugging purposes, use eg:
my $cs_conparam = Audio::M4P::Decrypt->new(
DEBUG => 1, DEBUGDUMPFILE => 'm4ptree.html'
);
DEBUG turns on debugging output. DEBUGDUMPFILE is an output file name to dump
an html picture of the m4p data structure.
=item B<DeDRMS>
my $cs = new Audio::M4P::Decrypt( forceclean => 1 );
$cs->DeDRMS('infilename', 'outfilename');
Decode infilename, write to outfilename. Reading slurps up an entire file,
so output can overwrite the same file without a problem, we hope. Backup first.
'forceclean => 1' will also attempt to remove residual personal data from the file.
=item B<DecryptFile>
$cs->DecryptFile('infilename', 'outfilename');
More descriptive alias for the B<DeDRMS> method.
=back
=head1 B<SEE ALSO>
=over 4
=item L<LWP::UserAgent::iTMS_Client>
=item L<iTunes::Sid>
=back
=head1 B<NOTES>
This software is designed to allow different but fair use of music by the
purchaser of the music. In no way is this software intended to facilitate
( run in 1.753 second using v1.01-cache-2.11-cpan-39bf76dae61 )