Created
July 29, 2014 18:35
-
-
Save ctrlcctrlv/0ca18ecad315f56b8ede to your computer and use it in GitHub Desktop.
Convert softsubbed MKV files into hardsubbed MP4 files for playback via Roku, low powered devices etc, keep all fonts intact.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# HARDSUB.SH | |
# (c) 2014 Fredrick Brennan | |
# | |
# Usage notes: | |
# This script requires that ~/.fonts is in your fontconfig path. | |
# This script also requires mkvmerge, realpath and ffmpeg to be installed. Only supports SSA subs and MKV files. | |
# Also note that this script can take a long time to run. | |
# Run as `hardsub.sh FILE_NAME` | |
# You should be able to delete the following created files after it is done: done_subtitles.ass and the entire contents of ~/.fonts/MKV | |
# They are not deleted automatically because you may want to use them again for a subsequent ffmpeg run | |
DIRECTORY=$HOME/.fonts/MKV | |
# Save $1 because `set` will overwrite it | |
VIDEO_FILE=`realpath "$1"` | |
OUTPUT=$2 | |
WD=`pwd` | |
declare -a FONTS | |
declare -a SUBTITLES | |
# Create fonts directory | |
if [ ! -d "$DIRECTORY" ]; then | |
mkdir "$DIRECTORY" | |
fi | |
if [ ! -f "$VIDEO_FILE" ]; then | |
echo "Cannot read $VIDEO_FILE" | |
exit 1 | |
fi | |
if [ -z "$OUTPUT" ]; then | |
echo "Warning: No output file specified, will use output.mp4" | |
OUTPUT='output.mp4' | |
fi | |
# Use mkvmerge to get all our subtitles | |
MKVMERGE=`mkvmerge -i "$VIDEO_FILE"` | |
if [ $? -ne 0 ]; then | |
echo "mkvmerge failed to run!" | |
echo "$MKVMERGE" | |
exit 1 | |
fi | |
# Get the track IDs of our subtitles | |
while read LINE; do | |
set $LINE | |
# $LINE should look like: | |
# $1 $2 $3 $4 $5 | |
# Track ID 3: subtitles (SubStationAlpha) | |
if [ $1 = 'Track' ]; then | |
if [ $4 = 'subtitles' ]; then | |
TRACK_ID=${3//[!0-9]/}; | |
SUBTITLES+=("$TRACK_ID") | |
fi | |
fi | |
# $LINE should look like: | |
# $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 | |
# Attachment ID 1: type 'application/x-truetype-font', size 58224 bytes, file name '9SALERNO.TTF' | |
if [ $1 = 'Attachment' ]; then | |
if [ $5 = "'application/x-truetype-font'," ]; then | |
ATTACH_ID=${3//[!0-9]/}; | |
FONTS+=("$ATTACH_ID") | |
fi | |
fi | |
done <<< "$MKVMERGE" | |
if [ ${#SUBTITLES[@]} -eq 0 ]; then | |
echo 'Error: File has no subtitles!' | |
exit 1 | |
fi | |
echo ${#SUBTITLES[@]} subtitle tracks found: ${SUBTITLES[*]} | |
echo ${#FONTS[@]} font attachments found: ${FONTS[*]} | |
#Extract all our subtitles | |
for i in ${SUBTITLES[@]}; do | |
mkvextract tracks "$VIDEO_FILE" "$i":subtitles"$i".ass | |
done | |
#Combine all subtitles into one mega SSA file; just simple concatenation seems to work. | |
cat subtitles* > done_subtitles.ass | |
#Delete separate subtitle files | |
rm subtitles* | |
#Extract all our fonts | |
cd $DIRECTORY | |
mkvextract attachments "$VIDEO_FILE" ${FONTS[*]} | |
cd $WD | |
#Do it. You can edit this line to your liking. | |
echo Running this line: ffmpeg -i \""$VIDEO_FILE"\" -acodec copy -vcodec libx264 -report -qscale 0 -vf "ass=done_subtitles.ass" "$OUTPUT" | |
echo | |
ffmpeg -i "$VIDEO_FILE" -acodec copy -vcodec libx264 -report -qscale 0 -vf "ass=done_subtitles.ass" "$OUTPUT" | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment