Automated Video Processor for iTunes (AVPI)

Automated Video Processor for iTunes (AVPI)

Videos purchased from iTunes come in standard and or high definition, perfectly formatted for your iDevice, and include features like cover art, movie ratings, description, cast and crew names, subtitles, and more.  While purchasing from iTunes is convenient, it can quickly grow to an unacceptable expense (especially if you already have a video file library).  This script outlines how you can automatically (for the most part) create iTunes like videos from the media (ex. avi, mkv, DVD’s, etc) you already own.

JesseWeb.Com’s Automated Video Processor for iTunes (AVPI)
Version 2.1  09/05/2012

Key Features:

  • Converts existing video sources to iTunes format (m4v)
  • Automatically selects and converts “main movie” for DVD folder or ISO sources
  • Automatically creates an iTunes HD-SD video combo from HD sources – enabling you to stream or sync your desired version from iTunes (ex. sync the SD version to your iPhonee and stream the HD version to your Apple TV)
  • Automatically optimizes videos for HTTP streaming (i.e. optimize for iTunes home sharing)
  • Batch convert videos with same or different encoding types (ex. encode all as SD, encode first as HD and second SD)
  • Automatically includes English audio tracks (if present) - You can customize to your desired audio languages by modifying the script below.
  • Automatically includes English and Portuguese subtitles (if present) – You can customize to your desired subtitle preferences by modifying the script below.
  • Automatically deinterlaces interlaced sources (when selected) – good for 480i files like DVD video or 1080i broadcasted video
  • Add video metadata like album art, movie synopsis, director and cast info, movie rating, etc
Current Limitations/Issues:
  • All sources must be on writeable media (ex your hard drive)
  • Only works on video files, DVD folders, and DVD ISOs (not folders, not files and folders, not DVD discs, not mounted DVD volumes, etc)
  • DVD’s with multiple titles (ex. a TV show DVD) may not have all episodes encoded (as only the “main movie” will be encoded)
  • Requires you to edit/confirm metadata in iDentify (I prefer to validate and fine tune this information before saving so this will likely always be a limitation)
  • Slopping but effective coding with limited error handling
Note: I am sharing the work I have done for my personal use as it may help save others time seeking to do the same.  As I automate more, I will continue to update this post.  This information and code comes with no support.  Use at your own risk.
Prerequisites
Setup
    1. Create a new Automator service
    2. At the top of the service, set ”Service receives Files or Folders in Finder”
    3. Add a “Run AppleScript” step with the following code:
      --Version 2.0
      ----supports DVD folders and DVD ISOs as sources
      ----automatically selects "main movie" for DVD sources
      --Version 2.1 
      ----adds error handling when closing terminal windows
      ----repeated terminal window code moved to subroutines
      
      global scriptTitle
      global sdPresetName
      global hdPresetName
      
      on run {input, parameters}
      	set scriptTitle to "JesseWeb.com: AVPI v2.1"
      	
      	--must be valid handbrake preset names
      	set sdPresetName to "iPhone 4"
      	set hdPresetName to "AppleTV 3"
      	
      	--default to different to be prompted during single file encoding
      	set sameDifferent to "Different"
      	set answer to ""
      	set item_count to (get count of items in input)
      	if item_count > 1 then
      		--use finder dictionary terms to set dialog title
      		using terms from application "Finder"
      			set question to display dialog "Encode all videos the same or different?" with icon note buttons {"Same", "Different"} default button 1 with title scriptTitle
      			set sameDifferent to button returned of question
      		end using terms from
      		
      		if sameDifferent is "Same" then
      			set answer to GetEncodingType()
      		end if
      	end if
      	
      	repeat with anItem in the input -- step through each item in the input
      		set sdFilePath to ""
      		set hdFilePath to ""
      		
      		if sameDifferent is "Different" then
      			set answer to GetEncodingType()
      		end if
      		
      		if answer is "SD-di" then
      			--encode deinterlaced SD version
      			set sdFilePath to my HB_Encode(anItem, "SD-di")
      			
      		else if answer is "HD-di" then
      			--encode deinterlaced SD version
      			set sdFilePath to my HB_Encode(anItem, "SD-di")
      			
      			--encode deinterlaced HD version
      			set hdFilePath to my HB_Encode(anItem, "HD-di")
      			
      			--assign same content ID
      			SetSameContentID(sdFilePath, hdFilePath)
      		else if answer is "SD" then
      			--encode SD version
      			set sdFilePath to my HB_Encode(anItem, "SD")
      		else if answer is "SD/HD" then
      			
      			--encode SD version
      			set sdFilePath to my HB_Encode(anItem, "SD")
      			
      			--encode HD version
      			set hdFilePath to my HB_Encode(anItem, "HD")
      			
      			--assign same content ID
      			SetSameContentID(sdFilePath, hdFilePath)
      		end if
      		
      		--open in identify
      		tell application "iDentify"
      			activate
      			open sdFilePath
      			
      			if hdFilePath is not "" then
      				open hdFilePath
      			end if
      		end tell
      	end repeat
      	
      	--use finder dictionary terms to set dialog title
      	using terms from application "Finder"
      		display dialog "Processing Complete" with icon note buttons {"OK"} default button 1 with title scriptTitle
      	end using terms from
      end run
      
      on GetEncodingType()
      	set selectedAnswer to choose from list {"SD Interlaced (i.e. DVD, 480i)", "SD Progressive (i.e. 480p)", "HD Interlaced (i.e. 1080i)", "HD Progressive (i.e. 720p, 1080p)"} with title scriptTitle with prompt ¬
      		"Source type:" default items "SD Interlaced (i.e. DVD, 480i)" OK button name ¬
      		"OK" cancel button name "Cancel" without multiple selections allowed
      	
      	if selectedAnswer is false then
      		quit
      	else
      		if (item 1 of selectedAnswer) as string is "SD Interlaced (i.e. DVD, 480i)" then
      			set answer to "SD-di"
      		else if (item 1 of selectedAnswer) as string is "SD Progressive (i.e. 480p)" then
      			set answer to "SD"
      		else if (item 1 of selectedAnswer) as string is "HD Interlaced (i.e. 1080i)" then
      			set answer to "HD-di"
      		else if (item 1 of selectedAnswer) as string is "HD Progressive (i.e. 720p, 1080p)" then
      			set answer to "SD/HD"
      		end if
      	end if
      	
      	return answer
      end GetEncodingType
      
      --Closes existing terminal windows
      on CloseTerminalWindows()
      	try
      		tell application "Terminal"
      			quit
      		end tell
      	end try
      	WaitForTerminalWindowClose()
      end CloseTerminalWindows
      
      --Wait for terminal windows to close
      on WaitForTerminalWindowClose()
      	try
      		set windowsClosed to 0
      		repeat until windowsClosed = 1
      			tell application "Terminal"
      				if (count of windows) is 0 then
      					set windowsClosed to 1
      				end if
      			end tell
      			delay 1
      		end repeat
      	on error
      		delay 1 --give time for terminal window to close		
      	end try
      end WaitForTerminalWindowClose
      
      on HB_Encode(anItem, definition)
      	set newFilePath to ""
      	set terminalCommand to ""
      	set presetName to ""
      	
      	--translate the file path from AppleScript colon delimited to Posix / delimited
      	set filePath to POSIX path of anItem
      	tell (info for anItem) to set {theName, theExt} to {name, name extension}
      	set shortName to text 1 thru ((get offset of "." & theExt in theName) - 1) of theName
      	
      	--do not include file extension in the new file name
      	if (characters -4 thru -4 of filePath) as string is "." then
      		set newFilePath to ((characters 1 thru -5 of filePath) as string) --trim last 4
      	else
      		set newFilePath to filePath & shortName
      	end if
      	
      	ignoring case
      		if definition is equal to "HD" then
      			set newFilePath to newFilePath & ".HD.m4v"
      			set presetName to "--preset=\"" & hdPresetName & "\""
      		else if definition is equal to "HD-di" then
      			set newFilePath to newFilePath & ".HD.m4v"
      			set presetName to "--preset=\"" & hdPresetName & "\" --decomb --detelecine"
      		else if definition is equal to "SD-di" then
      			set newFilePath to newFilePath & ".SD.m4v"
      			set presetName to "--preset=\"" & sdPresetName & "\" --decomb --detelecine"
      		else if definition is equal to "SD" then
      			set newFilePath to newFilePath & ".SD.m4v"
      			set presetName to "--preset=\"" & sdPresetName & "\""
      		end if
      	end ignoring
      	
      	--encode video, optimized for http streaming, english as native audio
      	--english and portuguese subtitles, to specified preset, select main DVD movie (if applicable)
      	set terminalCommand to "/Applications/HandBrakeCLI -i \"" & filePath & "\" -o \"" & newFilePath & "\" --main-feature --optimize --native-language eng --native-dub --srt-lang eng,por " & presetName & ";exit"
      	
      	CloseTerminalWindows()
      	
      	tell application "Terminal"
      		do script with command terminalCommand in window 1
      		tell window 1
      			set custom title to definition & " Encoding (" & shortName & ")"
      			set title displays custom title to true
      			set title displays shell path to false
      		end tell
      		activate
      	end tell
      	
      	--Wait for script to finish
      	WaitForTerminalWindowClose()
      	
      	return newFilePath
      end HB_Encode
      
      on SetSameContentID(sdFilePath, hdFilePath)
      	set mp4tagsPath to "\"/Applications/Batch Rip Actions for Automator.app/Contents/MacOS/mp4tags\""
      	
      	CloseTerminalWindows()
      	
      	tell application "Terminal"
      		do script with command "nextcnID=$(echo $(( 10000+($RANDOM)%(20000-10000+1) ))$(( 1000+($RANDOM)%(9999-1000+1) )));" in window 1
      		tell window 1
      			set custom title to "Assigning content IDs"
      			set title displays custom title to true
      			set title displays shell path to false
      		end tell
      		do script with command mp4tagsPath & " -I $nextcnID \"" & sdFilePath & "\"" in window 1
      		do script with command mp4tagsPath & " -I $nextcnID \"" & hdFilePath & "\"" in window 1
      		do script with command "exit" in window 1
      		activate
      	end tell
      	
      	--Wait for script to finish
      	WaitForTerminalWindowClose()
      end SetSameContentID
      
    4. Save the service

Usage

  1. Simply right click on any video file or DVD folder, choose “Services”, and select the name of the service you created
  2. Select your video source type

    Note:
    - An SD source will produce 1 SD video formatted for the iPhone 4
    - An HD source will produce 1 SD video formatted for the iPhone 4 and 1 HD video formatted for the Apple TV 3 (and display as 1 HD-SD video in iTunes)
  3. Wait for the encoding to finish and the files to be loaded in iDentify
  4. The script will indicate that it has finished, leaving you to use iDentify and edit/save the correct metadata in your new videos
  5. Simply import the new videos into iTunes and you’re done!