Files
ffmpeg_collection/bulk_threading_test_test.py
2026-02-26 15:52:01 +01:00

160 lines
5.7 KiB
Python

import subprocess
import sys
from pathlib import Path
import os
from time import sleep
from threading import Thread
import threading
import re
import xml.etree.ElementTree as ET
max_threads=4
i=0
output_folder_name ="/bulk_convert_out/"
stream_index_modify = []
channels_index_modify = []
stream_index = []
channels_index = []
target_bps_per_channel=96000
audio_stringmap = ""
droppedFile = sys.argv[1]
droppedName = Path(droppedFile).name
originalfiles = sys.orig_argv[2:]
#long path shenanigans
joined = (' '.join(originalfiles))
re.sub (' +', ' ', joined)
listed = re.split(r'(.+?mkv)', joined)
listed = list(filter(None, listed))
listed = [i.lstrip() for i in listed]
#droppedFile= ['test.mkv0out.mkv', "test.mkv1out.mkv","test.mkv2out.mkv","test.mkv3out.mkv","test.mkv4out.mkv","test.mkv5out.mkv"]
#get path of script location and remove the tail
head_tail = os.path.split(sys.argv[0])
output_path = head_tail[0]
#skip first part of sys.argv since it points to script location
#arguments = sys.argv[1:]
#arguments = droppedFile
#check if output folder exists, otherwise create it
isExist = os.path.exists(output_path+output_folder_name)
if not isExist:
os.makedirs(output_path+output_folder_name)
org_count = len(listed)
finished_count = int()
class CustomThread(Thread):
# constructor
def __init__(self):
# execute the base constructor
Thread.__init__(self)
# set a default value
def run(self):
#sleep(1)
global i
global finished_count
global audio_stringmap
file=listed.pop(0)
os.rename(file, file+"i")
mkvmerge_input = file+"i"
mkv_args = 'mkvmerge.exe --output "{file}" "{mkvmerge_input}"'.format(file=file, output_path=output_path, output_folder_name=output_folder_name, mkvmerge_input=mkvmerge_input)
mkv_run = subprocess.run(mkv_args)
#wait = mkv_run.wait()
print("before remove file")
os.remove(file+"i")
basename = os.path.basename(file)
print(file)
sleep(1)
#find audio channels to encode
ffprobe_args = '.\\ffprobe.exe -i "{file}" -show_entries format:streams -of xml'.format(file=file)
print(ffprobe_args)
ffprobe = subprocess.Popen(["powershell.exe", ffprobe_args], stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='UTF-8')
ffprobe_out = ffprobe.communicate()[0]
print("printing out", ffprobe_out)
root = ET.fromstring(ffprobe_out)
streams = root[1].findall("stream")
for index in streams:
if index.get("codec_type") == "audio":
stream_channels = int(index.get("channels"))
for tag in index.findall("tag"):
if tag.get("key") == "BPS":
BPS_Value = int(tag.get("value"))
if BPS_Value >= target_bps_per_channel*stream_channels*1.2:
stream_index_modify.append(int(index.get("index"))-1)
channels_index_modify.append(int(index.get("channels")))
else:
stream_index.append(int(index.get("index"))-1)
channels_index.append(int(index.get("channels")))
x=0
print("streams to transcode: ", stream_index_modify)
print("channels to modify", channels_index_modify)
print("streams to copy: ", stream_index)
print("channels to copy: ", channels_index)
for each in stream_index_modify:
channel_layout = channels_index_modify[x]
bitrate = int(channel_layout*target_bps_per_channel/1000)
audio_stringmap += "-map 0:a:{each} -c:a:{each} libopus -ac:a:{each} {channel_layout} -b:a:{each} {bitrate}k ".format(each=each,bitrate=bitrate,channel_layout=channel_layout)
x+=1
#print(audio_stringmap)
x=0
for each in stream_index:
channel_layout = channels_index[x]
bitrate = int(channel_layout*target_bps_per_channel/1000)
audio_stringmap += "-map 0:a:{each} -c:a:{each} copy ".format(each=each,bitrate=bitrate,channel_layout=channel_layout)
x+=1
print(audio_stringmap)
args = 'ffmpeg.exe -analyzeduration 20000000 -probesize 20000000 -i "{file}" -fps_mode passthrough -map 0:t? -map 0:v:0? -c:v libx265 -preset slow -crf 15.4 -x265-params "no-sao=1:bframes=8:psy-rd=2:psy-rdoq=1.5:aq-mode=3:ref=6:deblock=-1,-1" -pix_fmt yuv420p10le {audio_stringmap} -map 0:s? -c:s copy -f matroska "{output_path}{output_folder_name}{basename}"'.format(file=file, output_path=output_path, output_folder_name=output_folder_name, basename=basename, audio_stringmap=audio_stringmap)
print(args)
results = subprocess.Popen(args, creationflags=0x00004000, stdout=subprocess.PIPE)
#streeamdata = results.communicate()[0]
data = results.wait()
if data == 0:
i=i-1
finished_count=finished_count+1
while listed != False:
if i < max_threads:
global self
if bool(listed) != False:
t1 = CustomThread()
t1.start()
if bool(listed) == False:
while bool(threading.active_count() > 1):
print("Finished",finished_count,"out of", org_count," ")
sleep(1)
t1.join()
print("Completed",finished_count,"out of",org_count, "inputs Successfully")
input("waiting")
exit()
print("incrementing i in loop")
i=i+1
else:
print("Finished ",finished_count,"out of ", org_count)
sleep(1)
print("continuing ")