Windows Powershell Script to batch convert movie collection to m4v

DominionZA

Executive Member
Joined
May 5, 2005
Messages
8,306
Reaction score
73
Location
Edenvale, Gauteng
I decided to convert my collection to m4v for native compatibility with XBox and ATV. For this I use Handbrake with a PowerShell script.

The script was only written yesterday and still in it's early stages.
The second post contains the script and the post will be updated as the script is updated. If you make any handy mods to the script please post it here and I will update the first post with it.

If you have an issue running this script it is more than likely permission related.
Run Powershell as Administrator and execute the following: Set-ExecutionPolicy RemoteSigned
Should be fine afterwards.

Requirements: Handbrake
Usage: Set the first 6 variables with you root paths
$TVShowsFolder: This is the root folder for your TV Shows
$MoviesFolder: This is the root folder for your Movies.
$TVShowsBackupFolder: Once a TV Show is converted, the original file will be moved to this folder retaining the folder layout.
$MoviesBackupFolder: Once a Movie is converted, the original file will be moved to this folder retaining the folder layout.
$HandbrakeCLI: This is the app used to do the actual work.
$HandbrakePreset: This is the preset to use. I chose AppleTV 3 as it is the most current. On initial install of Handbrake the script failed as it could not find this preset. I had to open Handbrake and instantly it updated it's preset list. The script worked fine afterwards.

This script will find all *.mkv,*.avi,*.mpeg,*.mpg files in collection and convert them to m4v. The converted file is stored in the same location as the original source file.
Once completed, it will move the original source file to your backup location. Ensure you have sufficient write permissions in your backup location. You can delete files from your backup location once you feel satisfied that Handbrake did it's job correctly.

On my Quad Core 3.2Ghz Xeon server, it converts around 1GB per 15 to 20 minutes depending on the codecs uses in the source file. So depending on the size of your collection, expect it to take some time.

Planned:
1. Automate it to run at specified intervals. Any new content will then be converted and backed up.
2. Enable iTunes support.

Enjoy! And if you have any better ways to do this, feel free to comment. I will update the second post if your changes are worthy :)
 
# If you get execution errors running a Powershell Script, start Powershell as Admin and execute the following "Set-ExecutionPolicy RemoteSigned"

$TVShowsFolder = "E:\Media\TV Shows\"
$MoviesFolder = "E:\Media\Movies\"
$TVShowsBackupFolder = "E:\Backups\Media\TV Shows\"
$MoviesBackupFolder = "E:\Backups\Media\Movies\"

$HandBrakeCLI = "C:\Program Files\Handbrake\HandBrakeCLI.exe"
$HandBrakePreset = "AppleTV 3"

"Starting TV Prox"
"Checking for existing TV Prox"

$Prox = Get-WmiObject Win32_Process -Filter "Name like '%powershell%'" | select-Object CommandLine | where {$_ -match "tvprox"}
$Proxc = $Prox | measure

if ($Proxc.Count -gt 1) {
"We already have a running TV Prox .. exiting"
exit
}

#Get a list of TV Shows and Movies that are not m4v or mp4. Update the extensions list below as necessary to include missed files.
$TVShows = get-childitem $TVShowsFolder -include *.mkv,*.avi,*.mpeg,*.mpg -recurse | foreach ($_) { $_.fullname } | sort
$Movies = get-childitem $MoviesFolder -include *.mkv,*.avi,*.mpeg,*.mpg -recurse | where {$_.length -ge 100MB} | foreach ($_) {$_.fullname} | sort

"Processing TV Shows"
foreach ($SourceFile in $TVShows) {
"Processing: $SourceFile"
$TargetFile = [io.path]::GetDirectoryName($SourceFile) + "\" + [io.path]::GetFileNameWithoutExtension($SourceFile) + ".m4v"
"Create: $targetfile"
& $HandBrakeCLI -i $SourceFile -o $TargetFile --preset=$HandBrakePreset

$BackupFile = $SourceFile.Replace($TVShowsFolder, $TVShowsBackupFolder)
"Backup: $BackupFile"
New-Item -ItemType File -Path $BackupFile -Force
Move-Item $SourceFile $BackupFile -Force
}

foreach ($SourceFile in $Movies) {
"Processing: $SourceFile"
$TargetFile = [io.path]::GetDirectoryName($SourceFile) + "\" + [io.path]::GetFileNameWithoutExtension($SourceFile) + ".m4v"
"Create: $targetfile"
& $HandBrakeCLI -i $SourceFile -o $TargetFile --preset=$HandBrakePreset

$BackupFile = $SourceFile.Replace($MoviesFolder, $MoviesBackupFolder)
"Backup: $BackupFile"
New-Item -ItemType File -Path $BackupFile -Force
Move-Item $SourceFile $BackupFile -Force
}
 
Windows scripting has come a long way, at least you dont have to use batch scripts anymore :p
 
I moved your thread here. Going to get lost in off topic and it's appropriate here methinks.
 
Mike Smit, why don't you just use the Handbrake batch converter? It's a small programme that uses Handbrake to do batch conversions. Used it and it's awesome.
 
Mike Smit, why don't you just use the Handbrake batch converter? It's a small programme that uses Handbrake to do batch conversions. Used it and it's awesome.

If you are referring to this: http://handbrakebatchencode.codeplex.com/
From what I can see:
1. No backup of my files - I only want to delete them once I am happy the conversion was 100%. It also leaves the original in the source location which messes with my servers as they show duplicates on my players.
2. Cannot see a decent way to automate it. A script can be automated within windows so simple.
3. No iTunes integration which I will be adding to the script.

I was going to write an app to do all this - and may still do that (just no time at the mo). The script enabled me to get something functional up and running quickly. It also enables me - or anyone that uses it - to adjust it to suit your own scenario.

I spent a fair amount of time looking at different options for doing this with already available tools. None I found could do it the way I wanted it done though. Scripts give us this flexibility. I am still open to a tool that can do the job though. I don't believe in re-inventing the wheel and would be grateful for a tool that does it the way I want.
 
I'm a total noob and haven't ever used powershell... how do I go about executing this.

I've used drop folder before but it doesn't make backups... unless of course you copy and past the files into your watch folder, it runs off adobe air and also uses handbrake to convert.
 
I'm a total noob and haven't ever used powershell... how do I go about executing this.

I've used drop folder before but it doesn't make backups... unless of course you copy and past the files into your watch folder, it runs off adobe air and also uses handbrake to convert.

You should have it installed already - otherwise you can just download it and use it.
If installed, you can right click the script and select Open With Powershell. Then edit it etc... and run it.
You can also run it from the context menu.

Windows 8 has it by default. Win 7 should - but not 100% sure.
 
If you are referring to this: http://handbrakebatchencode.codeplex.com/
From what I can see:
1. No backup of my files - I only want to delete them once I am happy the conversion was 100%. It also leaves the original in the source location which messes with my servers as they show duplicates on my players.
2. Cannot see a decent way to automate it. A script can be automated within windows so simple.
3. No iTunes integration which I will be adding to the script.

For point number 1, there's an option that says don't delete when done converting, but in your instance, you need more than just a converter, so your choice makes sense :)
 
You should have it installed already - otherwise you can just download it and use it.
If installed, you can right click the script and select Open With Powershell. Then edit it etc... and run it.
You can also run it from the context menu.

Windows 8 has it by default. Win 7 should - but not 100% sure.

So... I dump the script into a text file and name it movie conversion.txt or .exe or something.
 
I decided to convert my collection to m4v for native compatibility with XBox and ATV. For this I use Handbrake with a PowerShell script....
Excellent stuff....

Here as requested some more detail on my workflow:

A few metadata pointers:
You can tap into iTunes metadata by: http://www.apple.com/itunes/affilia...tion/itunes-store-web-service-search-api.html

And For iTunes artwork (itunes square images):
1. To get hires artwork replace the "100x100" url bit with "600x600" found in the "artworkUrl100" json tag.
2. Also for series artwork search for tvSeason as opposed to tvEpisode; (one will find artwork, the other will fail)

Example search: (Smallville, Season 7)
https://itunes.apple.com/search?term=Smallville, Season 7&country=us&entity=tvSeason

100x100 image url:
http://a1.mzstatic.com/us/r1000/055/Video/49/50/90/mzl.ccsokacx.100x100-75.jpg

600x600 image url (100x100 replaced with 600x600)
http://a1.mzstatic.com/us/r1000/055/Video/49/50/90/mzl.ccsokacx.600x600-75.jpg

Fyi Episode specific metadata can be found with a search for "entity=tvEpisode"

"thetvdb" and "themoviedb" have similar search APIs for their metadata / artwork.

I parse these feeds into a metadata class structure (and auto pick the right result) and then use the MP4v2 framework to update / change / read the embedded metadata within media files.

To auto update tags on the resulting handbrake files look for a windows equivalent of either "https://github.com/ccjensen/MP4Tagger" or "http://code.google.com/p/subler/" which both simplify the use of the MP4v2 framework.

You'll of course first have to try to automatically make sense of the current filenames (your coding experience should make this an interesting but quite simple step)

Ps. if you understand objective-c I could if needed throw some similar code your way; basically uses a few regular expressions to extract required lookup variables: Title, Season, Episode, Year, ...
Alternatively just the logic and regular expressions.

Once the metadata is integrated into the media files; I then have a routine that reads the internal metadata and normalizes the filenames, and optionally directories (a good directory structure helps with DLNA access)

For example, I name my episode files as follows:
Series Title - SxxExx - Episode Title
Smallville - S07E06 - Relic.m4v

Fyi I chose this format to ensure the filename would be unique throughout my collection, sorts well, and could be stored in a single or tiered folder arrangement.

I then store this in the following folders:
TVShows --> Smallville --> Season 7 --> "filename"

Good luck with the endeavor; I too found some reduction in size with MKV files, yet some of the converted AVIs reversed this gain; but overall for me, it was less, and quality was maintained.
 
Last edited:
I just ended up using AirVideo in the end.

If you locked yourself into the Apple ecosystem and only watch on mobile devices or push to an ATV, then all good.

I want my collection to be seamless across everything. It pretty much was as a mix of mkv, avi, etc... but I wanted to get all content to the same format and the latest standard. And so m4v it was.
 
Top
Sign up to the MyBroadband newsletter
X