Sunday, June 5, 2016

Viewing MP4 Video Tags via Powershell

In my earlier post, I described my technique to easily tag TV Show MP4 files via a PowerShell script. But how do you validate that it worked? Most of this tagged information can't be seen when viewing the detailed file properties in Windows Explorer. (I think Year and Genre are all you can see).
So, I wanted a quick way to view the information was successfully set before importing to iTunes. Here's what I came up with.
There are 2 scripts, actually. One displays a table of information (but not description or long description) and the other displays a long list of all data for each file.
First, please note this leverages Taglib-Sharp. It's free, so don't worry. Simply follow the link to download "tarballs" and get the windows zip. Extract taglib-sharp.dll from the Libraries directory and place somewhere on your machine. Point the import statement in my code to that dll.
Each script when executed will prompt for the directory location of your MP4 files.

#modify the path below to point to the taglib-sharp dll file
Import-Module "D:\powershell\modules\MPTag\taglib-sharp.dll"

#code written by Crazy-S Farm guy
#http://powershelltidbits.blogspot.com
#use at your own risk

$BOXTYPE_TVEN = "tven"; # episode name
$BOXTYPE_TVES = "tves"; # episode number
$BOXTYPE_TVSH = "tvsh"; # TV Show or series
$BOXTYPE_PURD = "purd"; # purchase date
$BOXTYPE_DESC = "desc"; # short description
$BOXTYPE_TVSN = "tvsn"; # season
#now, we have to set up to set the broadcast (air) date
$c = [char]169

#you would think you could do this... but it doesn't work...
#$BOXTYPE_AIRDATE_STRING = $c + "day"; # broadcast date
#this is a little bit of "magic" since for some reason, it wants to stick "194" character in front of it.
# there may be a better way to do this, but I can't figure it out.
$BOXTYPE_BROADCASTDATE = [TagLib.ByteVector]::New()
$BOXTYPE_BROADCASTDATE.add([TagLib.ByteVector]::FromUShort(169)[1])
$BOXTYPE_BROADCASTDATE.add([TagLib.ByteVector]::FromString("d"))
$BOXTYPE_BROADCASTDATE.add([TagLib.ByteVector]::FromString("a"))
$BOXTYPE_BROADCASTDATE.add([TagLib.ByteVector]::FromString("y"))

$BOXTYPE_EPISODE_TITLE = [TagLib.ByteVector]::New()
$BOXTYPE_EPISODE_TITLE.add([TagLib.ByteVector]::FromUShort(169)[1])
$BOXTYPE_EPISODE_TITLE.add([TagLib.ByteVector]::FromString("n"))
$BOXTYPE_EPISODE_TITLE.add([TagLib.ByteVector]::FromString("a"))
$BOXTYPE_EPISODE_TITLE.add([TagLib.ByteVector]::FromString("m"))


$mediaDirectory = Read-Host -Prompt "Enter directory to scan"


$fileList = Get-ChildItem -Path $mediaDirectory -Filter "*.mp4"

$output = @()

foreach ($file in $fileList)
{
    $mediafile = [TagLib.File]::Create($file.FullName)
    [TagLib.Mpeg4.AppleTag]$customTag = $mediaFile.GetTag([TagLib.TagTypes]::Apple, 1)
    $rowData = New-Object -TypeName PSObject

    Add-Member -InputObject $rowData -MemberType NoteProperty -Name "File" -Value ($file.Name)

    Add-Member -InputObject $rowData -MemberType NoteProperty -Name "TV Show" -Value ($customTag.DataBoxes($BOXTYPE_TVSH).Text)
    Add-Member -InputObject $rowData -MemberType NoteProperty -Name "Title" -Value ($customTag.DataBoxes($BOXTYPE_EPISODE_TITLE).Text)
    #the tven is used for sorting purposes
    Add-Member -InputObject $rowData -MemberType NoteProperty -Name "Sort" -Value ($customTag.DataBoxes($BOXTYPE_TVEN).Text)

    $number = ""
    $array = $customTag.DataBoxes($BOXTYPE_TVSN)
    if (($array -ne $null) -and ($array.Data.count -ge 3))
    {
        $number = $array.Data[3].toString()
    }
    Add-Member -InputObject $rowData -MemberType NoteProperty -Name "Season" -Value $number

    $number = ""
    $array = $customTag.DataBoxes($BOXTYPE_TVES)
    if (($array -ne $null) -and ($array.Data.count -ge 3))
    {
        $number = $array.Data[3].toString()
    }
    Add-Member -InputObject $rowData -MemberType NoteProperty -Name "#" -Value $number

    $airDate = $customTag.DataBoxes($BOXTYPE_BROADCASTDATE).Text
    if (($airDate -ne $null) -and ($airDate.length -gt 10))
    {
        $airDate = $airDate.substring(0,10)
    }
    Add-Member -InputObject $rowData -MemberType NoteProperty -Name "Air Date" -Value ($airDate)
    Add-Member -InputObject $rowData -MemberType NoteProperty -Name "Short Description" -Value ($customTag.DataBoxes($BOXTYPE_DESC).Text)

    $output += $rowData
}

$output | Format-Table -AutoSize

Here's a sample of the output:
sample table output


#modify the path below to point to the taglib-sharp dll file
Import-Module "D:\powershell\modules\MPTag\taglib-sharp.dll"

#code written by Crazy-S Farm guy
#http://powershelltidbits.blogspot.com
#use at your own risk

$BOXTYPE_LDES = "ldes"; # long description
$BOXTYPE_TVEN = "tven"; # episode name
$BOXTYPE_TVES = "tves"; # episode number
$BOXTYPE_TVSH = "tvsh"; # TV Show or series
$BOXTYPE_PURD = "purd"; # purchase date
$BOXTYPE_DESC = "desc"; # short description
$BOXTYPE_TVSN = "tvsn"; # season
#now, we have to set up to set the broadcast (air) date
$c = [char]169

#you would think you could do this... but it doesn't work...
#$BOXTYPE_AIRDATE_STRING = $c + "day"; # broadcast date
#this is a little bit of "magic" since for some reason, it wants to stick "194" character in front of it.
# there may be a better way to do this, but I can't figure it out.
$BOXTYPE_BROADCASTDATE = [TagLib.ByteVector]::New()
$BOXTYPE_BROADCASTDATE.add([TagLib.ByteVector]::FromUShort(169)[1])
$BOXTYPE_BROADCASTDATE.add([TagLib.ByteVector]::FromString("d"))
$BOXTYPE_BROADCASTDATE.add([TagLib.ByteVector]::FromString("a"))
$BOXTYPE_BROADCASTDATE.add([TagLib.ByteVector]::FromString("y"))

$BOXTYPE_EPISODE_TITLE = [TagLib.ByteVector]::New()
$BOXTYPE_EPISODE_TITLE.add([TagLib.ByteVector]::FromUShort(169)[1])
$BOXTYPE_EPISODE_TITLE.add([TagLib.ByteVector]::FromString("n"))
$BOXTYPE_EPISODE_TITLE.add([TagLib.ByteVector]::FromString("a"))
$BOXTYPE_EPISODE_TITLE.add([TagLib.ByteVector]::FromString("m"))


$mediaDirectory = Read-Host -Prompt "Enter directory to scan"


$fileList = Get-ChildItem -Path $mediaDirectory -Filter "*.mp4"

$output = @()

foreach ($file in $fileList)
{
        
    $mediafile = [TagLib.File]::Create($file.FullName)
    [TagLib.Mpeg4.AppleTag]$customTag = $mediaFile.GetTag([TagLib.TagTypes]::Apple, 1)

    Write-Output ("File: " + $file.Name)
    Write-Output ("TV Show: " + $customTag.DataBoxes($BOXTYPE_TVSH).Text)
    Write-Output ("Episode Title: " + $customTag.DataBoxes($BOXTYPE_EPISODE_TITLE).Text)
    Write-Output ("Sort Title: " + $customTag.DataBoxes($BOXTYPE_TVEN).Text)

    $number = ""
    $array = $customTag.DataBoxes($BOXTYPE_TVSN)
    if (($array -ne $null) -and ($array.Data.count -ge 3))
    {
        $number = $array.Data[3].toString()
    }
    Write-Output ("Season: " + $number)

    #Write-Output ("Season: " + (($customTag.DataBoxes($BOXTYPE_TVSN)).Data)[3].ToString())

    $number = ""
    $array = $customTag.DataBoxes($BOXTYPE_TVES)
    if (($array -ne $null) -and ($array.Data.count -ge 3))
    {
        $number = $array.Data[3].toString()
    }

    Write-Output ("Episode Number: " + $number)
    #Write-Output ("Episode Number: " + (($customTag.DataBoxes($BOXTYPE_TVES)).Data)[3].ToString())

    $airDate = $customTag.DataBoxes($BOXTYPE_BROADCASTDATE).Text
    if (($airDate -ne $null) -and ($airDate.length -gt 10))
    {
        $airDate = $airDate.substring(0,10)
    }

    Write-Output ("Air Date: " + $airDate)
    Write-Output ("Short Description: " + $customTag.DataBoxes($BOXTYPE_DESC).Text)
    Write-Output ("Long Description: " + $customTag.DataBoxes($BOXTYPE_LDES).Text)
    Write-Output "--------------------------------------------------"

}



Here's a sample output:
sample details output

No comments:

Post a Comment