Tag: conversion

Converting MKV video file to MP4 with hardsubs (embedded subtitles) on Linux (Ubuntu)

I had to convert some MKV video files into MP4 format with embedded (rendered) subtitles. This would not be a problem if not the external ASS subs that I had. HandBrakeCLI can easily convert between those formats but it can use embedded ASS file (from MKV video) or provided SRT. There is no way to use an external ASS subtitles file. Luckily there is a quite simple solution for that issue: we can just remove original MKV video subtitles, add ours and then use HandBrakeCLI to convert the video.

Replacing the ASS MKV subtitles with our own

First we need to remove the original ASS subtitles that are stored in MKV file:

mkvmerge --no-subtitles source.mkv -o target.mkv

This will copy MKV file but will remove subtitles.

After that, we need to add our ow ASS file (subtitles.ass):

mkvmerge -o target_with_subs.mkv target.mkv -D -A subtitles.ass

Now we have a MKV file with our ASS subtitles, that we can use to create MP4 file.

Creating MP4 file with embedded (hardcoded) subtitles

Convertion is really simple:

HandBrakeCLI -i target_with_subs.mkv -o result.mp4 -e x264 -q 20 -B 160\
 --x264-preset medium --two-pass -O --turbo --subtitle "1" \
 --subtitle-burn "1" --srt-codeset utf8

Simple one line long command and 30 minutes later you have your MP4 file with hardsubs.

Converting nested hash into HTTP url params hash version in Ruby

We cannot send nested hash as a param in HTTP requests. For example, when we would like to send something like this:

{:key => "value", :nested => {:nest => "value"}}

It would be (or should be) mapped like this:

/url/?key=value&nested=%7B%3Anest%3D%3E%5C%22value%5C%22%7D

Doesn't look to good ;) However there is a simple way to convert a nested hash into a params acceptable form. We can convert it to a form, that can be mapped into params like this:

/url/?key=value&nested[nest]=value

Here is method to convert any nested hash to a "one level" equivalent:

  module HashConverter

    def self.encode(value, key = nil, out_hash = {})
      case value
      when Hash  then 
        value.each { |k,v| encode(v, append_key(key,k), out_hash) }
        out_hash
      when Array then 
        value.each { |v| encode(v, "#{key}[]", out_hash) }
        out_hash
      when nil   then ''
      else
        out_hash[key] = value
        out_hash
      end
    end

    private

    def self.append_key(root_key, key)
      root_key.nil? ? :"#{key}" : :"#{root_key}[#{key.to_s}]"
    end

  end

And usage example:

hash = {:level0 => 'value', :nested => {:nest1 => "val1", :nest2 => "val2"}}
HashConverter.encode(hash)
#=> {:level0=>"value", :"nested[nest1]"=>"val1", :"nested[nest2]"=>"val2"}

This form can be easily mapped into a HTTP url params

Copyright © 2024 Closer to Code

Theme by Anders NorenUp ↑