Log in

View Full Version : Rip Movie Collection for PS3 playback


enderandrew
11th January 2009, 23:25
I have over 400 DVD's, and frankly I'm running out of room to keep all the discs and cases. I'm building a new PC with my tax rebate, and I was thinking of getting a bunch of 1.5 TB HDD's for a RAID array and ripping my entire DVD collection.

I dual-boot Windows and Linux (technically triple-boot, but I digress).

I am not expecting the videos to look absolutely perfect, nor do I assume one codec and setting with work best with all my movies. However, with 400 movies I do want to find a good generic codec and setting that will work fairly well for my entire collection.

I intend to stream movies to my PS3 to watch them on the TV. So the codec and container must be something the PS3 can play.

I'm hoping to get decent video quality, with movies averaging 1 gig or less in file size. From what I've read, x.264 seems to be the best codec to use, but I'm certainly open to suggestions.

I've tried converting a few downloaded video files with Any Video Converter, and sometimes they play on the PS3, and sometimes they don't, even when I use the same codec settings.

Can someone please recommend an app for ripping my DVD collection?

dat720
12th January 2009, 15:24
x264 is certaily the go...it gives better video quality for the same bitrate as xvid or divx.....

Your file size targets are realistic too, but don't set your mind on file sizes, instead aim for desired quality and accept the file size you get, using CRF encoding in x264 is useful for this.

PS3 is abit of a picky bugger when it comes to video's.... XVID/DIVX + MP3/AC3 in a AVI container will be the most compatible for the PS3, x264 + AAC in a MP4 container will look better, but it's hard to get right sometimes, another nice option is to put x264 + AAC/AC3/MP3 in a m2ts Container, this i what i use for my HD video's.

To do what you are suggesting i have a automated VB script which does a very nice job, only catch is it can take a fair bit of fiddling to get right.

To get movies to the PS3 i use a MythTV (mythbuntu) box which is used as the main "hub" in my house for media, I disabled the inbuilt uPnP server and installed MediaTomb, It's running on a Old SlimLine HP PC i used to use as my main PC (Pentium D 935, 2GB Ram, 256mb ATI Graphics Card) and it's Rock Solid!!! it's currently been up for 25 Days 5 hours 9 mins...

enderandrew
12th January 2009, 17:12
Thanks for your response!

I'd love to see the script you put together. Even if it requires fiddling, it might get me started in the right direction.

I thought MP4 was the primary, recommended container for the PS3. What are the pros and cons of going with MP4 vs m2ts and vice-versa? I'm not familiar with m2ts at all.

dat720
12th January 2009, 22:29
It is you are right, but i've had better luck with m2ts it's far less picky with m2ts than it is with MP4.

The original script was posted by AliendMind, i made some changes and added soem smarts to suit myself, you will need mplayer, mencoder and eac3to... and depending on the discs you may need AnyDVD.

If you use mine make sure you go down to line 301 and change the path to eac3to... i was lazy and didn't give it a nice variable like AlienMind did for mplayer and mencoder

Heres my Modified Script:
'Option Explicit
'Option Explicit
If LCase(Right(Wscript.FullName, 11)) = "wscript.exe" Then
Set objShell = CreateObject("Wscript.Shell")
objShell.Run("%comspec% /c cscript.exe /nologo " & """" & Wscript.ScriptFullName & """") : Wscript.Quit
End If

Wscript.StdOut.Write "Scanning Drives, please wait.... " & vbCrLf & vbCrLf
Dim name
Dim objFSO, colDrives, DriveCount,i, strRip
set objFSO = CreateObject("Scripting.FileSystemObject")
set colDrives = objFSO.Drives
strRip = False

For Each objDrive In colDrives
If objDrive.DriveType = 4 Then
if strRip = False then Wscript.StdOut.Write vbCrLf & vbCrLf
if strRip = False then Wscript.StdOut.Write objDrive.DriveLetter & ": " & objDrive.VolumeName & vbCrLf
if strRip = False then Wscript.StdOut.Write "Is this the Disc you wish to rip? [y/n] "
if strRip = False then if Wscript.StdIn.ReadLine = "y" then strRip = objDrive.DriveLetter & ":," & objDrive.VolumeName
End If
Next
if strRip = False then Wscript.StdOut.Write vbCrLf & "Error: No Drive Selected" : wscript.quit

Wscript.StdOut.Write vbCrLf & vbCrLf

Wscript.StdOut.Write "Enter size in MB for Rips: [if nothing entered defualt = 700] "
SizeMB = Wscript.StdIn.ReadLine
if SizeMB = "" then SizeMB = 700
If Not IsNumeric(SizeMB) then Wscript.StdOut.Write vbCrLf & "Error: Value entered is not a number" : wscript.quit


Wscript.StdOut.Write vbCrLf & vbCrLf

strRip = split(strRip,",")

dvdPath = strRip(0)
strText = strRip(1)
strText = replace(strText,"_"," ")
dvdname = trim(PCase(strText))

Wscript.StdOut.Write "Drive: " & dvdPath & vbCrLf
Wscript.StdOut.Write "Label: " & dvdname & vbCrLf
Wscript.StdOut.Write "Size: " & SizeMB & vbCrLf



' Installation:
'
' 1) Download "MPlayer/MEncoder svn rev 27811" or higher @ http://oss.netfarm.it/mplayer-win32.php ,
' extract somewhere and set "mplayerPath" to it.
'
' 2) Download "MKVToolnix installer for v2.4.0" or higher @ http://www.bunkus.org/videotools/mkvtoolnix/downloads.html#windows ,
' install and set "mkvtoolnixPath" to it.
'
' 3) Create empty directory somewhere,
' save this script there
' do "cmd" and switch to that directory
'
'
' Usage:
' Adjust sizeMB below (size of whole DVD after storage)
' Enter: cscript rip.vbs
' This will store all dvd's title(s) (with all audio and subtitle tracks) to local directory
' using h264/aac (and multiple cpu's if you have them) correctly cropped and scaled as mkv file(s)
'
' Known Vista Annoyance:
' - I've detected a "mplayer has stopped working" in M$ Vista after the second pass encoding step.
' Please just push "quit program" here.
' It's the "problem report service" "werfault.exe" and there is NO way to deactivate this,
' you can only change it's looks in the control panel...
' BUT: Just write a batch file and put the following 4 lines in it:
' :a
' ping 127.0.0.1
' taskkill /IM werfault.exe
' goto a
' Run that in a new "cmd" and it will take care of that prick.
'
' Changelog:
' - removed brdo:bime for MPlayer-p4-svn-27811
'
' - added cooler stuff:
' adding partitions=all after direct_pred for enabling bigger block-sizes at all
' adding 8x8dct after partitions=all for intelligent macroblock choosing
' adding bframes=3 after frameref for enabling autoinsertion of 0-3 bframes at all
'
' Comments:
' The subwindows are still getting focus (http://msdn.microsoft.com/en-us/library/d5fk67ky(VS.85).aspx)
' Already Tried 8, 10
'
' If you get "too much audio frames", you must omit "-noskip" and fix the audio later



'size of rip in MB
'sizeMB= 1400

mplayerPath = "E:\VidTools\AutoMen"
mkvtoolnixPath = "C:\Program Files\MKVtoolnix"
eac3topath = "E:\vidtools\eac3to"
temppath = "E:\vidtools\DVD Rip\Temp\"
' assume dot as comma
SetLocale("en-us")

function error(str)
WScript.StdOut.Write(str)
WScript.Quit(1)
end function

function print(str)
'WScript.StdOut.Write(str & '\r\n')
WScript.Echo(str)
end function


Set fsObj = CreateObject("Scripting.FileSystemObject")

dim sidArr()
' first element is always skipped because UBound function breaks on null entry otherwise
ReDim Preserve sidArr(1)
sidArr(1) = "dummy"

dim aidArr()
' first element is always skipped because UBound function breaks on null entry otherwise
ReDim Preserve aidArr(1)
aidArr(1) = "dummy"


' Get..
cmdStr= mplayerPath & "\mplayer.exe -identify -nosound -novideo -dvd-device " & dvdPath & " dvd://999"
Set shellObj = WScript.CreateObject("WScript.Shell")
print("---")

print(vbCrLf & vbCrLf)
print("Total inventory")
print(vbCrLf & vbCrLf)

Set execObj = shellObj.Exec(cmdStr)
str = execObj.StdOut.ReadAll
Set regxObj = New RegExp
regxObj.Global = True

' .. title count
regxObj.Pattern = "ID_DVD_TITLES=([0-9]+)"
Set matchObj= regxObj.Execute(str)
if matchObj.Count <> 1 then
error("ERR: parse title count")
end if
titleCount= matchObj.Item(0).Submatches(0)

' .. total length => totalLength
regxObj.Pattern = "ID_DVD_TITLE_[0-9]+_LENGTH=([0-9.]+)"
Set matchObj= regxObj.Execute(str)
totalLength= 0
for i = 1 to matchObj.Count
totalLength= totalLength + CDbl(matchObj.Item(i-1).Submatches(0))
next

