LinHES Forums http://forum.linhes.org/ |
|
Modified myth2ipod for ripping DVD to iPod http://forum.linhes.org/viewtopic.php?f=17&t=16945 |
Page 1 of 1 |
Author: | nickca [ Fri Oct 12, 2007 3:48 am ] |
Post subject: | Modified myth2ipod for ripping DVD to iPod |
Hello all, Here is a modified version of myth2ipod I wrote to rip DVDs to H.264/AAC videos and create an RSS feed for iTunes. I use my KnoppMyth box as a video jukebox rather than a PVR, and I have a dedicated 500GB drive with ripped DVD ISOs on it. This script takes an ISO, mounts it, and rips the video to H.264/AAC. I also put in options to transcode other videos (.avi, etc.) but I haven't tried that yet. You could easily modify it to directly rip DVDs, but they'd have to be unencrypted, so it's better to just rip to ISO first. The ISO must be indexed by Video Manager to grab the title, plot synopsis, etc. for the RSS feed, and the script is interactive so it must be run from a terminal. It uses your choice of either ffmpeg or HandBrake (not included in KM by default, but easily added, just go to handbrake.m0k.org and download the Linux command line binary). I added a line to the XML for cover art, do "ln -s /myth/video/.covers /myth/ipodfeed/covers" for it to work, but it doesn't seem to show up properly in iTunes anyway. Here is the code, comments, suggestions, improvements, etc are welcome: Code: #!/usr/bin/perl
use DBI; my $handbrake_options_ipod_low = "-e x264b30 -b 700 -B 160 -R 48 -E faac -f mp4 -w 320 -x keyint=300:keyint-min=30:bframes=0:cabac=0:ref=1:vbv-maxrate=768:vbv-bufsize=2000:analyse=all:me=umh:subme=6:no-fast-pskip=1 -m"; my $handbrake_options_ipod_hi = "-e x264b30 -b 1500 -B 160 -R 48 -E faac -f mp4 -w 640 -x keyint=300:keyint-min=30:bframes=0:cabac=0:ref=1:vbv-maxrate=1500:vbv-bufsize=2000:analyse=all:me=umh:subme=6:no-fast-pskip=1 -m"; my $handbrake_options_standard = "-e x264 -b 1500 -B 160 -R 48 -E faac -f mp4 -x ref=2:bframes=2:subme=5:me=umh -m -p -2 -T -w 320"; my $handbrake_options_classic = "-b 1000 -B 160 -R 48 -E faac -f mp4 -w 320"; my $ffmpeg_options = "-f mp4 -r 29.97 -vcodec mpeg4 -maxrate 768 -b 700 -qmin 3 -qmax 5 -bufsize 4096 -g 250 -acodec aac -ar 44100 -ab 160 -async 1 -s 320x240 -aspect 4:3"; my $ffmpeg_options_pal = "-f mp4 -r 25 -vcodec mpeg4 -maxrate 768 -b 700 -qmin 3 -qmax 5 -bufsize 4096 -g 250 -acodec aac -ar 44100 -ab 160 -async 1 -s 320x240 -aspect 4:3"; $handbrake = $handbrake_options_ipod_low; my $portable = "ipod"; # paths for RSS feed, leave these unless you've modified your KM install my $feedfile = "/myth/ipodfeed/feed.php"; my $feedpath = "/myth/ipodfeed/"; # default path where ISO/video is, you can also specify on the cmd line my $dvdisopath = "/myth/video/dvd/"; # path where ISO will be mounted my $mountpath = "/mnt/loop"; # path to www files, leave this unless you've modified your KM install my $wwwloc = "/var/www/"; my $host = "PUT YOUR HOSTNAME HERE"; my $feedurl = "http://$host/ipodfeed/"; sub DisplayUsage { print "usage: dvd2ipod <iso file> <encoder> <directory>\n\nDirectory is optional, if not specified dvd2ipod will look for the file in $dvdisopath\n\nEncoder can be one of:\n\thandbrake: Use HandBrake to convert to H.264/AAC\n\tffmpeg: Use ffmpeg to convert to H.264/AAC\n\tffmpegpal: Use ffmpeg for PAL source\n\n"; exit; } if($ARGV[1] ne "handbrake" && $ARGV[1] ne "ffmpeg" && $ARGV[1] ne "ffmpegpal") { print "Invalid encoder\n\n"; DisplayUsage(); exit; } else { if($ARGV[1] eq "ffmpegpal") { $ffmpeg_options = $ffmpeg_options_pal; our $encoder = "ffmpeg"; } else { our $encoder = $ARGV[1]; } } if($ARGV[2]) { $dvdisopath = $ARGV[2]; } my $debug = 1; if(!($ARGV[0]) || !($ARGV[1])) {! DisplayUsage(); } our $file = $ARGV[0]; our ($basefile, $fileext) = split(/\./,$file); if($fileext == "iso") { $is_iso = 1; } our $mountfile = $dvdisopath.$file; if (! -e $mountfile) { print "$file does not exist in $dvdisopath\n"; exit; } print "Encoding file...\n"; Encode4Portable(); if(! -e $feedfile) { print "(Re)generating RSS feed...\n"; GenerateRSSFeed(); } sub Encode4Portable { if($is_iso == 1) { system("mount -o loop $mountfile $mountpath"); } PrepSQLRead(); $db_handle = DBI->connect("dbi:mysql:database=$db_name:host=$db_host", $db_user, $db_pass) or die "Cannot connect to database\n"; $sql = "SELECT title,plot,category,coverfile,rating,year,length FROM videometadata WHERE filename='$mountfile'"; if($debug == 1) { print "SQL: $sql\n"; } $statement = $db_handle->prepare($sql) or die "Couldn't prepare query $sql: $DBI::errstr\n"; $statement->execute() or die "Couldn't execute query $sql: $DBI::errstr\n"; $row_ref = $statement->fetchrow_hashref(); $title = $row_ref->{title}; $description = $row_ref->{plot}; $category = $row_ref->{category}; $coverfile = $row_ref->{coverfile}; $rating = $row_ref->{rating}; $year = $row_ref->{year}; $length = $row_ref->{length}; $filename = $mountfile; printf("Starting encoder...\n"); EncodeIt(); printf("Encoding complete. Generating RSS...\n"); CreateItemXML(); printf("XML created for $filename\n"); printf("Cleaning up...\n"); if($is_iso == 1) { system("umount $mountpath"); } system("rm -f $feedpath$basefile.temp.mp4"); } sub EncodeIt { if($is_iso == 1) { if($encoder eq "handbrake") { system("/usr/local/bin/HandBrakeCLI -i $mountpath/VIDEO_TS -t 0"); $titletorip = &promptUser("\nSelect a title to rip: ","1"); $outfile = $basefile."_title$titletorip".".temp.mp4"; $outpath = $feedpath.$outfile; $finaloutpath = $feedpath.$basefile."_title$titletorip".".".$portable.".mp4"; $cmd = "/usr/local/bin/HandBrakeCLI -i $mountpath/VIDEO_TS -o $outpath -t $titletorip $handbrake"; } if($encoder eq "ffmpeg") { $outfile = $basefile.".temp.mp4"; $outpath = $feedpath.$outfile; $finaloutpath = $feedpath.$basefile.".".$portable.".mp4"; $cmd = "cat $mountpath/VIDEO_TS/*.VOB | ffmpeg -i - $ffmpeg_options $outpath"; } } else { $outfile = $basefile.".temp.mp4"; $outpath = $feedpath.$outfile; $finaloutpath = $feedpath.$basefile.".".$portable.".mp4"; if($encoder eq "handbrake") { $cmd = "/usr/local/bin/HandBrakeCLI -i $dvdisopath/$file -o $outpath $handbrake"; } if($encoder eq "ffmpeg") { $cmd = "ffmpeg -i $dvdisopath/$file $ffmpeg_options $outpath"; } } if($debug == 1) { print "Encoder: $cmd\n"; } if(system($cmd)) { print "Encoder failed.\n"; } $cmd = "/usr/local/bin/MP4Box -add $outpath $finaloutpath"; if($debug == 1) { print "MP4Box: $cmd\n"; } if(system($cmd)) { print "MP4Box cleanup failed.\n"; } } sub CreateItemXML { $usetitle = &promptUser("\nEnter a title (hit return for \"$title\"): ",$title); $usedescription = &promptUser("\nEnter a description (hit return for \"$description\"): ",$description); $finalouturl = $feedurl.$basefile.".".$portable.".mp4"; my ($a, $b, $c, $d, $cover) = split("/", $coverfile); my $coverurl = $feedurl."covers/".$cover; open(ITEM, ">$feedpath$basefile.$portable.xml"); print ITEM "<item>\n"; print ITEM "<title>".&encodeForXML($usetitle)."</title>\n"; print ITEM "<itunes:author>MythTV</itunes:author>\n"; print ITEM "<author>MythTV</author>\n"; print ITEM "<itunes:category text=\"Movies\"></itunes:category>\n"; print ITEM "<comments>".&encodeForXML($file)."</comments>\n"; print ITEM "<description>".&encodeForXML($usedescription)."</description>\n"; print ITEM "<pubDate>".&encodeForXML(`date`)."</pubDate>\n"; print ITEM "<enclosure url=\"".&encodeForXML($finalouturl)."\" type=\"video/quicktime\" />\n"; print ITEM "<itunes:duration></itunes:duration>\n"; print ITEM "<itunes:keywords>".&encodeForXML($title)."</itunes:keywords>\n"; print ITEM "<itunes:image href=\"".&encodeForXML($coverurl)."\" />\n"; print ITEM "</item>\n"; print "$filename added to feed.\n"; close(ITEM); return 0; } sub GenerateRSSFeed { open(RSS, ">$feedfile"); print RSS "<?php\n"; print RSS "header(\"Content-Type: text/xml\");\n"; print RSS "echo \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\"; ?>\n"; print RSS "<rss xmlns:itunes=\"http://www.itunes.com/DTDs/Podcast-1.0.dtd\" version=\"2.0\">\n"; print RSS "<channel>\n"; print RSS "<title>MythTV - <? if (\$_GET['title'] == \"\") { \$title = \"*\"; echo \"Recorded Programs\"; }\n"; print RSS "else { \$title = \$_GET['title']; echo str_replace(\"_\",\" \",\$_GET['title']); } ?> </title>\n"; print RSS "<itunes:author>MythTV - myth2ipod</itunes:author>\n"; print RSS "<link>".&encodeForXML($feedurl)."</link>\n"; print RSS "<itunes:subtitle>Transcoded recording for your iPod Video.</itunes:subtitle>\n"; print RSS "<itunes:summary>Myth TV Recorded Programs for the iPod v.1</itunes:summary>\n"; print RSS "<description>Myth TV Recorded Programs for the iPod v.1</description>\n"; print RSS "<itunes:owner>\n"; print RSS "<itunes:name>MythTV</itunes:name>\n"; print RSS "<itunes:email>mythtv\@localhost</itunes:email>\n"; print RSS "</itunes:owner>\n"; print RSS "<itunes:explicit>No</itunes:explicit>\n"; print RSS "<language>en-us</language>\n"; print RSS "<copyright>Copyright 2005.</copyright>\n"; print RSS "<webMaster>mythtv\@localhost</webMaster>\n"; print RSS "<itunes:image href=\"http://myth2ipod.com/mythipod_200.jpg\" />\n"; print RSS "<itunes:category text=\"TV Shows\"></itunes:category>\n"; print RSS "<category>TV Shows</category>\n"; print RSS "<itunes:image href=\"http://myth2ipod.com/mythipod_200.jpg\"/>"; print RSS "<image>"; print RSS "<url>http://myth2ipod.com/mythipod_200.jpg</url>\n"; print RSS "<title>MythTV 2 iPod</title>\n"; print RSS "<link>".&encodeForXML($feedurl)."</link>\n"; print RSS "<width>200</width>\n"; print RSS "<height>200</height>\n"; print RSS "</image>\n"; print RSS "<? foreach (glob(\$title\.\"*\.$portable\.xml\") as \$file) {include \$file;} ?>\n"; print RSS "</channel>\n"; print RSS "</rss>\n"; close(RSS); if($debug == 1){ print "I created a feed file, was I supposed to?\n"}; return 0; } # # This code taken from one of the mythlink.sh scripts to get MySQL information # sub PrepSQLRead{ # Get the hostname of this machine $hostname = `hostname`; chomp($hostname); # Read the mysql.txt file in use by MythTV. # could be in a couple places, so try the usual suspects my $found = 0; my @mysql = ('/usr/local/share/mythtv/mysql.txt', '/usr/share/mythtv/mysql.txt', '/etc/mythtv/mysql.txt', '/usr/local/etc/mythtv/mysql.txt', "$ENV{HOME}/.mythtv/mysql.txt", 'mysql.txt' ); foreach my $file (@mysql) { next unless (-e $file); $found = 1; open(CONF, $file) or die "Unable to open $file: $!\n\n"; while (my $line = <CONF>) { # Cleanup next if ($line =~ /^\s*#/); $line =~ s/^str //; chomp($line); # Split off the var=val pairs my ($var, $val) = split(/\=/, $line, 2); next unless ($var && $var =~ /\w/); if ($var eq 'DBHostName') { $db_host = $val; } elsif ($var eq 'DBUserName') { $db_user = $val; } elsif ($var eq 'DBName') { $db_name = $val; } elsif ($var eq 'DBPassword') { $db_pass = $val; } # Hostname override elsif ($var eq 'LocalHostName') { $hostname = $val; } } close CONF; } die "Unable to locate mysql.txt: $!\n\n" unless ($found && $db_host); return 0; } sub promptUser { local($promptString,$defaultValue) = @_; if ($defaultValue) { print $promptString, "[", $defaultValue, "]: "; } else { print $promptString, ": "; } $| = 1; # force a flush after our print $_ = <STDIN>; # get the input from STDIN (presumably the keyboard) chomp; if ("$defaultValue") { return $_ ? $_ : $defaultValue; # return $_ if it has a value } else { return $_; } } # substitute for XML entities sub encodeForXML { local $result; $result = $_[0]; $result =~ s/&/&/g; $result =~ s/</</g; $result =~ s/>/>/g; $result; } |
Author: | nickca [ Fri Oct 12, 2007 3:50 am ] |
Post subject: | |
Oh, and just for grins, here's the script I use to rip DVDs. I got this from somewhere else and modified it some. Code: #!/bin/sh
#script to backup full dvd's including menu's #needs the dvdbackup tool from http://dvd.chevelless230.com/dvdbackup.html # set these to match your system settings dvddevice="/dev/dvd" # temp storage while creating iso image (could use tmp if that is on a big partition) dvdstorage="/media/sdb1/temp" mythvideodir="/media/sdb1/iso" ################################## #make a complete copy of the dvd echo "Copying DVD" dvdbackup -i $dvddevice -o $dvdstorage -M naam=`ls $dvdstorage` #get the DVD name from the foldername created by dvdbackup echo $dvdstorage"/"$naam echo $mythvideodir"/"$naam echo "Creating ISO" mkisofs -dvd-video -udf -V "Backup DVD" $dvdstorage"/"$naam > $mythvideodir"/"$naam".iso" chown mythtv.mythtv $mythvideodir"/"$naam".iso" echo "Cleaning up" rm -rf /media/sdb1/temp/* #echo "Squashing ISO" #mksquashfs $mythvideodir"/"$naam".iso" $mythvideodir"/"$naam".squash" -no-duplicates #rm $mythvideodir"/"$naam".iso" mythtvosd --template=alert --alert_text='DVD rip completed!' aplay /home/nickca/rip_completed.wav |
Author: | thornsoft [ Fri Oct 12, 2007 6:21 am ] |
Post subject: | |
This sounds great. I need this. Thanks for contributing. I hope to check it out this weekend. -- Chris |
Author: | thornsoft [ Tue Oct 16, 2007 6:27 pm ] |
Post subject: | |
Something wrong? I get this: Code: root@mythtv:/# dvd2ipod.sh SOME_DVD.iso handbrake
Encoding file... mount: mount point /mnt/loop does not exist SQL: SELECT title,plot,category,coverfile,rating,year,length FROM videometadata WHERE filename='/myth/video/dvd/SOME_DVD.iso' Starting encoder... HandBrake 0.9.1 (2007100800) - http://handbrake.m0k.org/ 1 CPU detected Opening /mnt/loop/VIDEO_TS... ERROR: dvd: DVDOpen failed (/mnt/loop/VIDEO_TS)No title found. HandBrake has exited. I tried ffmpeg too... Maybe there's a step that you did, that I didn't do? I'm on R5F27. Probem seems to be /mnt/loop |
Author: | thornsoft [ Tue Oct 16, 2007 6:40 pm ] |
Post subject: | |
Duh, I tried creating /mnt/loop and now it's running.... I'll report back. |
Author: | nickca [ Sun Oct 21, 2007 2:27 pm ] |
Post subject: | |
It doesn't necessarily have to be /mnt/loop, all the variables at the top (inluding the HandBrake and ffmpeg options) can be changed to whatever you want. Also, unless you're running a DNS server on your local network or have added the IP address and hostname to the hosts file of whatever machine(s) you run iTunes on, it's easier to just put the IP address of your Myth box where it says "PUT YOUR HOSTNAME HERE" instead of the hostname. Same goes for the stock myth2ipod. For example, mine is set to 192.168.0.153 instead of the hostname "vidiot". Oh, and you will have problems with both this and myth2ipod (and mythweb and any number of other things) if your myth box is getting its IP address from DHCP rather than a static IP that you've set. Do "man interfaces", read it, and edit /etc/network/interfaces to set up a static IP. |
Author: | Too Many Secrets [ Tue Oct 23, 2007 12:13 pm ] |
Post subject: | |
This looks real handy. Will it work for .vob rips as well as iso's ? |
Page 1 of 1 | All times are UTC - 6 hours |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |