Skip to content

Instantly share code, notes, and snippets.

@pog42
Last active March 29, 2021 14:51
Show Gist options
  • Save pog42/fa6893d4e8769336abe92a7ebce6f429 to your computer and use it in GitHub Desktop.
Save pog42/fa6893d4e8769336abe92a7ebce6f429 to your computer and use it in GitHub Desktop.
Remuxing batch scripts for windows with ffmpeg and mkvtoolnix
import os,re,time,subprocess
folder2 = os.getcwd()
folderout = os.path.join(folder2, 'output')
mkvpaths = []
mkvnames = []
subpaths = []
fontpaths = []
def replace(s):
x=s.replace('-', '').replace(" ", "").replace("[","").replace("]","").replace("_","").replace("(","").replace(")","")
return x.lower()
for root, dirnames, filenames in os.walk(folder2):
for filename in filenames:
if filename.lower().endswith('.mkv'):
mkvpaths.append(os.path.join(root, filename))
replaced = filename.replace('.mkv', '')
replaced = replaced.strip()
mkvnames.append(replaced)
if filename.lower().endswith('ass'):
subpaths.append(os.path.join(root, filename))
if filename.lower().endswith('ttf') or filename.lower().endswith('otf'):
fontpaths.append(os.path.join(root, filename))
def match(mkvnames, mkvpaths, fontpaths,subpaths):
for i in range(len(mkvnames)):
y=0
pattern = re.compile(replace(mkvnames[i]))
outpath = os.path.join(folderout, mkvnames[i]+".mkv")
command=['mkvmerge', '--output', outpath, '--no-attachments','--no-subtitles', mkvpaths[i]]
for x in range(len(subpaths)):
matches = pattern.findall(replace(subpaths[x]))
if matches:
y=1
command.extend([subpaths[x]])
for x in range(len(fontpaths)):
matches = pattern.findall(replace(fontpaths[x]))
if matches:
y=1
command.extend(["--attach-file", fontpaths[x]])
#print(command)
if y==1:
subprocess.call(command)
elif y==0:
print("No matches")
else:
print("Error in matching")
def match_debug(mkvnames, mkvpaths, fontpaths,subpaths):
for i in mkvnames:
print(replace(i))
for i in fontpaths:
print(replace(i))
for i in subpaths:
print(replace(i))
match(mkvnames, mkvpaths, fontpaths, subpaths)
print("Done")
import vapoursynth,sys
core = vapoursynth.core
core.std.LoadPlugin(path='/home/pog/lib/libffms2.so')
clip = core.ffms2.Source(file)
clip = clip[::720]
clip = core.resize.Spline36(clip, format=vapoursynth.RGB24, matrix_in_s="709", dither_type="error_diffusion")
clip.set_output()
#USAGE
for file in *.mkv;do
vspipe comp.vpy -a "file=${file}" - | ffmpeg -f rawvideo -pix_fmt gbrp -s 1920x1080 -i pipe: -map 0:v "./images2/%3d-${file%.*}.png"
done
FOR /F "tokens=*" %g IN ( 'dir /b *.mkv ') DO vspipe comp.vpy -a "file=%g" - | ffmpeg -f rawvideo -pix_fmt gbrp -s 1920x1080 -i pipe: -map 0:v "./images/%3d-%g.png"
for %%f in (*.mkv) do mkdir "Attachments\%%f\fonts"
for %%g in (*.mkv) do (
cd "Attachments\%%g\fonts"
ffmpeg -y -dump_attachment:t "" -i "%%~fg"
cd ..\..\.. )
for %%g in (*.mkv) do (
ffmpeg -n -i "%%g" -map 0:s:0 -c:s copy "Attachments\%%g\%%~ng_track1.ass"
ffmpeg -n -i "%%g" -map 0:s:1 -c:s copy "Attachments\%%g\%%~ng_track2.ass"
ffmpeg -n -i "%%g" -map 0:s:2 -c:s copy "Attachments\%%g\%%~ng_track3.ass"
ffmpeg -n -i "%%g" -map 0:s:3 -c:s copy "Attachments\%%g\%%~ng_track4.ass"
)
for file in *.mkv;do
aaa="$(pwd)/${file}"
mkdir -p "Attachments/${file}/fonts"
cd "./Attachments/${file}/fonts"
ffmpeg -y -dump_attachment:t "" -i "$aaa"
cd ../../..
done
for file in *.mkv;do
ffmpeg -n -i "${file}" -map 0:s:0 -c:s copy "Attachments\${file}\${file}_track1.ass"
ffmpeg -n -i "${file}" -map 0:s:1 -c:s copy "Attachments\${file}\${file}_track2.ass"
ffmpeg -n -i "${file}" -map 0:s:2 -c:s copy "Attachments\${file}\${file}_track3.ass"
ffmpeg -n -i "${file}" -map 0:s:3 -c:s copy "Attachments\${file}\${file}_track4.ass"
done
:: Check ffmpeg map for detailed explanations
:: Copy first video, second audio, third subtitle stream and all attachments
FOR /F "tokens=*" %G IN ( 'dir /b *.mkv ') DO ffmpeg -n -i "%G" -map 0:v:0 -map 0:a:1 -map 0:s:2 -map 0:t? -c copy "%~nG .mkv"
::Linux example
mkdir output
for file in *.mkv;do
ffmpeg -n -i "$file" -map 0:v:0 -map 0:a:1 -map 0:s:2 -map 0:t? -c copy "./output/${file%.*}.mkv"
done
:: Extract first audio/subtitle/video stream
FOR /F "tokens=*" %G IN ( 'dir /b *.mkv ') DO ffmpeg -n -i "%G" -map 0:a:0 -c:a copy "%~nG.opus"
FOR /F "tokens=*" %G IN ( 'dir /b *.mkv ') DO ffmpeg -n -i "%G" -map 0:s:0 -c:s copy "%~nG.ass"
FOR /F "tokens=*" %G IN ( 'dir /b *.mkv ') DO ffmpeg -n -i "%G" -map 0:v -c:v copy "%~nG.mkv"
:: Add subs/audio
FOR /F "tokens=*" %G IN ( 'dir /b *.mkv ') DO ffmpeg -n -i "%G" -i "%~dpnG.ass" -map 0:v -map 0:a -map 1:s -map 0:t? -c copy "%~nG .mkv"
FOR /F "tokens=*" %G IN ( 'dir /b *.mkv ') DO ffmpeg -n -i "%G" -i "%~dpnG.ass" -i "%~dpnG doki.ass" -map 0:v -map 0:a -map 1:s -map 2:s -map 0:s? -map 0:t? -c copy "%~nG .mkv"
FOR /F "tokens=*" %G IN ( 'dir /b *.mkv ') DO ffmpeg -n -i "%G" -i "%~dpnG .mkv" -map 0:v -map 1:a -map 1:s -map 1:t? -map 0:s? -map 0:t? -c copy "%~nG .mkv"
::Remove all subs/fonts
FOR /F "tokens=*" %G IN ( 'dir /b *.mkv ') DO ffmpeg -n -i "%G" -map 0 -map -0:s -c copy "%~nG nosub.mkv"
FOR /F "tokens=*" %G IN ( 'dir /b *.mkv ') DO ffmpeg -n -i "%G" -map 0 -map -0:t -c copy "%~nG nofonts.mkv"
:: Set video title to filename
FOR /F "tokens=*" %G IN ( 'dir /b *.mkv ') DO ffmpeg -n -i "%G" -map 0 -metadata title="%G" -c copy "%~nG .mkv"
::Extract Frames
FOR /F "tokens=*" %G IN ( 'dir /b ' ) DO ffmpeg -ss 00:06:31.00 -i "%G" -f image2 -t 1 "%2d-%~nG.png"
FOR /F "tokens=*" %G IN ( 'dir /b ' ) DO ffmpeg -n -i "%G" -f image2 -vf fps=fps=1/100 "%2d-%~nG.png"
:: Attach single font
FOR /F "tokens=*" %G IN ( 'dir /b *.mkv ') DO ffmpeg -n -i "%G" -map 0 -attach "fontname.ttf" -metadata:s:9 mimetype=application/x-truetype-font -c copy "%~nG .mkv"
:: Dump all attachments(overwriting dupes across all files)
FOR /F "tokens=*" %G IN ( 'dir /b *.mkv ') DO ffmpeg -y -dump_attachment:t "" -i "%G"
:: ffmpeg would be my first choice because map>mkvmerge track IDs
:: About track IDs - https://gitlab.com/mbunkus/mkvtoolnix/-/wikis/About-track-UIDs,-track-numbers-and-track-IDs#misconceptions-about-the-relationship-between-track-ids-and-track-numbers
::Language/tag reference(will work when when all streams are correctly tagged in input)
::Audio jpn or eng
::Sings/songs may be eng, full subs may be eng/jpn/und or everything may be und, use absolute ref in that case
:: Remove eng audio and eng,und subs
FOR /F "tokens=*" %G IN ( 'dir /b *.mkv ') DO mkvmerge --output "%~nG .mkv" --audio-tracks !eng --subtitle-tracks !eng,und "%G"
:: Keep only jpn audio and und subs
FOR /F "tokens=*" %G IN ( 'dir /b *.mkv ') DO mkvmerge --output "%~nG .mkv" --audio-tracks jpn --subtitle-tracks und "%G"
::Absolute track ID reference (check the track IDs with mkvmerge -i "input.mkv" and replace them in the commands)
:: Keep audio track 1 and subtitle track 4 (will not work if track 1 isn't audio or track 4 isn't sub)
FOR /F "tokens=*" %G IN ( 'dir /b *.mkv ') DO mkvmerge --output "%~nG .mkv" --audio-tracks 1 --subtitle-tracks 4 "%G"
:: Remove all video/audio/subs/attachments streams
FOR /F "tokens=*" %G IN ( 'dir /b *.mkv ') DO mkvmerge --output "%~nG .mkv" --no-video --no-audio --no-subtitles --no-attachments "%G"
:: Add subs/font
FOR /F "tokens=*" %G IN ( 'dir /b *.mkv ') DO mkvmerge --output "%~nG .mkv" "%~dpnG.ass" "%G"
FOR /F "tokens=*" %G IN ( 'dir /b *.mkv ') DO mkvmerge --output "%~nG .mkv" --attachment-mime-type application/x-truetype-font --attach-file "font.ttf "%G"
param(
[Parameter(Mandatory)]
[string]$Fonts
)
$mkvmerge = Get-Command mkvmerge -ErrorAction SilentlyContinue
if ($? -eq $false) {
throw [System.Management.Automation.CommandNotFoundException]::new("mkvmerge not found.")
}
Write-Debug "Using mkvmerge: $($mkvmerge.Path)"
Write-Debug "Font directory: $Fonts"
$FontFlags = ""
$FontFiles = Get-ChildItem -LiteralPath $Fonts
# mkvmerge requires the MIME type
$FontFiles | Where-Object Extension -eq ".ttf" | ForEach-Object {
$FontFlags += "--attachment-name `"$($_.BaseName)`" --attachment-mime-type font/ttf --attach-file `"$($_.FullName)`" "
}
$FontFiles | Where-Object Extension -eq ".otf" | ForEach-Object {
$FontFlags += "--attachment-name `"$($_.BaseName)`" --attachment-mime-type font/otf --attach-file `"$($_.FullName)`" "
}
Write-Debug "Font attachment flags: $FontFlags"
$InputFiles = Get-ChildItem "$PWD\*.mkv"
$InputFiles | ForEach-Object {
$Output = $_.DirectoryName + "\" + $_.BaseName + "muxed" + $_.Extension
Write-Debug "Output: $Output"
Invoke-Expression "& `"$($mkvmerge.Path)`" -o `"$Output`" `"$($_.FullName)`" $SubtitleFlags $FontFlags"
}
# Open powershell in the folder with the mkv files and run the following command
#.\Mux-Kawaiika.ps1 -Fonts <directory where the fonts are>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment