Skip to content

Commit 2fc415b

Browse files
committed
v1.32
* Removed the need for the binary mediainfo.exe (cli) - this has been replaced by an internal python module pymediainfo, it's a lot quicker/easier to use * Removed lots of code that was related to mediainfocli * Corrected part of the code to reset the config.ini file * The "Start" button will no longer enable until you have selected a job (HDR or Dolby parser) or unless the program automatically does it for you * Program now has the ability to detect if a file has BOTH Dolby Vision and HDR10+, in the event it detects both, the program will not automatically select which parser to use. You have to choose which you want and parse, if you want both, you will need to parse both separately and then feed both the json for hdr10+ and bin file for dolby vision to your encoder * Added a new pop up message window when you hover your mouse over the Info label, this is for when the text inside is longer then you can see, you are able to hover the mouse over this and read all of it if you desire * Added a new error window if the program was not able to automatically detect the HDR type, it tells you that it could not automatically detect, opens your web-browser to the github issue tracker where you can post a source sample and the error, in the event it actually was a programming error and not a user error * Progress bars now rely on the new pymediainfo module, this is more simple/less code to use *
1 parent 3a169ac commit 2fc415b

File tree

1 file changed

+47
-85
lines changed

1 file changed

+47
-85
lines changed

HDR-Multi-Tool-Gui.py

Lines changed: 47 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import tkinter as tk
55
import pathlib, subprocess, shutil, threading, webbrowser
66
from TkinterDnD2 import *
7+
from idlelib.tooltip import Hovertip
8+
from pymediainfo import MediaInfo
79
from Packages.about import openaboutwindow
810
from configparser import ConfigParser
911

@@ -23,7 +25,7 @@ def root_exit_function(): # Asks if user wants to close main GUI + close all ta
2325

2426

2527
root = TkinterDnD.Tk() # Main GUI with TkinterDnD function (for drag and drop)
26-
root.title("HDR-Multi-Tool-Gui v1.3")
28+
root.title("HDR-Multi-Tool-Gui v1.32")
2729
root.iconphoto(True, PhotoImage(file="Runtime/Images/hdrgui.png"))
2830
root.configure(background="#434547")
2931
window_height = 400
@@ -60,11 +62,6 @@ def root_exit_function(): # Asks if user wants to close main GUI + close all ta
6062
if not config.has_option('dolbyvision_tool_path', 'path'):
6163
config.set('dolbyvision_tool_path', 'path', '')
6264

63-
if not config.has_section('mediainfocli_path'):
64-
config.add_section('mediainfocli_path')
65-
if not config.has_option('mediainfocli_path', 'path'):
66-
config.set('mediainfocli_path', 'path', '')
67-
6865
if not config.has_section('debug_option'):
6966
config.add_section('debug_option')
7067
if not config.has_option('debug_option', 'option'):
@@ -154,22 +151,6 @@ def set_dolbyvision_tool_path():
154151

155152
options_menu.add_command(label='Set "dovi_tool.exe" path', command=set_dolbyvision_tool_path)
156153

157-
158-
def set_mediainfocli_path():
159-
global mediainfocli
160-
path = filedialog.askopenfilename(title='Select Location to "MediaInfo.exe"', initialdir='/',
161-
filetypes=[('MediaInfo', 'MediaInfo.exe')])
162-
if path == '':
163-
pass
164-
elif path != '':
165-
mediainfocli = '"' + str(pathlib.Path(path)) + '"'
166-
config.set('mediainfocli_path', 'path', mediainfocli)
167-
with open(config_file, 'w') as configfile:
168-
config.write(configfile)
169-
170-
171-
options_menu.add_command(label='Set "MediaInfo.exe" path', command=set_mediainfocli_path)
172-
173154
options_menu.add_separator()
174155

175156

@@ -179,7 +160,7 @@ def reset_config():
179160
try:
180161
config.set('ffmpeg_path', 'path', '')
181162
config.set('hdr10plus_parser_path', 'path', '')
182-
config.set('mediainfocli_path', 'path', '')
163+
config.set('dolbyvision_tool_path', 'path', '')
183164
with open(config_file, 'w') as configfile:
184165
config.write(configfile)
185166
messagebox.showinfo(title='Prompt', message='Please restart the program')
@@ -198,7 +179,6 @@ def reset_config():
198179
# Bundled app path(s) -------------------------------------------------------------------------------------------------
199180
ffmpeg = config['ffmpeg_path']['path']
200181
hdr10plus_tool = config['hdr10plus_parser_path']['path']
201-
mediainfocli = config['mediainfocli_path']['path']
202182
dolbyvision_tool = config['dolbyvision_tool_path']['path']
203183

204184
if not pathlib.Path(ffmpeg.replace('"', '')).is_file(): # Checks config for bundled app paths path -------------------
@@ -211,12 +191,13 @@ def write_path_to_ffmpeg(): # Writes path to ffmpeg to the config.ini file
211191
except (Exception,):
212192
pass
213193

194+
214195
if shutil.which('ffmpeg') is not None:
215196
ffmpeg = '"' + str(pathlib.Path(shutil.which('ffmpeg'))).lower() + '"'
216197
messagebox.showinfo(title='Prompt!', message='ffmpeg.exe found on system PATH, '
217-
'automatically setting path to location.\n\n'
218-
'Note: This can be changed in the config.ini file'
219-
' or in the Options menu')
198+
'automatically setting path to location.\n\n '
199+
'Note: This can be changed in the config.ini file '
200+
'or in the Options menu')
220201
if pathlib.Path("Apps/ffmpeg/ffmpeg.exe").is_file():
221202
rem_ffmpeg = messagebox.askyesno(title='Delete Included ffmpeg?',
222203
message='Would you like to delete the included FFMPEG?')
@@ -232,23 +213,19 @@ def write_path_to_ffmpeg(): # Writes path to ffmpeg to the config.ini file
232213
ffmpeg = str(pathlib.Path("Apps/ffmpeg/ffmpeg.exe"))
233214
write_path_to_ffmpeg()
234215
else:
235-
error_prompt = messagebox.askyesno(title='Error!',
236-
message='Cannot find ffmpeg, '
237-
'please navigate to "ffmpeg.exe"')
216+
error_prompt = messagebox.askyesno(title='Error!', message='Cannot find ffmpeg, '
217+
'please navigate to "ffmpeg.exe"')
238218
if not error_prompt:
239-
messagebox.showerror(title='Error!',
240-
message='Program requires ffmpeg.exe to work correctly')
219+
messagebox.showerror(title='Error!', message='Program requires ffmpeg.exe to work correctly')
241220
root.destroy()
242221
if error_prompt:
243222
set_ffmpeg_path()
244223
if not pathlib.Path(ffmpeg).is_file():
245-
messagebox.showerror(title='Error!',
246-
message='Program requires ffmpeg.exe to work correctly')
224+
messagebox.showerror(title='Error!', message='Program requires ffmpeg.exe to work correctly')
247225
root.destroy()
248226

249227
# FFMPEG ------------------------------------------------------------------------------
250228

251-
252229
if not pathlib.Path(hdr10plus_tool.replace('"', '')).is_file(): # Checks config for bundled app paths path
253230
# HDR10plus_tool -----------------------------------------------------------------------
254231
if pathlib.Path('Apps/HDR10PlusTool/hdr10plus_tool.exe').is_file():
@@ -267,26 +244,6 @@ def write_path_to_ffmpeg(): # Writes path to ffmpeg to the config.ini file
267244
webbrowser.open('https://github.com/quietvoid/hdr10plus_tool/releases')
268245
# hdr10plus_tool -------------------------------------------------------
269246

270-
271-
if not pathlib.Path(mediainfocli.replace('"', '')).is_file(): # Checks config for bundled app paths path
272-
# mediainfocli -------------------------------------------------------------
273-
if pathlib.Path('Apps/MediaInfoCLI/MediaInfo.exe').is_file():
274-
messagebox.showinfo(title='Info', message='Program will use the included '
275-
'"MediaInfo.exe" located in the "Apps" folder')
276-
mediainfocli = '"' + str(pathlib.Path('Apps/MediaInfoCLI/MediaInfo.exe')) + '"'
277-
try:
278-
config.set('mediainfocli_path', 'path', mediainfocli)
279-
with open(config_file, 'w') as configfile:
280-
config.write(configfile)
281-
except (Exception,):
282-
pass
283-
elif not pathlib.Path('Apps/MediaInfoCLI/MediaInfo.exe').is_file():
284-
messagebox.showerror(title='Error!', message='Please download mediainfo.exe and set path to '
285-
'mediainfo.exe in the Options menu')
286-
webbrowser.open('https://mediaarea.net/download/binary/mediainfo/21.09/MediaInfo_CLI_21.09_Windows_x64.zip')
287-
# mediainfocli ----------------------------------------------------------
288-
289-
290247
# dolbyvision_tool --------------------------------------------------------
291248
if not pathlib.Path(dolbyvision_tool.replace('"', '')).is_file():
292249
if pathlib.Path('Apps/dovi_tool/dovi_tool.exe').is_file():
@@ -363,6 +320,7 @@ def write_path_to_ffmpeg(): # Writes path to ffmpeg to the config.ini file
363320
# HDR Parse Checkbutton -----------------------------------------------------------------------------------------------
364321
def hdr10plus_parse():
365322
dolbyvision_parse.set('off')
323+
start_button.configure(state=NORMAL)
366324

367325

368326
hdr_parse = StringVar()
@@ -379,6 +337,7 @@ def hdr10plus_parse():
379337
# Dolby Vision Checkbutton --------------------------------------------------------------------------------------------
380338
def dolby_parse():
381339
hdr_parse.set('off')
340+
start_button.configure(state=NORMAL)
382341

383342

384343
dolbyvision_parse = StringVar()
@@ -389,7 +348,6 @@ def dolby_parse():
389348
activeforeground="white", selectcolor="#434547", font=("Helvetica", 12))
390349
dolbyvision_parse.set('off')
391350

392-
393351
# -------------------------------------------------------------------------------------------- Dolby Vision Checkbutton
394352

395353
# Dolby Vision Crop Checkbutton ---------------------------------------------------------------------------------------
@@ -434,32 +392,47 @@ def dobly_vision_mode_menu_hover_leave(e):
434392

435393
# Input Button Functions ----------------------------------------------------------------------------------------------
436394
def check_for_hdr():
437-
hdr_format_mediainfocli = '"' + mediainfocli + " " + '"--Inform=Video;%HDR_Format/String%"' \
438-
+ " " + VideoInputQuoted + '"'
439395
try:
440-
mediainfo_duration = subprocess.Popen('cmd /c ' + hdr_format_mediainfocli,
441-
creationflags=subprocess.CREATE_NO_WINDOW,
442-
universal_newlines=True, stdout=subprocess.PIPE,
443-
stderr=subprocess.PIPE, stdin=subprocess.PIPE)
444-
stdout, stderr = mediainfo_duration.communicate()
445-
if 'HDR10+' in stdout:
446-
link_input_label.config(text=stdout.rstrip("\n"), anchor='center')
396+
mediainfo_hdr_parse = MediaInfo.parse(VideoInputQuoted.replace('"', ''))
397+
for track in mediainfo_hdr_parse.tracks:
398+
if track.track_type == "Video":
399+
hdr_format_string = ''.join(track.other_hdr_format)
400+
401+
if 'Dolby Vision' in hdr_format_string and 'HDR10+' in hdr_format_string: # Source is Dolby Vision and HDR10+
402+
messagebox.showinfo(title='Information', message='Source file has both Dolby Vision and HDR10+\n\n'
403+
'If you want to retain both HDR formats in your encode '
404+
'you will need to parse HDR10+ AND Dolby Vision '
405+
'separately to inject them into your encoder')
406+
link_input_label.config(text=hdr_format_string.rstrip("\n"), anchor=W)
407+
Hovertip(link_input_label, hdr_format_string.rstrip("\n"), hover_delay=600)
408+
elif 'HDR10+' in hdr_format_string: # If source only has HDR10+
409+
link_input_label.config(text=hdr_format_string.rstrip("\n"), anchor='center')
447410
hdr_tool_tabs.select(hdr_frame)
448411
hdr_parse.set('on')
449412
dolbyvision_parse.set('off')
450-
elif 'Dolby Vision' in stdout:
451-
link_input_label.config(text=stdout.rstrip("\n"), anchor=W)
413+
start_button.configure(state=NORMAL)
414+
Hovertip(link_input_label, hdr_format_string.rstrip("\n"), hover_delay=600)
415+
elif 'Dolby Vision' in hdr_format_string: # If source only has Dolby Vision
416+
link_input_label.config(text=hdr_format_string.rstrip("\n"), anchor=W)
452417
hdr_tool_tabs.select(dolby_frame)
453418
hdr_parse.set('off')
454419
dolbyvision_parse.set('on')
455-
else:
420+
start_button.configure(state=NORMAL)
421+
Hovertip(link_input_label, hdr_format_string.rstrip("\n"), hover_delay=600)
422+
else: # If source has no HDR
456423
link_input_label.config(text='No Parsing Needed', anchor='center')
457424
messagebox.showinfo(title="No Processing Needed", message="No need to parse anything other then an HDR10+"
458425
"or Dolby Vision file.\n\n If you see this in "
459426
"error please let me know on the github tracker "
460427
"with a sample of the source file.")
428+
Hovertip(link_input_label, 'No Parsing Needed', hover_delay=600)
461429
except (Exception,):
462-
pass
430+
messagebox.showerror(title='Error', message='Could not automatically detect HDR type, please post on the '
431+
'github tracker with a sample of the source file.\n\n'
432+
'Program can still parse without automatic detection, just '
433+
'select the proper HDR type from your file and start job.')
434+
webbrowser.open('https://github.com/jlw4049/HDR-Multi-Tool-Gui/issues')
435+
463436

464437
def input_button_commands():
465438
global VideoInput, autosavefilename, autofilesave_dir_path, VideoInputQuoted, VideoOutput
@@ -490,7 +463,6 @@ def input_button_commands():
490463
output_entry.insert(0, str(VideoOut))
491464
output_entry.configure(state=DISABLED)
492465
output_button.configure(state=NORMAL)
493-
start_button.configure(state=NORMAL)
494466
check_for_hdr()
495467
else:
496468
link_input_label.config(text='Please Open a Dolby Vision or HDR10+ compatible file', anchor='center')
@@ -538,7 +510,6 @@ def update_file_input(*args):
538510
output_entry.insert(0, str(VideoOut))
539511
output_entry.configure(state=DISABLED)
540512
output_button.configure(state=NORMAL)
541-
start_button.configure(state=NORMAL)
542513
check_for_hdr()
543514
else:
544515
link_input_label.config(text='Please Open a Dolby Vision or HDR10+ compatible file', anchor='center')
@@ -571,20 +542,12 @@ def start_job():
571542
VideoOutputQuoted = '"' + VideoOutput + '.bin"'
572543

573544
if shell_options.get() == "Default":
574-
global total_duration
575-
mediainfocli_cmd = '"' + mediainfocli + " " + '--Inform="General;%FileSize%"' \
576-
+ " " + VideoInputQuoted + '"'
577-
578545
try:
579-
mediainfo_duration = subprocess.Popen('cmd /c ' + mediainfocli_cmd,
580-
creationflags=subprocess.CREATE_NO_WINDOW,
581-
universal_newlines=True, stdout=subprocess.PIPE,
582-
stderr=subprocess.PIPE,
583-
stdin=subprocess.PIPE)
584-
stdout, stderr = mediainfo_duration.communicate()
585-
math = int(stdout) / 1000
586-
split = str(math)
587-
total_duration = split.rsplit('.', 1)[0]
546+
mediainfo_file_size = MediaInfo.parse(VideoInputQuoted.replace('"', ''))
547+
for track in mediainfo_file_size.tracks:
548+
if track.track_type == "General":
549+
total_file_size = track.file_size
550+
total_duration = str(int(total_file_size) / 1000).rsplit('.', 1)[0] # Compressed code for progress bars
588551
except (Exception,):
589552
pass
590553

@@ -634,7 +597,6 @@ def close_window():
634597
'-f hevc - -hide_banner -loglevel warning -stats|' \
635598
+ dolbyvision_tool + ' ' + dobly_vision_mode_choices[dobly_vision_mode.get()] \
636599
+ dolbyvision_crop.get() + ' extract-rpu - -o ' + str(VideoOutputQuoted) + '"'
637-
print(finalcommand)
638600
elif shell_options.get() == "Debug":
639601
finalcommand = '"' + ffmpeg + ' -analyzeduration 100M -probesize 50M -i ' + VideoInputQuoted \
640602
+ ' -map 0:v:0 -c:v:0 copy -vbsf hevc_mp4toannexb -f hevc - |' \

0 commit comments

Comments
 (0)