Jump to content

How to batch convert subtitles inside an mkv from .ass to .srt

Go to solution Solved by WereCatf,
7 minutes ago, elfensky said:

it seems to convert, but it seems not to be able to write the file to disk. I tried running with sudo, no difference

*sigh* No, you don't need sudo to run the script. It seems either the script didn't correctly catch the subtitle-language from mkvinfo, or it's not specified at all. I added a small tweak to the script now:

#!/bin/bash

for x in *.mkv
do

numTracks=$(mkvinfo "$x"|grep -c "S_TEXT/ASS")
if [ $numTracks -ne 1 ]
then
	echo "No tracks to convert or more than one! Aborting."
	exit 1
fi

for subTrack in $(mkvinfo "$x"|grep -B4 "S_TEXT/ASS"|grep "Track UID"|cut -d ":" -f 2)
do
	trackLang=$(mkvinfo "$x"|grep -B4 "S_TEXT/ASS"|grep -C3 "Track UID: $subTrack"|grep "Language:"|cut -d ":" -f 2|tr -d '\040\011\012\015')
	if [ -z "$trackLang" ]
	then
		trackLang="eng"
	fi
	let subTrack--
	ffmpeg -i "$x" -map 0:$subTrack out.srt
	if [ $? -ne 0 ]
	then
		echo "Failed to convert subtitle to SRT!"
		exit 1
	fi
	mkvmerge -o output.mkv "$x" --language 0:$trackLang --default-track "0:yes" out.srt
	if [ $? -ne 0 ]
	then
		echo "Failed to merge subtitle to $x!"
		exit 1
	fi
	rm out.srt
	mkdir -p Converted
	echo "Successfully converted $x to output.mkv with added SRT-subs!"
	mv output.mkv "Converted/$x"
	break
done

done

 

My Plex client doesn't like .ass subtitles and requires a video transcode for them, so I want to convert them all into .srt, which from testing I know it can play just fine. I'm aware I will loose formatting/position when I do it, but I plan keep both

 

My current workflow is to extract the subtitle using MKVCleaver, convert it using https://sorz.github.io/asstosrt-wasm/ and then, using MKVToolNix GUI to put it in front of the .ass file and re-encode it.

And while that approach works for movies, it gets tedious real quick if I start doing series.

 

So I'm wondering if there's a way to automate that, using a script or something. I imagine a script that would do all that automatically for every file in a directory. Is something like that possible, or is there an even better way?

 

edit: on either, Windows 10 or Ubuntu Server 19.04 (preferably I would like ways for both, so I can try different ways of integrating it into my workflow)

Link to comment
Share on other sites

Link to post
Share on other sites

5 minutes ago, elfensky said:

Is something like that possible

Certainly, and it's not even particularly difficult. That said, you didn't mention what OS you're using.

Hand, n. A singular instrument worn at the end of the human arm and commonly thrust into somebody’s pocket.

Link to comment
Share on other sites

Link to post
Share on other sites

13 minutes ago, WereCatf said:

Certainly, and it's not even particularly difficult. That said, you didn't mention what OS you're using.

Windows 10 or Ubuntu Server 19.04, whichever's easier.

right now I do everything I described on Windows, because having a GUI makes my life so much easier.

Link to comment
Share on other sites

Link to post
Share on other sites

4 minutes ago, elfensky said:

Windows 10 or Ubuntu Server 19.04, whichever's easier.

Well, the easiest and by far the fastest method would be to...simply download the subtitles as SRT from e.g. Subscene or similar.

Hand, n. A singular instrument worn at the end of the human arm and commonly thrust into somebody’s pocket.

Link to comment
Share on other sites

Link to post
Share on other sites

9 minutes ago, WereCatf said:

Well, the easiest and by far the fastest method would be to...simply download the subtitles as SRT from e.g. Subscene or similar.

That still requires me to use MKVToolNix to embed them into the .mkv file.

Also, that would take even more time, as I'll need to go looking for subtitles of the show and hope the timing matches, so I dont have to edit the offset and so on.

Meanwhile, I have a "perfectly good" .ass that I know is matched to the video file.



Anyway, let's say I follow your advice, and I have a bunch of .mkv files with matchted .srt files... How can I batch-embed those files into the corresponding mkv files, while also giving the tracks a name and language etc... ? 'Cuz right now I'm doing it 1 by 1 using the GUI

Link to comment
Share on other sites

Link to post
Share on other sites

3 minutes ago, elfensky said:

That still requires me to use MKVToolNix to embed them into the .mkv file.

Also, that would take even more time, as I'll need to go looking for subtitles of the show and hope the timing matches, so I dont have to edit the offset and so on.

Meanwhile, I have a "perfectly good" .ass that I know is matched to the video file.

Pretty sure converting it would require them to be re-matched as it's usually by file name (including extension). 

If you have a smart system like plex or emby, they should handle that for you as long as the Mkv and srt files are in the same folder. 

Fine you want the PSU tier list? Have the PSU tier list: https://linustechtips.com/main/topic/1116640-psu-tier-list-40-rev-103/

 

Stille (Desktop)

Ryzen 9 3900XT@4.5Ghz - Cryorig H7 Ultimate - 16GB Vengeance LPX 3000Mhz- MSI RTX 3080 Ti Ventus 3x OC - SanDisk Plus 480GB - Crucial MX500 500GB - Intel 660P 1TB SSD - (2x) WD Red 2TB - EVGA G3 650w - Corsair 760T

Evoo Gaming 15"
i7-9750H - 16GB DDR4 - GTX 1660Ti - 480GB SSD M.2 - 1TB 2.5" BX500 SSD 

VM + NAS Server (ProxMox 6.3)

1x Xeon E5-2690 v2  - 92GB ECC DDR3 - Quadro 4000 - Dell H310 HBA (Flashed with IT firmware) -500GB Crucial MX500 (Proxmox Host) Kingston 128GB SSD (FreeNAS dev/ID passthrough) - 8x4TB Toshiba N300 HDD

Toys: Ender 3 Pro, Oculus Rift CV1, Oculus Quest 2, about half a dozen raspberry Pis (2b to 4), Arduino Uno, Arduino Mega, Arduino nano (x3), Arduino nano pro, Atomic Pi. 

Link to comment
Share on other sites

Link to post
Share on other sites

2 minutes ago, BrinkGG said:

Pretty sure converting it would require them to be re-matched as it's usually by file name (including extension). 

If you have a smart system like plex or emby, they should handle that for you as long as the Mkv and srt files are in the same folder. 

I'm aware, Plex picks up external subtitle files as long as the names are the same, and that's the solution I currently use for series, but it's imo messy, given the ability to embed the file exists.
Also, with the internal .ass still being present, Plex will default to it over the external file, necessitating a manual switch every time... Which is annoying.
 

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, elfensky said:

My current workflow is to extract the subtitle using MKVCleaver, convert it using https://sorz.github.io/asstosrt-wasm/ and then, using MKVToolNix GUI to put it in front of the .ass file and re-encode it.

And while that approach works for movies, it gets tedious real quick if I start doing series.

 

So I'm wondering if there's a way to automate that, using a script or something. I imagine a script that would do all that automatically for every file in a directory. Is something like that possible, or is there an even better way?

Would the script have to convert all the ASS-subtitles in the file or only one? Do the files have multiple ASS-subs in them or only one? If there's only one, then it'd be easy, but if there's multiple ones, you'd have to manually tell the script which one to convert.

Hand, n. A singular instrument worn at the end of the human arm and commonly thrust into somebody’s pocket.

Link to comment
Share on other sites

Link to post
Share on other sites

2 minutes ago, WereCatf said:

Would the script have to convert all the ASS-subtitles in the file or only one? Do the files have multiple ASS-subs in them or only one? If there's only one, then it'd be easy, but if there's multiple ones, you'd have to manually tell the script which one to convert.

there is a single .ass subtitle per file.

O0k2VNW.png

Link to comment
Share on other sites

Link to post
Share on other sites

41 minutes ago, elfensky said:

there is a single .ass subtitle per file.

Something like this should work under Linux. I didn't test it thoroughly, but give it a try:

#!/bin/bash

for x in *.mkv
do

numTracks=$(mkvinfo "$x"|grep -c "S_TEXT/ASS")
if [ $numTracks -ne 1 ]
then
	echo "No tracks to convert or more than one! Aborting."
	exit 1
fi

for subTrack in $(mkvinfo "$x"|grep -B4 "S_TEXT/ASS"|grep "Track UID"|cut -d ":" -f 2)
do
	trackLang=$(mkvinfo "$x"|grep -B4 "S_TEXT/ASS"|grep -C3 "Track UID: $subTrack"|grep "Language:"|cut -d ":" -f 2|tr -d '\040\011\012\015')
	let subTrack--
	ffmpeg -i "$x" -map 0:$subTrack out.srt
	if [ $? -eq 1 ]
	then
		echo "Failed to convert subtitle to SRT!"
		exit 1
	fi
	mkvmerge -o output.mkv "$x" --language 0:$trackLang --default-track "0:yes" out.srt
	if [ $? -eq 1 ]
	then
		echo "Failed to merge subtitle to $x!"
		exit 1
	fi
	rm out.srt
    echo "Successfully converted $x to output.mkv with added SRT-subs!"
	#COMMENT THESE OUT IF YOU REALLY WANT TO DO THIS
	#rm "$x"
	#mv output.mkv "$x"
	break
done

done

 

Do note that you need mkvinfo, mkvmerge and ffmpeg installed.

Hand, n. A singular instrument worn at the end of the human arm and commonly thrust into somebody’s pocket.

Link to comment
Share on other sites

Link to post
Share on other sites

2 minutes ago, WereCatf said:

Something like this should work under Linux. I didn't test it thoroughly, but give it a try:


#!/bin/bash

for x in *.mkv
do

numTracks=$(mkvinfo "$x"|grep -c "S_TEXT/ASS")
if [ $numTracks -ne 1 ]
then
	echo "No tracks to convert or more than one! Aborting."
	exit 1
fi

for subTrack in $(mkvinfo "$x"|grep -B4 "S_TEXT/ASS"|grep "Track UID"|cut -d ":" -f 2)
do
	trackLang=$(mkvinfo "$x"|grep -B4 "S_TEXT/ASS"|grep -C3 "Track UID: $subTrack"|grep "Language:"|cut -d ":" -f 2|tr -d '\040\011\012\015')
	let subTrack--
	ffmpeg -i "$x" -map 0:$subTrack out.srt
	if [ $? -eq 1 ]
	then
		echo "Failed to convert subtitle to SRT!"
		exit 1
	fi
	mkvmerge -o output.mkv "$x" --language 0:$trackLang --default-track "0:yes" out.srt
	if [ $? -eq 1 ]
	then
		echo "Failed to merge subtitle to the video!"
		exit 1
	fi
	rm out.srt
	#COMMENT THESE OUT IF YOU REALLY WANT TO DO THIS
	#rm "$x"
	#mv output.mkv "$x"
	break
done

done

 

Do note that you need mkvinfo, mkvmerge and ffmpeg installed.

uhm.. so.. what do I save that as? .sh?

Link to comment
Share on other sites

Link to post
Share on other sites

12 minutes ago, elfensky said:

uhm.. so.. what do I save that as? .sh?

Whatever you like, really.

Hand, n. A singular instrument worn at the end of the human arm and commonly thrust into somebody’s pocket.

Link to comment
Share on other sites

Link to post
Share on other sites

20 minutes ago, WereCatf said:

You need mkvinfo, mkvmerge and ffmpeg installed.

I have ffmpeg installed

8LMqGI5.png

 

But mkvinfo and mkvmerge I'm struggling with. Are they both packaged inside mkvtoolnix? If so I seem to have it installed as well.
vFNH4og.png

 

But.. uhm.. how am I supposed to run that script? I put it into a txt file and then renamed it to sh.

z0Z2l1Z.png

Link to comment
Share on other sites

Link to post
Share on other sites

1 minute ago, elfensky said:

But.. uhm.. how am I supposed to run that script? I put it into a txt file and then renamed it to sh.

You didn't mention that you're a complete newbie when it comes to Linux. You just mentioned that you're fine with Ubuntu 19.04, so I assumed things. First of all, here's a slightly tweaked script, so you don't have to modify it yourself:

#!/bin/bash

for x in *.mkv
do

numTracks=$(mkvinfo "$x"|grep -c "S_TEXT/ASS")
if [ $numTracks -ne 1 ]
then
	echo "No tracks to convert or more than one! Aborting."
	exit 1
fi

for subTrack in $(mkvinfo "$x"|grep -B4 "S_TEXT/ASS"|grep "Track UID"|cut -d ":" -f 2)
do
	trackLang=$(mkvinfo "$x"|grep -B4 "S_TEXT/ASS"|grep -C3 "Track UID: $subTrack"|grep "Language:"|cut -d ":" -f 2|tr -d '\040\011\012\015')
	let subTrack--
	ffmpeg -i "$x" -map 0:$subTrack out.srt
	if [ $? -eq 1 ]
	then
		echo "Failed to convert subtitle to SRT!"
		exit 1
	fi
	mkvmerge -o output.mkv "$x" --language 0:$trackLang --default-track "0:yes" out.srt
	if [ $? -eq 1 ]
	then
		echo "Failed to merge subtitle to $x!"
		exit 1
	fi
	rm out.srt
	mkdir -p Converted
	echo "Successfully converted $x to output.mkv with added SRT-subs!"
	mv output.mkv "Converted/$x"
	break
done

done

 

Secondly, yes, mkvmerge and mkvinfo are a part of mkvtoolnix.

 

Thirdly, save the above script to some file, like e.g. convert.sh and then do chmod u+x convert.sh on it to make it executable. Then cd to the directory of your choosing and execute /path/to/convert.sh and POOF -- it'll output the new files with the SRT included in them into a directory called Converted.

Hand, n. A singular instrument worn at the end of the human arm and commonly thrust into somebody’s pocket.

Link to comment
Share on other sites

Link to post
Share on other sites

26 minutes ago, WereCatf said:

You didn't mention that you're a complete newbie when it comes to Linux. You just mentioned that you're fine with Ubuntu 19.04, so I assumed things. First of all, here's a slightly tweaked script, so you don't have to modify it yourself:

 

snip

 

Thirdly, save the above script to some file, like e.g. convert.sh and then do chmod u+x convert.sh on it to make it executable. Then cd to the directory of your choosing and execute /path/to/convert.sh and POOF -- it'll output the new files with the SRT included in them into a directory called Converted.

vWGucXV.jpg

 

it seems to convert, but it seems not to be able to write the file to disk. I tried running with sudo, no difference

 

Link to comment
Share on other sites

Link to post
Share on other sites

7 minutes ago, elfensky said:

it seems to convert, but it seems not to be able to write the file to disk. I tried running with sudo, no difference

*sigh* No, you don't need sudo to run the script. It seems either the script didn't correctly catch the subtitle-language from mkvinfo, or it's not specified at all. I added a small tweak to the script now:

#!/bin/bash

for x in *.mkv
do

numTracks=$(mkvinfo "$x"|grep -c "S_TEXT/ASS")
if [ $numTracks -ne 1 ]
then
	echo "No tracks to convert or more than one! Aborting."
	exit 1
fi

for subTrack in $(mkvinfo "$x"|grep -B4 "S_TEXT/ASS"|grep "Track UID"|cut -d ":" -f 2)
do
	trackLang=$(mkvinfo "$x"|grep -B4 "S_TEXT/ASS"|grep -C3 "Track UID: $subTrack"|grep "Language:"|cut -d ":" -f 2|tr -d '\040\011\012\015')
	if [ -z "$trackLang" ]
	then
		trackLang="eng"
	fi
	let subTrack--
	ffmpeg -i "$x" -map 0:$subTrack out.srt
	if [ $? -ne 0 ]
	then
		echo "Failed to convert subtitle to SRT!"
		exit 1
	fi
	mkvmerge -o output.mkv "$x" --language 0:$trackLang --default-track "0:yes" out.srt
	if [ $? -ne 0 ]
	then
		echo "Failed to merge subtitle to $x!"
		exit 1
	fi
	rm out.srt
	mkdir -p Converted
	echo "Successfully converted $x to output.mkv with added SRT-subs!"
	mv output.mkv "Converted/$x"
	break
done

done

 

Hand, n. A singular instrument worn at the end of the human arm and commonly thrust into somebody’s pocket.

Link to comment
Share on other sites

Link to post
Share on other sites

18 minutes ago, WereCatf said:

*sigh*

I'm sorry pls forgive me ? I'll mention I'm new to linux next time.

Also, you are my new hero, thanks a lot!
ylRmBU2.png

 

It works!
 

Link to comment
Share on other sites

Link to post
Share on other sites

4 minutes ago, elfensky said:

thanks a lot!

You're welcome.

Hand, n. A singular instrument worn at the end of the human arm and commonly thrust into somebody’s pocket.

Link to comment
Share on other sites

Link to post
Share on other sites

It may be easier to use eac3to  to extract tracks

you can use  eac3.to filename to get a dump of the tracks inside the file ex :

 

eac3to.exe "D:\Movies\movie.mkv"
MKV, 1 video track, 2 audio tracks, 10 subtitle tracks, 2:03:42, 24p /1.001
1: h264/AVC, English, 1280x536 24p /1.001
2: AC3, English, 5.1 channels, 640kbps, 48kHz
3: AC3, English, 2.0 channels, 192kbps, 48kHz
   "Commentary"
4: Subtitle (SRT), English
5: Subtitle (SRT), English, "SDH"
6: Subtitle (SRT), English, "Commentary"
7: Subtitle (PGS), French
8: Subtitle (PGS), French, "Commentary"
9: Subtitle (PGS), Portuguese
10: Subtitle (PGS), Portuguese, "Commentary"
11: Subtitle (PGS), Spanish
12: Subtitle (PGS), Spanish, "Commentary"
13: Subtitle (SRT), Turkish

as you can see you can tell what tracks are subtitles easily (by subtitle keyword) and have language, and if it's commentary track subtitle or not

you can then extract one or several tracks by saying something like

 

eac3to.exe "D:\Movies\movie.mkv" 4: sub1.srt 5: sub2.sub 6: sub3.srt
rem extension must match format of subtitle ex .srt for SRT, sub or whatever extension PGS has etc

 

 

Link to comment
Share on other sites

Link to post
Share on other sites

  • 2 weeks later...
On 10/4/2019 at 11:45 PM, WereCatf said:

You're welcome.

Sorry to bother you again, but any chance you could add to the script so it would remove the original .ass subs?
Or change it to the second subtitle track?

I tried looking at the documentation for mkvtoolnix, but it honestly confuses the crap outta me.

 

to select the first subtitle track I'd have to do --edit track:s1, and deleting seems to be --delete <name>, so would the line be --delete track:s1?
 

--set track:s1=track:s3
--set track:s1=track:s1
--set track:s3=track:s2? 
That seems super convoluted (if that's even the right way to do it)  

 



And if yes where would I have to put it in the scipt?

Link to comment
Share on other sites

Link to post
Share on other sites

Do the steps you want to do in the mkvtoolnix gui and select the menu option "multiplexer > show command line"  to see how the application would create the command.

Link to comment
Share on other sites

Link to post
Share on other sites

  • 3 months later...

Sorry to revive this thread. But i have a problem.. When i run the script, it works perfectly. But for some reason srt subs now have 

 

<font face="sans-serif" size="47"> subtexthere </font>

on every sub... And this makes the subs HUGE!
Is there any way to fix this? Thanks!

Link to comment
Share on other sites

Link to post
Share on other sites

The easiest would be to do a search and replace in notepad

 

search for <font face="sans-serif" size="47"> 

replace with [nothing]

 

search for </font>

replace with [nothing]

 

Link to comment
Share on other sites

Link to post
Share on other sites

  • 7 months later...
On 10/4/2019 at 2:29 PM, WereCatf said:

Certainly, and it's not even particularly difficult. That said, you didn't mention what OS you're using.

Why could you replicate this for windows? I'm not a Linux newbie but prefer my emby on my windows 10.

Or could this be integrated as some sort of Scheduled Task inside of by server? I really need this! 

 

hit us up here! https://emby.media/community/index.php?/topic/83855-script-to-extract-subs/

Link to comment
Share on other sites

Link to post
Share on other sites

1 hour ago, dovedescent7 said:

Why could you replicate this for windows?

You could convert the script to Powershell, yes, but I don't use Powershell. You could also install Cygwin or e.g. Git for Windows and that way use Bash under Windows, allowing you to simply run Bash-scripts as-is.

1 hour ago, dovedescent7 said:

hit us up here!

No. I don't use Emby, I have no interest in joining some Emby-specific forums.

Hand, n. A singular instrument worn at the end of the human arm and commonly thrust into somebody’s pocket.

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×