Compare Folder Names to File Names, Create Arary, Feed Command, Loop 5 Times

This topic contains 8 replies, has 4 voices, and was last updated by Profile photo of Dave Wyatt Dave Wyatt 2 years, 11 months ago.

  • Author
    Posts
  • #16546
    Profile photo of Sean Kuchle
    Sean Kuchle
    Participant

    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

  • #16547
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    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 }
    }
    
  • #16550
    Profile photo of Rob Simmers
    Rob Simmers
    Participant

    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
  • #16551
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    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.

  • #16552
    Profile photo of Simon Wåhlin
    Simon Wåhlin
    Participant

    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 }
    }
    
  • #16554
    Profile photo of Sean Kuchle
    Sean Kuchle
    Participant

    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

  • #16555
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    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 }
    }
    
  • #16560
    Profile photo of Sean Kuchle
    Sean Kuchle
    Participant

    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!

  • #17187
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    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.

You must be logged in to reply to this topic.