Subject: | Cannot read title tag in Sony PSP MP4 files |
As you may know your MP4::Info doesn't support Sony PSP MP4 files.
Movie files for the PSP don't use the NAM tag for storing the movie
title. In those file the title is stored in custom uuid called USMT
that holds a MTDT block with several subblocks in it, and one of them
is the title subblock. So I modified a little bit your MP4::Info perl
module to map the $tag->{NAM} to the sony psp movie title when
present. (I also added sony psp TIMESTAMP).
I'm sending you the patch to the Info.pm file, in case you want to add
the patch to your module. I encorage you to do so because otherwise if
very difficult to extract the movie title from a Sony mp4 file as
those files never have a meaningful filename (the filename
convention is MAQ12345.MP4) so the only way to get the title is use a
library like your MP4::Info to read it. I didn't find any other
library/utility supporting psp usmt->mtdt custom uuid, only windows
encoders like PSP video 9 can read and manipulate this tag to my
knowledge.
If you wan to know more about psp USMT->MTDT read my blog post at
http://rubenlaguna.com/wp/2007/02/25/how-to-read-title-in-sony-psp-mp4-files/
Subject: | diff.txt |
*** original
--- psp-aware
***************
*** 27,33 ****
all => [@EXPORT, @EXPORT_OK]
);
! $VERSION = '1.11';
my $debug = 0;
--- 27,33 ----
all => [@EXPORT, @EXPORT_OK]
);
! $VERSION = '1.12';
my $debug = 0;
***************
*** 87,93 ****
VERSION => 1, LAYER => 1,
BITRATE => 1, FREQUENCY => 1, SIZE => 1,
SECS => 1, MM => 1, SS => 1, MS => 1, TIME => 1,
! COPYRIGHT => 1, ENCODING => 1, ENCRYPTED => 1,
);
my $tags = get_mp4tag ($file) or return undef;
--- 87,93 ----
VERSION => 1, LAYER => 1,
BITRATE => 1, FREQUENCY => 1, SIZE => 1,
SECS => 1, MM => 1, SS => 1, MS => 1, TIME => 1,
! COPYRIGHT => 1, ENCODING => 1, ENCRYPTED => 1, TIMESTAMP => 1,
);
my $tags = get_mp4tag ($file) or return undef;
***************
*** 277,282 ****
--- 277,283 ----
MEAN => 1,
NAME => 1,
DATA => 1,
+ UUID => 1,
);
# More interesting atoms, but with non-standard data layouts
***************
*** 520,526 ****
return parse_container ($fh, $level, $size, $tags);
}
! # Unkown atom - skip past it
seek $fh, $size, 1;
return 0;
}
--- 521,528 ----
return parse_container ($fh, $level, $size, $tags);
}
! # Unknown atom - skip past it
! # printf "unknown atom: %s\n", $id if $debug;
seek $fh, $size, 1;
return 0;
}
***************
*** 664,671 ****
--- 666,712 ----
if (read ($fh, $data, $size) != $size)
{
$@ = 'Premature eof';
+ printf "premature eof\n" if $debug;
return -1;
}
+ if ($id eq 'UUID') {
+ my $uuid=unpack 'a4',$data;
+ if ($uuid eq 'USMT') {
+ #skip to MTDT
+ $data = substr ($data, 20);
+ my $inner = unpack 'a4', $data;
+ printf "USMT->%s\n", unpack 'a4', $data if $debug;
+ if ($inner eq 'MTDT') {
+ $data = substr($data,4);
+ my $nblocks = unpack 'n', $data;
+ $data = substr($data,2);
+ printf "MTDT %d blocks\n",$nblocks if $debug;
+
+ for (my $count=0; $count<$nblocks; $count++)
+ {
+ print "start block\n" if $debug;
+
+ my ($bsize, $btype, $flags, $ptype) = unpack 'nNnn',$data;
+ $data = substr($data, 10);
+ printf "block size: %d, block type: %d, flags: %d, payload type: %d\n", $bsize, $btype, $flags, $ptype if $debug;
+ if ($btype eq '1') {
+ my $title = decode("UTF-16BE", substr($data, 0, $bsize-10));
+ printf "title: %s\n", $title if $debug;
+ return 0 if defined ($tags->{NAM});
+ $tags->{NAM} = $title;
+ }
+ if ($btype eq '3') {
+ my $timestamp = decode("UTF-16BE", substr($data, 0, $bsize-10));
+ return 0 if defined ($tags->{TIMESTAMP});
+ $tags->{TIMESTAMP} = $timestamp;
+ }
+ $data = substr($data, $bsize-10);
+ }
+
+
+ }
+ }
+ }
# 3GPP - different format when child of 'udta'
if (($id eq 'TITL') ||