Created
January 4, 2017 23:54
-
-
Save tillig/60138a69606729705deeb4505ee9a39d to your computer and use it in GitHub Desktop.
Automate running hymn against an iTunes library for removing DRM.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
' M4P Backup | |
' by Travis Illig | |
' http://www.paraesthesia.com | |
' | |
' This script backs up your protected iTunes music (*.m4p) along with a | |
' decrypted version (*.m4a). The decryption is done using the "hymn" | |
' program, available at http://hymn-project.org/. | |
' | |
' Note that for "hymn" to properly decrypt your iTunes files, you may | |
' need to use the "FairKeys" program, available at | |
' http://www.nanocrew.net/software/. | |
' | |
' The script finds all *.m4p files in your Music Library. It copies those | |
' files, in a similar directory tree as your Music Library, into the backup | |
' folder specified. It then looks to see if there is a corresponding *.m4a | |
' file available. If there is, it copies that file into the backup folder. | |
' If there isn't, it runs "hymn" to decrypt the *.m4p file into the *.m4a | |
' file, then copies that decrypted file to the backup folder. | |
' | |
' In the below section marked "CONFIGURATION," set up the required file and | |
' folder paths as specified. | |
Option Explicit | |
'============================================================================== | |
'============================================================================== | |
' CONFIGURATION | |
' Set the following variables as noted. | |
Dim MUSICLIBRARYPATH, HYMNPATH, BACKUPFOLDERPATH | |
' Full path to "Music Library" folder, including trailing slash. | |
MUSICLIBRARYPATH = "F:\Music Library\" | |
' Full path to "hymn.exe" program. | |
HYMNPATH = "C:\Program Files\hymn-0.7.1\hymn.exe" | |
' Full path to backup folder, including trailing slash. | |
BACKUPFOLDERPATH = "F:\backup\Protected Music\" | |
'============================================================================== | |
'============================================================================== | |
'============================================================================== | |
' PROGRAM | |
' DO NOT CHANGE ANYTHING BELOW! | |
' Set up common objects and check for file paths | |
On Error Resume Next | |
Dim VERSION | |
VERSION = "1.0" | |
Dim fso, wshell, MusicLibraryFolder, BackupFolder | |
Set fso = CreateObject("Scripting.FileSystemObject") | |
If (Err.Number <> 0) Then | |
WScript.Echo "Unable to create FileSystemObject. Exiting." | |
WScript.Quit(1) | |
End If | |
Err.Clear | |
Set wshell = CreateObject("WScript.Shell") | |
If (Err.Number <> 0) Then | |
WScript.Echo "Unable to create WScript.Shell. Exiting." | |
WScript.Quit(1) | |
End If | |
Err.Clear | |
Set MusicLibraryFolder = fso.GetFolder(MUSICLIBRARYPATH) | |
If (Err.Number <> 0) Then | |
WScript.Echo "Unable to locate Music Library folder at [" & MUSICLIBRARYPATH & "]. Exiting." | |
WScript.Quit(1) | |
End If | |
Err.Clear | |
Set BackupFolder = fso.GetFolder(BACKUPFOLDERPATH) | |
If (Err.Number <> 0) Then | |
WScript.Echo "Unable to locate backup folder at [" & BACKUPFOLDERPATH & "]. Exiting." | |
WScript.Quit(1) | |
End If | |
Err.Clear | |
If (Not fso.FileExists(HYMNPATH)) Then | |
WScript.Echo "Unable to locate hymn.exe at [" & HYMNPATH & "]. Exiting." | |
WScript.Quit(1) | |
End If | |
WScript.Echo WScript.ScriptName & " " & VERSION | |
WScript.Echo "Music Library: " & MUSICLIBRARYPATH | |
WScript.Echo "Backup Folder: " & BACKUPFOLDERPATH | |
WScript.Echo "hymn.exe: " & HYMNPATH | |
WScript.Echo "Starting Backup..." | |
DoRecursiveBackup MusicLibraryFolder | |
WScript.Echo "Backup COMPLETE." | |
Sub DoRecursiveBackup(FolderObj) | |
' For all of the m4p files in the current folder... | |
Dim file | |
For Each file In FolderObj.Files | |
If (LCase(Right(file.Name, 4)) = ".m4p") Then | |
WScript.Echo "Found: " & file.Path | |
' Calculate the complete backup folder path | |
Dim newPath | |
newPath = Right(file.Path, Len(file.Path) - Len(MusicLibraryFolder.Path)) | |
newPath = Left(newPath, Len(newPath) - Len(file.Name)) | |
newPath = BackupFolder.Path & newPath | |
' Xcopy the m4p to the backup folder | |
WScript.Echo "Copying to: " & newPath | |
ExecuteXCopy file.Path, newPath | |
' Get the corresponding m4a | |
Dim m4aPath | |
m4aPath = Left(file.Path, Len(file.Path) - 4) & ".m4a" | |
' If it doesn't exist, run "hymn" to create it | |
If (Not fso.FileExists(m4aPath)) Then | |
ExecuteHymn file.Path | |
End If | |
' If it still doesn't exist, "hymn" didn't make it; write error message and continue | |
If (Not fso.FileExists(m4aPath)) Then | |
WScript.Echo "Decryption failed. Unable to back up decrypted version of [" & file.Path & "]. Continuing backup process..." | |
Else | |
'The M4A version exists; copy it. | |
ExecuteXCopy m4aPath, newPath | |
End If | |
End If | |
Next | |
' For all of the folders in the current folder, recurse | |
Dim folder | |
For Each folder In FolderObj.SubFolders | |
DoRecursiveBackup folder | |
Next | |
End Sub | |
Sub ExecuteHymn(M4PPath) | |
' If the M4PPath doesn't exist, exit the sub | |
If (Not fso.FileExists(M4PPath)) Then | |
WScript.Echo "Unable to locate file [" & M4PPath & "] for hymn.exe processing." | |
Exit Sub | |
End If | |
' Run hymn.exe to convert the M4P to M4A | |
WScript.Echo "Executing 'hymn.exe' to decrypt [" & M4PPath & "]" | |
ExecuteProgram("""" & HYMNPATH & """ """ & M4PPath & """") | |
End Sub | |
Sub ExecuteXCopy(filepath, destfolderpath) | |
ExecuteProgram("xcopy /y """ & filepath & """ """ & destfolderpath & """") | |
End Sub | |
Sub ExecuteProgram(CommandLine) | |
Dim commandexec, output | |
Set commandexec = wshell.Exec(CommandLine) | |
Do While commandexec.Status = 0 | |
WScript.Sleep(50) | |
Loop | |
output = commandexec.StdOut.ReadAll & vbCrLf & commandexec.StdErr.ReadAll | |
WScript.Echo output | |
End Sub |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment