Tuesday, October 20, 2009

Windows 7 Media Center WTV to iPhone / iPod Video Transcode

Below is my first pass at building a Powershell utility to monitor my Recorded TV folder from Windows 7 Media Center and automatically trim commercials and transcode them into iPhone format.

Some notes:

  • The version of ffmpeg.exe comes from iPodifier. I want it to use a more recent stock build.
  • Requires comskip and and drvcut. Built with Comskip 80_25.
  • Next version will also output Podcast XML, which will greatly clean up the experience on the iPhone.
  • Keep an eye on the transcode tag here for future updates.

$sourceFilesUnfiltered = "C:\Users\Public\Recorded TV\*.wtv"; $binDir = "C:\Users\Media\Downloads\comskip80_025"; $outputDir = "C:\iPodVideos2"; $keepWindowDays = 14; $sleepInterval = 600; while(1) { # Filter the input files $sourceFiles = Get-ChildItem $sourceFilesUnfiltered | Where-Object { $_.CreationTime -gt (Get-Date).AddDays(0 - $keepWindowDays) } | Sort-Object CreationTime; Write-Output ("Setting process priority to Idle."); [System.Diagnostics.Process]::GetCurrentProcess().PriorityClass = [System.Diagnostics.ProcessPriorityClass]::Idle; # Convert WTV to DVR-MS, Analyze afor commercials, trim commercials, and transcode to iPhone format. foreach($file in $sourceFiles) { #echo "Beginning $file"; # We don't want to process a currently recording show, so check last write time $file.Refresh(); #if(((Get-Date) - ($file.LastWriteTime)).TotalSeconds -lt 120) #{ # Write-Output ("Skipping $file because it is in use."); # continue; #} try { $handle = $file.OpenWrite(); } catch { Write-Output ("Skipping $file because it is in use."); continue; } finally { #TODO if handle isn't null $handle.Close(); } $baseName = $file.BaseName; $dvrmsFile = "$outputDir\$baseName.dvr-ms"; $cleanName = "$outputDir\$baseName" + "_clean.dvr-ms"; $m4vName = "$outputDir\$baseName" + ".m4v"; $trimFile = "$outputDir\$baseName" + "_dvrcut.bat"; #if ipod version does not exist if(!(Test-Path $m4vName)) { Write-Output "Beginning $file"; Write-Output ("Converting to DVR-MS."); & "C:\Windows\ehome\WTVConverter.exe" $file $dvrmsFile | Wait-Process; Write-Output ("Running ComSkip."); & "$binDir\comskip.exe" -q --ini="$binDir\comskip.ini" $dvrmsFile $outputDir | Wait-Process; Write-Output ("Trimming Commercials."); & Start-Process -Wait $trimFile;# | Wait-Process; Write-Output ("Compressing video."); & "$binDir\ffmpeg.exe" -y -i $cleanName -f mp4 -s 480x320 -acodec libfaac -async 4800 -dts_delta_threshold 1 -threads auto -vcodec libx264 -b 512k -level 21 -r 30000/1001 -bufsize 2000k -maxrate 768k -g 250 -coder 0 $m4vName | Wait-Process; del "$outputDir\$baseName.log", "$outputDir\$baseName.logo.txt", "$outputDir\$baseName.txt", $trimFile, $dvrmsFile, $cleanName; } else { Write-Output "Nothing to do for $file"; } #break; } # Delete extra (outside of the keep window) files foreach($m4vfile in Get-ChildItem "$outputDir\*.m4v") { $matchFound = [bool]0; foreach($wtvFile in $sourceFiles) { if($wtvFile.BaseName -eq $m4vFile.BaseName) { $matchFound = [bool]1; } } if(!$matchFound) { Write-Output ("Extra file found: $m4vFile"); } } Start-Sleep $sleepInterval; }