' ..subtitle-ids (info can't be fetched off the .vob's later) => sidArr
regxObj.Pattern = "ID_SUBTITLE_ID=([0-9]+)"
Set matchObj= regxObj.Execute(str)
for sidNum = 2 to matchObj.Count + 1
ReDim Preserve sidArr(sidNum)
sidArr(sidNum)= CInt(matchObj.Item(sidNum-2).Submatches(0))
next

' .. assuming two audiotracks with 80kb/s, the movie bitrate to use
videoBitrate= ( ( (sizeMB*2^20)-(totalLength*((80+80)*1000/8)) ) / ( totalLength ) ) * 8 / 1000
' this is some magic value, don't ask
'videoBitrate= CInt(videoBitrate * 0.92)
videoBitrate= videoBitrate * 0.92
' this is a safety lock against shitty quality
if videoBitrate < 400 then
videoBitrate = 400
end if

videoBitrate = round(videoBitrate)






for titleNum = 1 to titleCount

' Rip title
cmdStr= mplayerPath & "\mplayer.exe -benchmark -nosound -vo null -dumpstream -dumpfile " & titleNum & ".vob -dvd-device " & dvdPath & " dvd://" & titleNum
print(vbCrLf & vbCrLf)
print("Dumping Title " & titleNum)
returnVal= shellObj.Run(cmdStr, 0, true)
if returnval = 0 then
print("Title " & titleNum & " Dumped Successfully")
else
print("Error Dumping Title " & titleNum)
end if
next



for titleNum = 1 to titleCount
'for titleNum = 30 to 30

' Get..
cmdStr= mplayerPath & "\mplayer.exe -identify -benchmark -nosound -vo null -endpos 1 " & titleNum & ".vob"
print(vbCrLf & vbCrLf)
print("Creating track Inventory")
print(vbCrLf & vbCrLf)
Set execObj = shellObj.Exec(cmdStr)
str = execObj.StdOut.ReadAll

' ..audiotrack-ids => aidArr
regxObj.Pattern = "ID_AUDIO_ID=([0-9]+)"
Set matchObj= regxObj.Execute(str)
for aidNum = 2 to matchObj.Count +1
ReDim Preserve aidArr(aidNum)
aidArr(aidNum)= CInt(matchObj.Item(aidNum-2).Submatches(0))
next

' ..aspect ratio => aspectX I won't use ID_VIDEO_ASPECT because it appears
' twice, and the first time, it has 0.
regxObj.Pattern = "Movie-Aspect is ([0-9.]+):1"
Set matchObj= regxObj.Execute(str)
aspectX= CDbl(matchObj.Item(0).Submatches(0))

' ..source video width => videoW
regxObj.Pattern = "ID_VIDEO_WIDTH=([0-9]+)"
Set matchObj= regxObj.Execute(str)
videoW= CInt(matchObj.Item(0).Submatches(0))

' ..source video height => videoH
regxObj.Pattern = "ID_VIDEO_HEIGHT=([0-9]+)"
Set matchObj= regxObj.Execute(str)
videoH= CInt(matchObj.Item(0).Submatches(0))

' .. fps
regxObj.Pattern = "ID_VIDEO_FPS=([0-9.]+)"
Set matchObj= regxObj.Execute(str)
fps= CDbl(matchObj.Item(0).Submatches(0))



' Get crop detection info at the middle of the title..
' On some DVD's -ss doesen't work for seconds, but for filesize in mb:
Set objFile= fsObj.GetFile(titleNum & ".vob")
fSizeByte= objFile.Size
cmdStr= mplayerPath & "\mplayer.exe -v -ss " & (fSizeByte/1024/1024/2) & "mb -endpos 100 -benchmark -nosound -vf cropdetect=16:16 -vo null " & titleNum & ".vob"
print("---")
print("Cropdetection Command: " & cmdStr)
Set execObj = shellObj.Exec(cmdStr)
str = execObj.StdOut.ReadAll

' .. pixelX / pixelY / cropX / cropY
regxObj.Pattern = "crop=([0-9]+):([0-9]+):([0-9]+):([0-9]+)"
Set matchObj= regxObj.Execute(str)
if matchObj.Count = 0 then
pixelX = videoW
pixelY = videoH
cropX = 0
cropY = 0
else
pixelX= CInt(matchObj.Item(matchObj.Count-1).Submatches(0))
pixelY= CInt(matchObj.Item(matchObj.Count-1).Submatches(1))
cropX= CInt(matchObj.Item(matchObj.Count-1).Submatches(2))
cropY= CInt(matchObj.Item(matchObj.Count-1).Submatches(3))
end if

' Correct y height according to x/y ratio of aspectX:1
scaledY= CInt(pixelY * (videoW / (aspectX * videoH)))
scaledY= scaledY-(scaledY mod 16)

'crop = pixelX & "x" & pixelY & " at " & cropX & "x " & cropY
print("===")
print("Extracting " & titleNum & ".h264 . Taking rectangle of " & pixelX & "x" & pixelY & " at " & cropX & "x " & cropY & "y. According to aspect " & aspectX & " of source " & videoW & "x" & videoH & ", downscaling height to " & scaledY & " .")

' 1st pass
cmdStr= mplayerPath & "\mencoder -noskip " & titleNum & ".vob -oac pcm -vf crop=" & pixelX & ":" & pixelY & ":" & cropX & ":" & cropY & ",scale=" & pixelX & ":" & scaledY & " -ovc x264 -x264encopts level_idc=41:frameref=6:bframes=3:b_pyramid:direct_pred=auto:partitions=all:8x8dct:me=umh:subq=7:me_range=64:trellis=2:nofast_pskip:bitrate=" & videoBitrate & ":pass=1:turbo=1:threads=auto -of rawvideo -o NUL"
'cmdStr= mplayerPath & "\mencoder -noskip " & titleNum & ".vob -vf harddup,crop=" & pixelX & ":" & pixelY & ":" & cropX & ":" & cropY & ",scale=" & pixelX & ":" & scaledY & " -ovc x264 -x264encopts crf=16:frameref=3:bframes=3:b_pyramid:direct_pred=auto:weight_b:partitions=all:8x8dct:me=umh:mixed_refs:brdo:bime:trellis=1:nopsnr:nossim:subq=6:level_idc=41:threads=auto -nosound -of rawvideo -o " & titleNum & ".h264"

print("---")
print("First Pass Command: " & cmdStr)
returnVal= shellObj.Run(cmdStr, 1, true)
if returnval = 0 then print("1st Pass Complated Successfully")
if returnval = 0 then
print("1st Pass Complated Successfully")
else
print("Error During 1st Pass")
end if

' 2nd pass
cmdStr= mplayerPath & "\mencoder -noskip " & titleNum & ".vob -oac pcm -vf crop=" & pixelX & ":" & pixelY & ":" & cropX & ":" & cropY & ",spp,scale=" & pixelX & ":" & scaledY & ",hqdn3d=2:1:2 -ovc x264 -x264encopts level_idc=41:frameref=6:bframes=3:b_pyramid:direct_pred=auto:partitions=all:8x8dct:me=umh:subq=7:me_range=64:trellis=2:nofast_pskip:bitrate=" & videoBitrate & ":pass=2:threads=auto -of rawvideo -o " & titleNum & ".h264"
print("---")
print("Second Pass Command: " & cmdStr)
returnVal= shellObj.Run(cmdStr, 1, true)
if returnval = 0 then print("2nd Pass Complated Successfully")

' Audiotracks
for i = 2 to UBound(aidArr)
print("Extracting audio id " & aidArr(i) & " as " & titleNum & "-" & (i-1) & ".ac3")
'cmdStr= mplayerPath & "\mencoder -v -noskip " & titleNum & ".vob -ovc copy -aid " & aidArr(i) & " -af resample=44100:0:2,channels=2,volnorm -oac faac -faacopts tns:br=80 -of rawaudio -o " & titleNum & "-" & (i-1) & ".aac"
'cmdStr= mplayerPath & "\mencoder -v -noskip " & titleNum & ".vob -ovc copy -aid " & aidArr(i) & " -a52drc 1 -channels 2 -srate 44100 -af-adv force=1 -af volnorm=2:0.25 -oac faac -faacopts tns:br=80 -of rawaudio -o " & titleNum & "-" & (i-1) & ".aac"
cmdStr= eac3topath & "\eac3to.exe " & titleNum & ".vob " & titleNum & "-" & (i-1) & ".ac3"
print("---")
print("Audio Command: " & cmdStr)
returnVal= shellObj.Run(cmdStr, 1, true)
next

' Subtitles
for i = 2 to UBound(sidArr)
print("Extracting subtitle id " & sidArr(i) & " as " & titleNum & "-" & (i-1) & ".idx/sub")
' the .ifo contains color palette for subtitle images
cmdStr= mplayerPath & "\mencoder -v -noskip " & titleNum & ".vob -ovc copy -oac copy -sid " & sidArr(i) & " -ifo " & dvdPath & "\video_ts\vts_01_0.ifo -vobsubout " & titleNum & "-" & (i-1) & " -o NUL"
print("---")
print("Subtitle Command: " & cmdStr)
returnVal= shellObj.Run(cmdStr, 0, true)
next

' Join
cmdStr= """" & mkvtoolnixPath & "\mkvmerge.exe"" -o " & """" & dvdname & "-" & titleNum & """" & ".mkv --default-duration 0:" & fps & "fps --aspect-ratio 0:" & pixelX & "/" & scaledY & " " & titleNum & ".h264"
for i = 2 to UBound(aidArr)
cmdStr= cmdStr & " " & titleNum & "-" & (i-1) & ".ac3"
next
for i = 2 to UBound(sidArr)
cmdStr= cmdStr & " " & titleNum & "-" & (i-1) & ".idx"
next
print("---")
print("Join Command: " & cmdStr)
returnVal= shellObj.Run(cmdStr, 1, true)
next



function PCase(strInput)
Dim strArr
Dim tmpWord
Dim tmpString
Dim last

strArr = split(strInput," ")

if ubound(strArr) > 0 Then
For x = lbound(strArr) To ubound(strArr)
strArr(x) = LCase(strArr(x))

Select Case strArr(x)
Case "a"
Case "an"
Case "and"
Case "but"
Case "by"
Case "for"
Case "in"
Case "into"
Case "is"
Case "of"
Case "off"
Case "on"
Case "onto"
Case "or"
Case "the"
Case "to"
Case "a.m."
strArr(x) = "A.M."
Case "p.m."
strArr(x) = "P.M."
Case "b.c."
strArr(x) = "B.C."
Case "a.d."
strArr(x) = "A.D."
Case Else

if len(strArr(x)) > 1 Then
if mid(strArr(x),1,1) = "'" or mid(strArr(x),1,1) = """" Then
tmpWord = mid(strArr(x),1,1) & Ucase(mid(strArr(x),2,1)) & mid(strArr(x),3,len(strArr(x))-2)
Else
tmpWord = Ucase(mid(strArr(x),1,1)) & mid(strArr(x),2,len(strArr(x))-1)
End if
strArr(x) = tmpWord
End if

End Select

if x > 0 Then
if instr(strArr(x-1),"-") _
or instr(strArr(x-1),":") _
or instr(strArr(x-1),";") Then
tmpWord = Ucase(mid(strArr(x),1,1)) & mid(strArr(x),2,len(strArr(x))-1)
strArr(x) = tmpWord
End if
End if

Next
Else
strArr(0) = LCase(strArr(0))
End if

if mid(strArr(0),1,1) = "'" or mid(strArr(0),1,1) = """" Then
tmpWord = mid(strArr(0),1,1) & Ucase(mid(strArr(0),2,1)) & mid(strArr(0),3,len(strArr(0))-2)
Else
tmpWord = Ucase(mid(strArr(0),1,1)) & mid(strArr(0),2,len(strArr(0))-1)
End if
strArr(0) = tmpWord

last = ubound(strArr)
if mid(strArr(last),1,1) = "'" or mid(strArr(last),1,1) = """" Then
tmpWord = mid(strArr(last),1,1) & Ucase(mid(strArr(last),2,1)) & mid(strArr(0),3,len(strArr(last))-2)
Else
tmpWord = Ucase(mid(strArr(last),1,1)) & mid(strArr(last),2,len(strArr(last))-1)
End if
strArr(last) = tmpWord

For x = lbound(strArr) To ubound(strArr)
tmpString = tmpString & strArr(x) & " "
Next

PCase = tmpString
End function

Heres the original posted by Alien Mind:
Original Thread (http://forum.doom9.org/showthread.php?t=143169)

dat720
13th January 2009, 02:13
My script has a rather bad bug, don't use it till i resolve the bug.

enderandrew
16th January 2009, 04:57
Thanks for posting it. I look forward to seeing the new version!

dat720
16th January 2009, 14:59
Posted the revised version, basicly all that was wrong was in the mkvmerge section i had it using the same name with no 'changing' title number, which is fine for movies with 1 title, but if you rip a movie with multiple titles the only mkv you end up with at the completion of the script is the last title, now you get titles labeled like so:
VanWilder2-1.mkv
VanWilder2-2.mkv
VanWilder2-3.mkv
And so on for the total number of titles on the disc.... i should set a time limit for titles, if for isntance the title is less than a minute it skips it.