Author Posts

June 26, 2014 at 7:17 am

Let me start by thanking you in advance for your help. I've got a very large folder on my computer where I've stored my DVD collection in MPEG 2 format, each movie has it's own folder with the movie title as the folder name. As my XBOX doesn't like MPEG 2 format I've been using HandBrake to encode them into MPEG 4. As HandBrake has a cue function it would be no big deal to add them all to that and wait, but I can only do this while I'm not using my computer so that amounts to about 5 a night. I'm looking for a script that will read the folder names in a folder (MPEG 2 movies), compare that to the file names in another folder(MPEG 4 movies), create an array of missing items. Then take that array and pass the first 5 items into the HandBrake CLI below, one at a time, waiting till the last one finishes before continuing. ./HandBrakeCLI -i "FROM Array" -o "FROM Array".mp4 –preset="Normal"

Your help is greatly appreciated

June 26, 2014 at 7:41 am

Should be fairly straightforward. Something along these lines:

# Setting up our test environment

$source = '.\TestSource'
$destination = '.\TestDestination'

$null = & {
    New-Item -Path $source -ItemType Directory -ErrorAction SilentlyContinue
    New-Item -Path $destination -ItemType Directory -ErrorAction SilentlyContinue

    # Create 20 source "movies"
    for ($i = 1; $i -le 20; $i++)
    {
        New-Item -Path "$source\Movie$i.mpeg" -ItemType File -ErrorAction SilentlyContinue
    }

    # Create 5 destination "movies"
    for ($i = 1; $i -le 10; $i += 2)
    {
        New-Item -Path "$destination\Movie$i.mp4" -ItemType File -ErrorAction SilentlyContinue
    }
}

# And here's the actual script

$numberOfMoviesToProcess = 5
$numberOfMoviesProcessed = 0
$sourceFiles = @(Get-ChildItem -Path $source\* -Include *.mpeg)

foreach ($movie in $sourceFiles)
{
    $movieDestination = "$destination\$([System.IO.Path]::ChangeExtension($movie.Name, '.mp4'))"

    if (Test-Path $movieDestination) { continue }

    # For testing purposes, just outputting the two file names here.  You'd get rid of this Write-Host
    # line and uncomment the HandBrakeCLI call in the live script.
    Write-Host "Processing source: '$($movie.FullName)', destination: '$movieDestination'"

    #.\HandBrakeCLI -i $movie.FullName -o $movieDestination -preset="Normal"

    $numberOfMoviesProcessed++
    if ($numberOfMoviesProcessed -ge $numberOfMoviesToProcess) { break }
}

June 26, 2014 at 7:59 am

To do an actual comparison of what has already been formatted as MP4, wouldn't you need to something like this?

$old = gci C:\old -File -Recurse -Filter "*.mpg" | Select BaseName, FullName
$new = gci C:\New -File -Recurse -Filter "*.mp4" | Select BaseName, FullName
$array = @()
(Compare-Object $old $new -Property BaseName -PassThru |
Where{$_.SideIndicator -eq "< ="}) | Select FullName -First 5

June 26, 2014 at 8:02 am

In the sample I posted, the call to Test-Path is what skips over already-converted files. You could use a compare-object approach as well.

June 26, 2014 at 8:17 am

I like your solution Dave, but each movie resides in its own folder so I took the liberty to revise you script a little.


$source = '.\TestSource'
$destination = '.\TestDestination'
 
$null = & {
    New-Item -Path $source -ItemType Directory -ErrorAction SilentlyContinue
    New-Item -Path $destination -ItemType Directory -ErrorAction SilentlyContinue
 
    # Create 20 source "movies"
    for ($i = 1; $i -le 20; $i++)
    {
        New-Item -Path "$source\Movie$i" -ItemType Directory -ErrorAction SilentlyContinue
        New-Item -Path "$source\Movie$i\Movie$i.mpeg" -ItemType File -ErrorAction SilentlyContinue
    }
 
    # Create 5 destination "movies"
    for ($i = 1; $i -le 15; $i += 2)
    {
        New-Item -Path "$destination\Movie$i" -ItemType Directory -ErrorAction SilentlyContinue
        New-Item -Path "$destination\Movie$i\Movie$i.mp4" -ItemType File -ErrorAction SilentlyContinue
    }
}

# And here's the actual script
 
