Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # This code is generated by ChatGPT 3.5
- # compile .exe by Pyinstaller
- #pyinstaller test.py --onefile --noconsole
- import tkinter
- import tkinter.font
- from tkinter import ttk
- import tkinter.filedialog
- import tkinter.simpledialog
- import configparser
- import subprocess
- import re
- import os
- import shutil
- import threading
- import winsound
- import time
- from smartcard.util import toHexString
- from smartcard.util import toBytes
- from smartcard.System import readers as get_readers
- # dumptsGUI.ini
- def read_ini():
- config = configparser.ConfigParser()
- config.read('dumptsGUI.ini')
- default_path = config.get('Paths', 'default_path', fallback='')
- mpc_hc_path = config.get('Paths', 'mpc_hc_path', fallback='')
- mkv_path = config.get('Paths', 'mkv_path', fallback='')
- return default_path, mpc_hc_path, mkv_path
- def write_ini(default_output_path, mpc_hc_path, mkv_path):
- config = configparser.ConfigParser()
- config['Paths'] = {'default_path': default_output_path,
- 'mpc_hc_path': mpc_hc_path,
- 'mkv_path': mkv_path}
- with open('dumptsGUI.ini', 'w') as configfile:
- config.write(configfile)
- def sanitize_filename(filename):
- # 許可する文字:英数字、ハイフン、アンダースコア、ドット、ひらがな、カタカナ、漢字、全角スペース、全角英字数字、全角カッコ、全角カギカッコ
- allowed_chars = re.compile(r'[^a-zA-Z0-9._\-\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FFF\u3000\uFF10-\uFF19\uFF08\uFF09\u300C\u300D\uFF21-\uFF3A\uFF41-\uFF5A]')
- sanitized_name = allowed_chars.sub('_', filename)
- return sanitized_name
- def rename_files_in_directory(directory, filename):
- sanitized_name = sanitize_filename(filename)
- old_path = filename
- new_path = sanitized_name
- if old_path != new_path:
- os.rename(os.path.join(directory, old_path), os.path.join(directory, new_path))
- label4['text'] =f'Rename(expand): {filename} -> {sanitized_name}'
- else:
- label4['text'] =f'No change needed: {filename}'
- return new_path
- # Program START
- if not os.path.exists('dumptsGUI.ini'):
- write_ini('', '', '')
- # Load paths from ini file
- default_path, mpc_hc_path, mkv_path = read_ini()
- readers = get_readers()
- print(readers)
- # Main window
- main_win = tkinter.Tk()
- main_win.title("DumpTS GUI, code generated by ChatGPT")
- main_win.geometry("700x380")
- # Main frame
- main_frm = ttk.Frame(main_win)
- main_frm.grid(column=0, row=0, sticky=tkinter.NSEW, padx=5, pady=10)
- if len(readers)!=0:
- conn = readers[0].createConnection()
- try:
- conn.connect()
- recv_data=conn.getATR()
- print(toHexString(recv_data))
- # widget line 1
- label1 = ttk.Label(main_frm,text=readers, foreground='orange', background='black')
- # widget line 2
- label2 = ttk.Label(main_frm,text=toHexString(recv_data), foreground='orange', background='black')
- if toHexString(recv_data[:4]) == '3B F0 13 00':
- # 4バイトが一致する場合の処理
- label2 ['text']= toHexString(recv_data)
- pass
- else:
- label2 ['text']= "Error: Confirm/Re-insert IC card"
- except:
- print('No card')
- label1 = ttk.Label(main_frm,text='No card', foreground='red', background='black')
- label2 = ttk.Label(main_frm,text=' ', foreground='orange', background='black')
- else:
- label1 = ttk.Label(main_frm,text='No IC readers', foreground='red', background='black')
- label2 = ttk.Label(main_frm,text=' ', foreground='orange', background='black')
- def btnReconnect_click():
- global readers,conn
- readers = get_readers()
- conn = readers[0].createConnection()
- conn.connect()
- recv_data=conn.getATR()
- label1 ['text'] =readers
- if toHexString(recv_data[:4]) == '3B F0 13 00':
- # 4バイトが一致する場合の処理
- label2 ['text']= toHexString(recv_data)
- pass
- else:
- label2 ['text']= "Error: Confirm/Re-insert IC card"
- main_win.mainloop()
- def select_file_and_run():
- global selected_file, AACmatches, HEVCmatches
- # ファイル選択ダイアログを表示し、ユーザからファイル名を取得
- selected_file = tkinter.filedialog.askopenfilename()
- directory = os.path.dirname(selected_file)
- if selected_file:
- selected_filename =rename_files_in_directory(directory, os.path.basename(selected_file) )
- selected_file= os.path.join(directory, selected_filename)
- # 選択されたファイル名とファイルパスを表示
- label_selected_file['text'] = f"Selected File: {selected_filename}\nFile Path: {selected_file}"
- # Dumpts.exeを実行し、選択されたファイル名を引数に渡す
- result = subprocess.run(["Dumpts.exe", selected_file, "--MAXMB=100", "--CID=1", "--showinfo"], stdout=subprocess.PIPE)
- if result.stdout is not None:
- # 出力を取得して処理する
- output_lines = result.stdout.decode('utf-8').splitlines()
- last_25_lines = '\n'.join(output_lines[-26:])
- label5['text'] = last_25_lines
- # パターンにマッチする部分を検索
- pattern = r"CID: (0x[0-9A-F]+), packet_id: (0x[0-9A-F]+).*HEVC Video Stream"
- HEVCmatches = re.findall(pattern, last_25_lines)
- cid, packet_id = HEVCmatches[0]
- label5['text'] = f"HEVC Video Stream: CID: {cid}, packet_id: {packet_id}\n"
- pattern = r"CID: (0x[0-9A-F]+), packet_id: (0x[0-9A-F]+).*MPEG-4 AAC Audio Stream"
- AACmatches = re.findall(pattern, last_25_lines)
- for match in AACmatches:
- cid, packet_id = match[0], match[1]
- label5['text'] += f"MPEG-4 AAC Audio Stream: CID: {cid}, packet_id: {packet_id}\n"
- else:
- label5['text'] = "Error: Unable to retrieve output from Dumpts.exe"
- def btnGetKey_click():
- global selected_file, AACmatches, HEVCmatches
- result = subprocess.run(["Dumpts.exe", "8k.mmts", "--MAXMB=100", "--CID=1", "--showinfo"], stdout=subprocess.PIPE)
- if result.stdout is not None:
- output_lines = result.stdout.decode('utf-8').splitlines() # バイナリデータをUTF-8でデコードして行に分割
- last_25_lines = '\n'.join(output_lines[-26:]) # 最後の25行を取得
- label5['text'] = last_25_lines
- # パターンにマッチする部分を検索
- # テキストからCIDとpacket_idを抽出する正規表現パターン
- pattern = r"CID: (0x[0-9A-F]+), packet_id: (0x[0-9A-F]+).*HEVC Video Stream"
- # 正規表現パターンにマッチする全てのCIDとpacket_idのペアを抽出
- HEVCmatches = re.findall(pattern, last_25_lines)
- # HEVC Video StreamとMPEG-4 AAC Audio StreamのCIDとpacket_idの値を取得
- cid, packet_id = HEVCmatches[0]
- print(f"HEVC Video Stream: CID: {cid}, packet_id: {packet_id}")
- pattern = r"CID: (0x[0-9A-F]+), packet_id: (0x[0-9A-F]+).*MPEG-4 AAC Audio Stream"
- # 正規表現パターンにマッチする全てのCIDとpacket_idのペアを抽出
- AACmatches = re.findall(pattern, last_25_lines)
- for match in AACmatches:
- cid, packet_id = match[0], match[1]
- print(f"MPEG-4 AAC Audio Stream: CID: {cid}, packet_id: {packet_id}")
- else:
- label5['text'] = "Error: Unable to retrieve output from AA.exe"
- main_win.mainloop()
- def btnWriteID_click():
- global AACmatches, HEVCmatches,output_filename, default_path, mpc_hc_path
- # 選択されたファイルがない場合は処理を中止
- if not selected_file:
- label5['text'] = "Error: No file selected"
- return
- # プログラムの実行場所を取得
- current_directory = os.getcwd()
- # デフォルトのパスを使用するか、iniファイルから読み込んだパスを使用するかを決定する
- current_directory = default_path if default_path else current_directory
- default_output_path = os.path.join(current_directory, f"out_{os.path.basename(selected_file)}")
- # ファイル名の入力を取得
- output_filename = default_output_path#tkinter.simpledialog.askstring("Input", "Enter the output filename:", initialvalue=default_output_path)
- if not output_filename:
- label5['text'] = "Error: No output filename entered"
- return
- # mmtsファイルの頭の〇〇MBをSkipして処理する。デフォルト値は0 MB
- input_value = numeric_input.get()
- if input_value.strip(): # 空でない文字列であるかどうかを確認
- skip_bytes = int(input_value)
- else:
- # エラー処理またはデフォルト値の設定などを行う
- skip_bytes = int(0) # 例えば、デフォルト値として0を設定
- # Dumpts.exe 実行のためのパケット ID リストを初期化
- packet_ids = []
- # HEVC パケット ID を取得
- for cid, packet_id in HEVCmatches:
- packet_ids.append(packet_id)
- # AAC パケット ID を取得
- for cid, packet_id in AACmatches:
- packet_ids.append(packet_id)
- # パケット ID を & でつなげる
- packet_ids_str = "&".join(packet_ids)
- process = subprocess.Popen(["Dumpts.exe", selected_file, f"--SKIPMB={skip_bytes}", f"--CID={cid}", f"--pid={packet_ids_str}", f"--output={output_filename}"], stdout=subprocess.PIPE)
- label4['text'] = "DumpTS.exe is running..."
- # パスをiniファイルに保存
- write_ini(current_directory, mpc_hc_path)
- # ファイルサイズの変化をチェックするスレッドを開始
- check_size_thread = threading.Thread(target=check_file_size)
- check_size_thread.start()
- def check_file_size():
- global output_filename, HEVCmatches
- output_filename_without_extension = output_filename.rsplit('.', 1)[0]
- # 映像ファイルのパスを生成
- video_file_path = f"{output_filename_without_extension}_{HEVCmatches[0][1]}.{output_filename.rsplit('.', 1)[1]}"
- time.sleep(10)
- # 初期のファイルサイズを取得
- initial_size = os.path.getsize(video_file_path)
- while True:
- # 10秒待機
- time.sleep(10)
- # 現在のファイルサイズを取得
- current_size = os.path.getsize(video_file_path)
- # ファイルサイズが変化しなくなった場合
- if current_size == initial_size:
- # "DumpTS.exe Completed"とラベルを更新
- label4['text'] = "DumpTS.exe Completed"
- # 効果音を鳴らす
- winsound.PlaySound("SystemExit", winsound.SND_ALIAS)
- break
- else:
- initial_size =current_size
- def playFile_click():
- global output_filename, HEVCmatches, AACmatches, default_path, mpc_hc_path
- if output_filename and HEVCmatches and AACmatches:
- try:
- output_filename_without_extension = output_filename.rsplit('.', 1)[0]
- # 映像ファイルのパスを生成
- video_file_path = f"{output_filename_without_extension}_{HEVCmatches[0][1]}.{output_filename.rsplit('.', 1)[1]}"
- # 音声ファイルのパスを生成(AACmatchesの2つ目のパケットIDを使用)
- original_audio_file_path = f"{output_filename_without_extension}_{AACmatches[0][1]}.{output_filename.rsplit('.', 1)[1]}"
- #renamed_audio_file_path = f"{output_filename_without_extension}_{AACmatches[0][1]}.dts"
- #shutil.copyfile(original_audio_file_path, renamed_audio_file_path)
- mpc_hc_path_ini=mpc_hc_path
- # mpc-hc64.exe のパスを取得
- mpc_hc_path = "C:\\Program Files\\MPC-HC\\mpc-hc64.exe"
- # デフォルトのパスを使用するか、iniファイルから読み込んだパスを使用するかを決定する
- mpc_hc_path = mpc_hc_path_ini if mpc_hc_path_ini else mpc_hc_path
- # mpc-hc64.exe を実行し、映像ファイルと音声ファイルのパスを引数として渡す
- subprocess.Popen([mpc_hc_path, video_file_path])#subprocess.run([mpc_hc_path, video_file_path, f"/dub \"{renamed_audio_file_path}\""])
- #subprocess.Popen([mpc_hc_path, original_audio_file_path ])
- # 実行成功時のメッセージを表示
- play_file_label['text'] = "MPC-HC has been executed successfully"
- mpc_hc_path_label['text'] = f"MPC-HC Location: {mpc_hc_path}"
- except FileNotFoundError:
- # ファイルが見つからない場合のエラーメッセージを表示
- play_file_label['text'] = "Error: MPC-HC not found"
- else:
- # 必要なファイルやマッチが見つからない場合のエラーメッセージを表示
- play_file_label['text'] = "Error: Missing output filename or matches"
- mpc_hc_path_label['text'] = ""
- def launch_mkv_tool():
- global mkv_path
- mkv_path_ini=mkv_path
- mkv_path = "C:\\Program Files\\MKVToolNix\\mkvtoolnix-gui.exe"
- mkv_path = mkv_path_ini if mkv_path_ini else mkv_path
- mkv_path_label.config(text=mkv_path)
- subprocess.Popen([mkv_path])
- mkv_path_label = ttk.Label(main_frm, text='', foreground='white', background='black')
- mkv_path_label.grid(column=1, row=7, sticky=tkinter.EW, padx=5)
- # ファイル処理ボタンの作成
- button_process_files_to_mkv = ttk.Button(main_frm, text="Launch MKVtoolnix", command=launch_mkv_tool)
- button_process_files_to_mkv.grid(column=0, row=7, pady=10)
- mpc_hc_path_label= ttk.Label(main_frm, text='', foreground='white', background='black')
- mpc_hc_path_label.grid(column=1, row=6, sticky=tkinter.EW, padx=5)
- button_play_file = ttk.Button(main_frm, text="Play File", command=playFile_click)
- button_play_file.grid(column=0, row=5, pady=10)
- play_file_label= ttk.Label(main_frm, text='', foreground='white', background='black')
- play_file_label.grid(column=1, row=5, sticky=tkinter.EW, padx=5)
- # ファイル選択ボタンの作成
- button_select_file = ttk.Button(main_frm, text="Select File", command=select_file_and_run)
- button_select_file.grid(column=0, row=2, pady=10)
- # 選択されたファイルを表示するラベルの作成
- label_selected_file = ttk.Label(main_frm, text='', foreground='white', background='black')
- label_selected_file.grid(column=1, row=2, sticky=tkinter.EW, padx=5)
- # widget line 4
- label5 = ttk.Label(main_frm, text='', foreground='white', background='black')
- # widget line 1
- label3 = ttk.Label(main_frm,text='Card Reader')
- # widget line 2
- buttonA = ttk.Button(
- main_frm, text = 'Re-analyze file', command=btnGetKey_click)
- # widget line 3
- buttonB = ttk.Button(
- main_frm, text = 'DumpTS', command=btnWriteID_click)
- # widget line 3
- label4 = ttk.Label(main_frm, text='Select mmts file, then click DumpTS', foreground='white', background='black')
- # widget line 4
- buttonC = ttk.Button(
- main_frm, text = 'Connect IC card', command=btnReconnect_click)
- label3.grid(column=0, row=0, pady=10)
- label1.grid(column=1, row=0, sticky=tkinter.EW, padx=5)
- buttonA.grid(column=0, row=4)
- label2.grid(column=1, row=1, sticky=tkinter.EW, padx=5)
- buttonB.grid(column=0, row=3, pady=10)
- label4.grid(column=1, row=3, sticky=tkinter.EW, padx=5)
- buttonC.grid(column=0, row=1, pady=10)
- label5.grid(column=1, row=4, sticky=tkinter.EW, padx=5)
- # 数値入力フィールドを追加
- label_numeric_input = ttk.Label(main_frm, text="(MB, Option):SKIP the first XXXMB of mmts file, if file can't play")
- label_numeric_input.grid(column=1, row=8, sticky=tkinter.EW, padx=5)
- numeric_input = ttk.Spinbox(main_frm, from_=0, to=10000)
- numeric_input.grid(column=0, row=8, pady=10)
- # place settings
- main_win.columnconfigure(0, weight=1)
- main_win.rowconfigure(0, weight=1)
- main_frm.columnconfigure(1, weight=1)
- main_win.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment