44import tkinter as tk
55import pathlib , subprocess , shutil , threading , webbrowser
66from TkinterDnD2 import *
7+ from idlelib .tooltip import Hovertip
8+ from pymediainfo import MediaInfo
79from Packages .about import openaboutwindow
810from 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
2527root = 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 " )
2729root .iconphoto (True , PhotoImage (file = "Runtime/Images/hdrgui.png" ))
2830root .configure (background = "#434547" )
2931window_height = 400
@@ -60,11 +62,6 @@ def root_exit_function(): # Asks if user wants to close main GUI + close all ta
6062if 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-
6865if not config .has_section ('debug_option' ):
6966 config .add_section ('debug_option' )
7067if not config .has_option ('debug_option' , 'option' ):
@@ -154,22 +151,6 @@ def set_dolbyvision_tool_path():
154151
155152options_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-
173154options_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) -------------------------------------------------------------------------------------------------
199180ffmpeg = config ['ffmpeg_path' ]['path' ]
200181hdr10plus_tool = config ['hdr10plus_parser_path' ]['path' ]
201- mediainfocli = config ['mediainfocli_path' ]['path' ]
202182dolbyvision_tool = config ['dolbyvision_tool_path' ]['path' ]
203183
204184if 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-
252229if 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 --------------------------------------------------------
291248if 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 -----------------------------------------------------------------------------------------------
364321def hdr10plus_parse ():
365322 dolbyvision_parse .set ('off' )
323+ start_button .configure (state = NORMAL )
366324
367325
368326hdr_parse = StringVar ()
@@ -379,6 +337,7 @@ def hdr10plus_parse():
379337# Dolby Vision Checkbutton --------------------------------------------------------------------------------------------
380338def dolby_parse ():
381339 hdr_parse .set ('off' )
340+ start_button .configure (state = NORMAL )
382341
383342
384343dolbyvision_parse = StringVar ()
@@ -389,7 +348,6 @@ def dolby_parse():
389348 activeforeground = "white" , selectcolor = "#434547" , font = ("Helvetica" , 12 ))
390349dolbyvision_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 ----------------------------------------------------------------------------------------------
436394def 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
464437def 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