Monthly Archives: June 2023

Quickly getting media info using MediaInfo

Years ago I started ripping all my DVD’s and BluRays to my NAS so I could stream them without having to load the disk into my XBox, which is my only player in the house. Although the process is a pain it is so much more convenient to be able to stream a movie to any TV in the house and on the plus side when taking a trip I can now download the movies to my phone or tablet and bring them with me. The problem is the file size….some movies are massive and halfway through ripping my collection I started to run out of space. So I started looking into Handbrake to compress them into a more manageable size. But first I wanted to get a idea of everything I had, mainly so I could start compressing the largest files first.

I started using MediaInfo which is a great program to get almost every piece of information from a media file. The problem was when scanning a lot of files, especially across a network, it would lock up and crash. I’m assuming because it’s retrieving hundreds of properties from each file it just gets overloaded. But they also make a command line version which lets you poll files for only the info you want which can run a lot quicker.

So after lots of trial and error using the command line version I made a PowerShell script that automates the command line MediaInfo program to get the basics: File name, duration, size, resolution height and width, and what was used to encode it so I could see whether it was already compressed with Handbrake or if it was the original rip from MakeMKV. Copy and paste this into your PowerShell editor, change the initial variables, and run:

# This script uses the MediaInfo CLI ( https://mediaarea.net/en/MediaInfo/Download/Windows ) to 
# quickly catalog media into a CSV file.  Change the initial variables to match your system then run

# Path to the root folder where you have your media
$RootFolder = "X:\Movies"

# Path to the MediaInfo CLI executable
$MediaInfoCLI ="C:\Temp\MediaInfo.exe"

# CSV File to create for your media's info
$CSVExport = "C:\Temp\MovieExport.csv"

# File types to include in the search.  Seperate by a comma like @("*.mkv","*.mp4","*.mpg") etc
$FileTypes = @("*.mkv","*.mp4")

# Add a resolution column to the file.  Once this finishes running a formula will be displayed that you
# can insert into excel to guesstimate the resolution.  Turn off to skip this.
$CreateResolutionColumn = 1

# Display status as the script is running.  0 for None, 1 for basic status, 2 for full status
$DisplayStatus = 1

#Display the exported file once complete.  0 for No, 1 for Yes
$DisplayExport = 1


### Do not change anything under here unless you know what you are doing

# Get our media info.
if (Test-Path -Path $MediaInfoCLI -PathType Leaf) { #Make sure MediaInfo exists
    $timer = [Diagnostics.Stopwatch]::StartNew()
    # The information to pull out of our media.  If you change any of this you will also have to change the 
    # header that is created.  Note the variable for new line since MediaInfo needs different sections on 
    # different lines even though it's exporting everything to a single line.  This info is put into a temp
    # file for MediaInfo to then read.
    $NL = "`r`n"
    $InfoToPull = 'General;"""%FileName%""",%FileSize/String%,%Encoded_Application%,' + $NL + 'Video;%Width%,%Height%,%Duration/String%' + $NL
    $TempFile = New-TemporaryFile
    $InfoToPull | Out-File -Encoding ascii -FilePath $TempFile

    # Create a header for our CSV file.
    If ($CreateResolutionColumn -eq 0) {
        'File Name, Size, Encoder, Width, Height, Duration, Notes' | Out-File -Encoding utf8 -FilePath $CSVExport
    } Else {
        'File Name, Size, Encoder, Width, Height, Duration, Resolution, Notes' | Out-File -Encoding utf8 -FilePath $CSVExport
    }

    If ($DisplayStatus -ge 1) {
        #Display all our variables if option is set
        CLS
        Write-Host "MediaInfo found at $MediaInfoCLI"
        Write-Host "Searching $RootFolder for all files matching these extensions:" $FileTypes.Replace("(", "").Replace(")", "").Replace("*.", "")
        Write-Host "Writting results to $CSVExport"
        Write-Host "Retrieving list of files...."
    }
    $ListOfFiles = Get-ChildItem -Path $RootFolder -Recurse -File -Include $FileTypes
    If ($DisplayStatus -ge 1) {
        $GetFilesTimer = [math]::Round($timer.elapsed.totalseconds,2)
        Write-Host "Found" $ListOfFiles.count "files in" $GetFilesTimer "seconds"
    }
    ForEach ($file in $ListofFiles) {
        If ($DisplayStatus -eq 2) {
            Write-Host "Getting info for $file..."
        }
        If ($DisplayStatus -eq 1) {
            Write-Host -NoNewline "."
        }
        $Args = @("--Output=file://$TempFile",$file)
        & $MediaInfoCLI $Args | Out-File -encoding utf8 -Append -FilePath $CSVExport
    }
    If ($DisplayStatus -ge 1) {
        $FinishedTimer = [math]::Round($timer.elapsed.totalseconds,2)
        Write-Host "`n"
        Write-Host "Finished exporting info.  Took" $FinishedTimer "seconds"
    }
    
    Remove-Item $TempFile  # remove the temp file used by MediaInfo

    if ($CreateResolutionColumn -eq 1) {
        Write-Host "`n"
        Write-Host "For Resolution column:  Copy and paste the following text into Row 2's resolution column then extend it down to the other rows:"
        Write-Host "=IF(D2>3830,""4K"",IF(E2=2160, ""4K"",IF(D2 <=719,IF(D2="""",""Need"",""SD""),IF(D2 <= 1900,IF(E2 > 1070, ""1080"", ""SD""),""1080""))))"
        Write-Host "`n"
        Write-Host "Then make sure to save the file as a standard xls/xlsx/ods to retain formatting."
    }
    If ($DisplayExport -eq 1) {
        Start-Process $CSVExport
    }
} Else {
    Write-Host "MediaInfo could not be found at $MediaInfoCLI.  Please double check it's location."
}

The script is pretty bare bones, not a lot of error checking other then making sure the CLI MediaInfo program is found, but does the job quickly.