Skip to content

Instantly share code, notes, and snippets.

@bradwilson
Last active January 27, 2024 08:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bradwilson/d137640a8f21b6d833958b396f62cb16 to your computer and use it in GitHub Desktop.
Save bradwilson/d137640a8f21b6d833958b396f62cb16 to your computer and use it in GitHub Desktop.
get-mkvinfo.ps1 (automating mkvmerge)
param(
[Parameter(ValueFromPipeline)]$values,
[switch]$All
)
# It's worth noting that this script is useful for me, because I speak English. So I show all audio
# tracks and just the English subtitle tracks, and just make note when one of my rips includes non-
# English subtitle tracks (usually indicting I forgot to reduce the things I ripped).
#
# This is a pipeline-compatible script, so my usage is typically:
#
# dir *.mkv | get-mkvinfo
#
# Output looks like this:
#
# A Charlie Brown Christmas.mkv [00:25:28]
# TITLE :: 'A Charlie Brown Christmas'
# VIDEO (0) v1 :: 1920x1080 (VC-1)
# AUDIO (1) a1 :: eng (6 channels, AC-3, 'Surround 5.1')
# SUBS (2) s1 :: eng (HDMV PGS)
#
# The labels ("VIDEO (0) v1") indicate the type ("VIDEO"), the mkvmerge ID ("0"), and the mkvpropedit track ID ("v1").
# Video tracks show the resolution and codec. Audio tracks show the language, channel count, the codec, and the "name"
# property (when set). Subtitle tracks show the language, optional flags (like "default" and "forced"), and the codec.
#
# The "-All" switch will show all subtitles rather than just English.
process {
$previousEncoding = [Console]::OutputEncoding
[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new()
try {
if (($_ -eq $null) -or ($null -eq $_.FullName)) {
if ($_ -ne $null) {
Write-Error "Unknown type: $_"
}
} else {
$json = & mkvmerge -F json --identify "$($_.FullName)" | ConvertFrom-Json
# Determine the total # of tracks so we can print appropriately
$videoTotal = ($json.tracks | Where-Object { $_.type -eq "video" }).Count
$audioTotal = ($json.tracks | Where-Object { $_.type -eq "audio" }).Count
$subTotal = ($json.tracks | Where-Object { $_.type -eq "subtitles" }).Count
$largestTotal = [Math]::Max([Math]::Max($videoTotal, $audioTotal), $subTotal)
$totalPadding = $largestTotal.ToString().Length
# Write title and duration
Write-Host -NoNewline -ForegroundColor Green $_.Name
$duration = $json.container.properties.duration
if ($null -ne $duration) {
Write-Host -NoNewline -ForegroundColor Blue " [$(([System.TimeSpan]::FromSeconds($duration / 1000000000)).ToString('hh\:mm\:ss'))]"
}
Write-Host ""
$fileTitle = $json.container.properties.title
if ($null -ne $fileTitle) {
Write-Host " TITLE $(" ".PadLeft($totalPadding)) :: '$($fileTitle)'"
}
# Write the video tracks
$videoCurrent = 0
$json.tracks | Where-Object { $_.type -eq "video" } | Foreach-Object {
$videoCurrent = $videoCurrent + 1
$codec = $_.codec
if ($codec -eq $null) {
$codec = $_.properties.codec_id
}
Write-Host " VIDEO ($($_.id.ToString().PadLeft($totalPadding))) v$($videoCurrent.ToString().PadRight($totalPadding)) :: $($_.properties.pixel_dimensions) ($($codec))"
}
$audioCurrent = 0
$json.tracks | Where-Object { $_.type -eq "audio" } | Foreach-Object {
$audioCurrent = $audioCurrent + 1
$default = ""
if ($_.properties.default_track) {
$default = " default"
}
$codec = $_.codec
if ($codec -eq $null) {
$codec = $_.properties.codec_id
}
$name = ""
if ($_.properties.track_name -ne $null) {
$name = ", '$($_.properties.track_name)'"
}
Write-Host " AUDIO ($($_.id.ToString().PadLeft($totalPadding))) a$($audioCurrent.ToString().PadRight($totalPadding)) :: $($_.properties.language)$($default) ($($_.properties.audio_channels) channels, $($codec)$($name))"
}
$subCurrent = 0
$nonEnglishSubCount = 0
$json.tracks | Where-Object { ($_.type -eq "subtitles") } | Foreach-Object {
$subCurrent = $subCurrent + 1
if ($All -or ($_.properties.language -eq 'eng')) {
$default = ""
if ($_.properties.default_track) {
$default = " default"
}
$forced = ""
if ($_.properties.forced_track) {
$forced = " forced"
}
$codec = $_.codec
if ($codec -eq $null) {
$codec = $_.properties.codec_id
}
$name = ""
if ($_.properties.track_name -ne $null) {
$name = ", '$($_.properties.track_name)'"
}
Write-Host " SUBS ($($_.id.ToString().PadLeft($totalPadding))) s$($subCurrent.ToString().PadRight($totalPadding)) :: $($_.properties.language)$($default)$($forced) ($($codec)$($name))"
} else {
$nonEnglishSubCount = $nonEnglishSubCount + 1
}
}
if ($nonEnglishSubCount -ne 0) {
Write-Host -ForegroundColor Yellow " *** Contains non-English subtitles ***"
}
}
}
finally {
[Console]::OutputEncoding = $previousEncoding
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment