I realized that the PSP refuses to play all my .MP4 files from the root VIDEO folder. If I move them to MP_ROOT/100ANV01 it will work but if I put them in the VIDEO folder PSP says that they are not compatible data. After investigating a little bit, it seems that it only refuses to play AVC encoded files all other are fine. Well, if fact only MPEG-4 320×240 files can be played from the video folder whereas AVC 480×272 is fine if I put them in MP_ROOT/100ANV01. Another interesting fact is that if I encode the files using Media Manager for PSP 2 instead of 3GP converter then I can play AVC files from the VIDEO folder.
I created this little perl program that creates an RSS feed from a set of video files (.mp4). This is useful to wirelessly transfer files to the PSP. The files will be saved in the VIDEO folder of the PSP.
You’ll need to install MP4::Info and HTTP::Daemon from CPAN first.
<span class='line'>#!/usr/bin/perl -w
</span><span class='line'>
</span><span class='line'># this small program starts a http daeomon listening on port 1111 and provides a RSS feed
</span><span class='line'># to all .mp4 files stored in the 'videos' folder.
</span><span class='line'># This program is intended to transfer movie files via wireless. Using the sony psp RSS feed utility
</span><span class='line'># 1. Start the server with ./rssstandaloneserver.pl
</span><span class='line'># 2. Copy some video files on videos subfolder
</span><span class='line'># 3. Point you PSP browser to the http://<address>:<port>/ and the psp browser will display a page to
</span><span class='line'># subscribe to the feed.
</span><span class='line'># 4. Go to Psp->Network->RSS Channel and select the new feed
</span><span class='line'># 5. A list of items should appear and pressing X will download the video files to your VIDEO folder
</span><span class='line'># on the PSP memory stick
</span><span class='line'># Please note that depending of your firmware and the encoder you used on your files PSP may refuse
</span><span class='line'># to play those files from the VIDEO folder. The VIDEO folder is not just like the MP_ROOT/100ANV01
</span><span class='line'># folder, it behaves a different way. So please first check and transfer some of your files via USB to the
</span><span class='line'># VIDEO folder and check that the PSP is able to play them from there.
</span><span class='line'># If you encode your files using the Media Manager for PSP software then those files will work in any folder.
</span><span class='line'># If you use 3GP encoder and QVGA MPEG-4 then those also will work in the VIDEO folder. but if you use
</span><span class='line'># another resolution or AVC codec then it won't work.
</span><span class='line'>use HTTP::Daemon;
</span><span class='line'>use HTTP::Status;
</span><span class='line'>use XML::RSS;
</span><span class='line'>use MP4::Info;
</span><span class='line'>use File::stat;
</span><span class='line'>use Time::localtime;
</span><span class='line'>use URI::Escape;
</span><span class='line'>use Encode;
</span><span class='line'>use LWP::MediaTypes;
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>#configuration
</span><span class='line'>my $feedtitle = "Perl Video Feed";
</span><span class='line'>my $feeddesc = "ecerulm perl video feed";
</span><span class='line'>my $hostname = "192.168.1.3";
</span><span class='line'>my $port = 1111;
</span><span class='line'>my $debug = 1;
</span><span class='line'>#end of configuration
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>my $rootaddr="http://" . $hostname . ":" . $port;
</span><span class='line'>my $ct = "video/m4v";
</span><span class='line'>
</span><span class='line'>LWP::MediaTypes::add_type($ct => qw(mp4 MP4));
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>my $d = HTTP::Daemon->new(LocalPort => $port) || die;
</span><span class='line'>
</span><span class='line'>print "Please contact me at: <URL:", $d->url, ">\n";
</span><span class='line'>while (my $c = $d->accept) {
</span><span class='line'> while (my $r = $c->get_request) {
</span><span class='line'>
</span><span class='line'> my $url = URI::Escape::uri_unescape($r->url->path);
</span><span class='line'> print $r->method . " " . "$url\n" if $debug;
</span><span class='line'> if ($r->method eq 'GET' and $url eq "/") {
</span><span class='line'> print "sending index.htm\n";
</span><span class='line'> $c->send_file_response("index.htm");
</span><span class='line'> } elsif ($url eq "/index.rss") {
</span><span class='line'> print "generating RSS content\n";
</span><span class='line'> my $rss = new XML::RSS (version => '2.0');
</span><span class='line'> $rss->channel(title => $feedtitle,
</span><span class='line'> link => $rootaddr,
</span><span class='line'> description => $feeddesc,
</span><span class='line'> );
</span><span class='line'>
</span><span class='line'> $rss->image(title => 'Perl video feed',
</span><span class='line'> url => $rootaddr . "/images/feedimage.jpg",
</span><span class='line'> link => $rootaddr,
</span><span class='line'> width => 88,
</span><span class='line'> height => 115,
</span><span class='line'> description => 'feed logo'
</span><span class='line'> );
</span><span class='line'>
</span><span class='line'>
</span><span class='line'> # videos
</span><span class='line'> my @fileList = <videos/*.MP4>;
</span><span class='line'> foreach $file (@fileList) {
</span><span class='line'> my $tag = get_mp4tag($file) or die "No TAG info";
</span><span class='line'> $date_string = ctime(stat($file)->mtime);
</span><span class='line'>
</span><span class='line'> #my $enclosurelink = "http://192.168.1.3:1111/" . URI::Escape::uri_escape_utf8($file);
</span><span class='line'> my $enclosurelink = $rootaddr . "/" . URI::Escape::uri_escape_utf8($tag->{NAM}) . ".MP4";
</span><span class='line'> #my $enclosurelink =~ s/videos%2F/videos\//;
</span><span class='line'> $rss->add_item(title => $tag->{NAM},
</span><span class='line'> enclosure => {
</span><span class='line'> url=>$enclosurelink,
</span><span class='line'> type=>$ct,
</span><span class='line'> },
</span><span class='line'> description => $tag->{NAM},
</span><span class='line'> pubDate=>$date_string
</span><span class='line'>
</span><span class='line'> );
</span><span class='line'> }
</span><span class='line'> # or save it to a file
</span><span class='line'> my $rs = new HTTP::Response(RC_OK);
</span><span class='line'> $rs->header('Content-type', "application/rss+xml");
</span><span class='line'> $rs->content($rss->as_string) if $r->method eq 'GET';
</span><span class='line'> $c->send_response($rs);
</span><span class='line'> print "RSS content sent\n" if $debug;
</span><span class='line'>
</span><span class='line'> } elsif (-e "." . $url) {
</span><span class='line'> print "the $url maps directly to a file in the filesystem\n" if $debug;
</span><span class='line'> if ($r->method eq 'GET') {
</span><span class='line'> print "sending " . $r->method . " " . $url . "\n";
</span><span class='line'> $c->send_file_response("." . $url) if $r->method eq 'GET';
</span><span class='line'> } else {
</span><span class='line'> print "sending HEAD " . $url . "\n";
</span><span class='line'> $c->send_basic_header;
</span><span class='line'> print $c "Content-type: $ct\n\n";
</span><span class='line'> }
</span><span class='line'> } else {
</span><span class='line'> print "$url doesn't map to file directly. We assume the url is the movie title\n" if $debug;
</span><span class='line'> my $t = $url;
</span><span class='line'> $t = Encode::decode("UTF-8", $t);
</span><span class='line'> $t = substr($t,1,-4); #remove the ".mp4" part.
</span><span class='line'> print "looking for a file with movie title: $t\n" if $debug;
</span><span class='line'>
</span><span class='line'>
</span><span class='line'> my @files = <videos/*.MP4>;
</span><span class='line'> my $found = 0;
</span><span class='line'> foreach $f (@files) {
</span><span class='line'> my $tag = get_mp4tag($f) or next;
</span><span class='line'> if ($tag->{NAM} eq $t) {
</span><span class='line'> print "sending " . $f . " file\n";
</span><span class='line'> $c->send_file_response($f);
</span><span class='line'> $found = 1;
</span><span class='line'> last;
</span><span class='line'> }
</span><span class='line'> }
</span><span class='line'> unless ($found) {
</span><span class='line'> print "cannot find " . $url . " using method " . $r->method . "\n";
</span><span class='line'> $c->send_error(RC_NOT_FOUND);
</span><span class='line'> }
</span><span class='line'> }
</span><span class='line'> }
</span><span class='line'> $c->close;
</span><span class='line'> undef($c);
</span><span class='line'>}</span>
If you faced the following subversion message in windows:
svn: PROPFIND request failed on '/repos/demosystemeic'
svn: PROPFIND of '/repos/demosystemeic': 503 Service Unavailable (http://x.x.x.x)
Probably the problem is caused because you are proxying your request via a proxy that doesn’t support HTTP methods like PROPFIND, etc.
If you don’t really need the proxy to access the repository edit the file c:\Documents and Settings\_username_\Application Data\Subversion\servers (Note: Subversion directory is hidden)
and comment out the following items
http-proxy-host=xxx
http-proxy-port=xxx
NOTE: In linux the file is located at ~/.subversion/servers+
Today I opened a new feature request (http://rt.cpan.org/Ticket/Display.html?id=25178) on MP4::Info perl module to include my patch to read the title in a Sony PSP files. Read this post to know more about the way title is encoded in PSP Mp4 files. With the following patch mp4infopatch.txt (applied to Info.pm) you can read the title of an PSP MP4 file using the following code snippet:
1234567891011
1 2 3 4 5 6 7 8 9 10 11
<span class='line'>use MP4::Info;
</span><span class='line'>my $file = 'MAQ12033.MP4';
</span><span class='line'>
</span><span class='line'>my $tag = get_mp4tag($file) or die "No TAG info";
</span><span class='line'>printf "$file title is %s\n", $tag->{NAM};
</span><span class='line'>
</span><span class='line'>my $info = get_mp4info($file);
</span><span class='line'>printf "$file title is %s\n", $info->{NAM};
</span><span class='line'>
</span><span class='line'>my $mp4 = new MP4::Info $file;
</span><span class='line'>printf "$file title is %s\n", $mp4->title;</span>
UPDATE: Jonathan Harris has released a new version of MP4::Info with support for Sony’s PSP files. more info
If you’re new to the PSP you must remember when copying files video files (created with 3GP converter or PSP Video 9) to your PSP that M4Vxxxxx.MP4 files go to the MP_ROOT/100MNV01 dir of the Memory Stick and the MAQxxxxx.MP4 files go to MP_ROOT/101ANV01 dir.
M4Vxxxxx files are conventional MPEG-4 files and MAQxxxxx are MPEG-4 files using AVC codec (recommended).
If you had tried to read the title of a Sony PSP MP4 file with Ruby’s mp4info or Perl’s MP4::Info you probably noticed that the title is not stored in the NAM tag where it should be.
Those two libraries cannot access the title info in Sony PSP files because title info is stored in a propierary way in a custom uuid atom called USMT (User Media Tags).
Inside this atom there is child atom called MTDT (Meta Data) that lists meta data entries, one of them is the title. I found all this information in the movenc.c file from ffmpeg
+/*********
+
+ PSP USMT->MTDT meta info block format (some guessing)
+
+ - Note that clips play fine without this block.
+
+ int32 : size of MTDT block
+ char[4] : "MTDT"
+ int16 : Number of sub-data blocks (payloads)
+ 0x0001 EOT markers have 1 block
+ 0x0004 is the most I've seen in an information block (title, date, etc)
+
+ Some number of data blocks, which take the form of:
+
+ int16 : size of sub-data block
+ int32 : block type ID (possibly 2 int16s: unk & type )
+ 0x01 = Title
+ 0x03 = Timestamp (date format = "+%Y-%m-%d %k:%M:%S")
+ 0x04 = Creator Name
+ 0x0A = End of Track Marker
+ 0x0B = UNKNOWN (appears in info MTDT blocks)
+ int16 : ?flags? - generally 0x55c4 or 0x15c7, seen 0x2a0e, possibly font or language?)
+ - Timestamp seems to always have 0x55c4
+ int16 : type of payload that follows? (int, string, etc..?)
+ - Unicode strings have 0x0001
+ - short[] data has 0x0000
+ data[] : Payload (strings are UTF16-BE short[] with 0x0000 terminator)
+
+
+ BLOCK IDs
+
+ 0x000A - Appear at end of tracks
+
+ - flags always = 0x55c4
+ - Payload looks like: 0x0000 0x0100 0x0000 0x0000
+
+ 0x000B - Appears in meta data
+ - Payload looks like: 0x0000 0x?????
+ - (0x???? probably flags- seen 0x1c02, 0x5cfe. Maybe something with aspect ratio or frame rate?)
+
+********/
Currently neither mp4info nor MP4::Info are capable of decoding this USMT→MTDT block. I’m looking into MP4::Info in order to add support for it. I will post something here if I got it working.UPDATE: I got it working read post