Skip to content

Interacting with MKVToolNix

Garen Sahagian edited this page May 28, 2021 · 4 revisions

MKVToolNix comes with a GUI as part of the official install package. Individual file operations can be completed through this GUI. However, we are interested in providing batch processing of files, and in the words of the developer:

Sorry, but such a feature will never be implemented in MKVToolNix GUI itself.

The documentation instead provides helpful examples of scripting shell commands in Ruby. The below example demonstrates how a simple library can be created for interacting with the CLI interface, and thus can be used as a basis for our batch processes.

#!/usr/bin/env ruby

# version 2019-01-24-01

require "json"
require "tempfile"

def identify_file file_name
  Tempfile.create(["mkvmerge-arguments", ".json"], nil, :encoding => "utf-8") do |file|
    file.puts JSON.dump([ "--identification-format", "json", "--identify", file_name ])
    file.close

    return JSON.load(`mkvmerge @#{file.path}`)
  end
end

def multiplex_file arguments
  Tempfile.create(["mkvmerge-arguments", ".json"], nil, :encoding => "utf-8") do |file|
    file.puts JSON.dump(arguments)
    file.close

    system "mkvmerge @#{file.path}"
  end
end

def edit_file_properties arguments
  Tempfile.create(["mkvpropedit-arguments", ".json"], nil, :encoding => "utf-8") do |file|
    file.puts JSON.dump(arguments)
    file.close

    system "mkvpropedit @#{file.path}"
  end
end

Under the hood, MKVToolNix is written primarily in C++, with some Ruby. Benchmarking could be interesting, but it seems safe to say that a single instance should be reasonably performant. And if not, somebody's going to have to learn some C++. Choice of backend language (see issue #4) will likely determine any further performance bottlenecks.

Regardless of the backend language chosen, the most obvious action loop would appear to be:

  1. run mkvextract to pull desired files from target .mkv
  2. run mkvmerge to create new .mkv with desired files and flags (i.e. default subtitles)

This poses the question of whether parallelism is necessary or even desirable. If batch extraction and batch merging run concurrently, then a given mkvmerge can await the results of its associated mkvextract before resolving. If these processes run in parallel, then we would be awaiting the results from each extraction anyway. At this level then, we are looking for concurrency. However, within the extraction process, it would be more performant to run all actions in parallel. The merge process must wait for the required files to be ready, so these actions can be run concurrently, but there isn't any benefit in trying to multithread them when they might be blocked by the extraction step anyway.

Clone this wiki locally