Extracting Subtitles from MKV Files

I’m not certain whether it’s linked to being an expat living in the Netherlands trying to understand what’s being said on their television channels, or just that my hearing isn’t is what it used to be, but it’s quite rare for me to watch anything without subtitles, whatever the language…. Often though, it’s the case that my TV is not able to use the subtitles embedded within an MKV file. Instead, I need to extract the subtitles data stream to a separate SRT file, and ensure the filename matches the MKV one, apart from the suffic.

This post follows on from one of a couple of weeks ago about getting MKV file information, and goes into how we can also extract the subtitles for one of these files.

The script is posted below. As you’ll probably already have noticed, it’s quite similar to the cmdlet from the earlier post. We’re accepting ‘FullName’ as an alias of the Path, and we’re constructing the command to be executed dynamically by combining the command parameters with the values that have been passed in. Also, the filename of the SRT file is matched to the original MKV file so we don’t need to change it after.

function Get-MKVSubtitles            
        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)][Alias('FullName')] [string] $Path,            
        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)] [string] $Track                   
        $Destination = ($Path.Substring(0,$Path.Length - 4)) + '.srt'            
        $command = "D:portablemkvtoolnixmkvextract.exe tracks -q `"$Path`" $Track`:`"$Destination`""            
        Write-Verbose -Message "Path        : $Path"            
        Write-Verbose -Message "Track       : $Track"            
        Write-Verbose -Message "Destination : $Destination"            
        Write-Verbose -Message "Command     : $command"            
        Invoke-Expression -Command $command                     

If we have one file, we can use the cmdlet like this:

Get-MKVSubtitles -Path C:DataVideosMyMovie.mkv -Track 0

PowerShell’s pipeline functionality comes into great effect if we have multiple MKV files with subtitles in a directory.  We could use a combination of Get-ChildItem, and Get-MKVTrackInfo with Get-MKVSubtitles :

Get-ChildItem -Filter *.mkv | Get-MKVTrackInfo | Where-Object -Property TrackType -EQ -Value 'Subtitles' | Get-MKVSubtitles

If your MKV files were spread over a series of sub-directories, you could even add the -recurse parameter to Get-ChildItem, since FullName is passed through the pipeline to Get-MKVInfo.


Leave a Reply

Your email address will not be published. Required fields are marked *