$numberOfMoviesToProcess = 5
$numberOfMoviesProcessed = 0
$sourceFiles = @(Get-ChildItem -Path $("$source\*\*") -Filter *.mpeg)
 
foreach ($movie in $sourceFiles)
{
    $movieFoldeName = $movie.Directory.BaseName
    $movieDestination = "$destination\$movieFoldeName\$($movie.BaseName).mp4"
 
    if (Test-Path $movieDestination) { continue }
 
    # For testing purposes, just outputting the two file names here.  You'd get rid of this Write-Host
    # line and uncomment the HandBrakeCLI call in the live script.
    Write-Host "Processing source: '$($movie.FullName)', destination: '$movieDestination'"
 
    #.\HandBrakeCLI -i $movie.FullName -o $movieDestination -preset="Normal"
 
    $numberOfMoviesProcessed++
    if ($numberOfMoviesProcessed -ge $numberOfMoviesToProcess) { break }
}

June 26, 2014 at 8:53 am

Wow thank you all very much! You guys rock!
Just some clarification, the MPEG2 movies are in folders and are not files. The script would need to read the folder names and compare it to mpeg4 file names.
So the MP2 movie folder "movies" has sub folders, movie1, movie2, movie3, and movie4
Folder "Convert" has files, movie1.mp4,movie2.mp4
The script would just need to convert movie 3 and 4

Thank you very much for your continued help

June 26, 2014 at 9:03 am

What parameters get passed to the HandBrakeCLI command for -i and -o? Are they file names, folder names, or some combination of both?

If I understand you correctly so far, here's what the code might look like:

$source = '.\TestSource'
$destination = '.\TestDestination'
 
$null = New-Item -Path $source -ItemType Directory -ErrorAction SilentlyContinue
$null = New-Item -Path $destination -ItemType Directory -ErrorAction SilentlyContinue
 
# Create 20 source "movies"
for ($i = 1; $i -le 20; $i++)
{
    $null = New-Item -Path "$source\Movie$i" -ItemType Directory -ErrorAction SilentlyContinue
    $null = New-Item -Path "$source\Movie$i\Movie$i.mpeg" -ItemType File -ErrorAction SilentlyContinue
}
 
# Create 5 destination "movies"
for ($i = 1; $i -le 15; $i += 2)
{
    $null = New-Item -Path "$destination\Movie$i.mp4" -ItemType File -ErrorAction SilentlyContinue
}
 
# And here's the actual script
 
$numberOfMoviesToProcess = 5
$numberOfMoviesProcessed = 0
$sourceFiles = @(
    Get-ChildItem -Path $source -Directory |
    Where-Object { Test-Path -Path "$($_.FullName)\$($_.Name).mpeg" }
)
 
foreach ($movieFolder in $sourceFiles)
{
    $sourceFile = "$($movieFolder.FullName)\$($movieFolder.Name).mpeg"
    $destinationFile = "$destination\$($movieFolder.Name).mp4"
    if (Test-Path $destinationFile) { continue }
    
    # For testing purposes, just outputting the two file names here.  You'd get rid of this Write-Host
    # line and uncomment the HandBrakeCLI call in the live script.
    Write-Host "Processing source: '$sourceFile', destination: '$destinationFile'"
    
    #.\HandBrakeCLI -i $movieFolder.FullName -o $destinationFile -preset="Normal"
    
    $numberOfMoviesProcessed++
    if ($numberOfMoviesProcessed -ge $numberOfMoviesToProcess) { break }
}

June 26, 2014 at 10:11 am

Thank you very much for your continued help.

The parameters for HandBrake are actually going to be the same for both.
The movie Folder name is going to become the mp4 name as well.
So lets say the movie folder is c:\movies\Movie3
The title for the mp4 would be c:\convert\Movie3.mp4

The c:\movies and c:\convert and mp4 will always be the same, the only thing changing in the HandBrake will be the title

Also as I only need the folder name is the line below needed. There is going to be n such file there.
$null = New-Item -Path "$source\Movie$i\Movie$i.mpeg" -ItemType File -ErrorAction SilentlyContinue

The only thing that needs to be compared is the folder name and the name of the mp4 as they will always be the same

Thank you very much for your help!

July 16, 2014 at 7:13 am

Anthony, enough. This forum is not your personal spam advertisement board. It's one thing to recommend your software in a thread where it might actually help, but just posting about it in random threads is pointless, and I'm going to keep deleting them as spam.