Guest User

Untitled

a guest
May 24th, 2024
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.82 KB | Source Code | 0 0
  1. # This code is generated by ChatGPT 3.5
  2. # compile .exe by Pyinstaller
  3. #pyinstaller test.py --onefile --noconsole
  4. import tkinter
  5. import tkinter.font
  6. from tkinter import ttk
  7. import tkinter.filedialog
  8. import tkinter.simpledialog
  9.  
  10. import configparser
  11. import subprocess
  12. import re
  13. import os
  14. import shutil
  15. import threading
  16. import winsound
  17. import time
  18. from smartcard.util import toHexString
  19. from smartcard.util import toBytes
  20. from smartcard.System import readers as get_readers
  21.  
  22. # dumptsGUI.ini
  23. def read_ini():
  24. config = configparser.ConfigParser()
  25. config.read('dumptsGUI.ini')
  26. default_path = config.get('Paths', 'default_path', fallback='')
  27. mpc_hc_path = config.get('Paths', 'mpc_hc_path', fallback='')
  28. return default_path, mpc_hc_path
  29.  
  30. def write_ini(default_output_path, mpc_hc_path):
  31. config = configparser.ConfigParser()
  32. config['Paths'] = {'default_path': default_output_path,
  33. 'mpc_hc_path': mpc_hc_path}
  34. with open('dumptsGUI.ini', 'w') as configfile:
  35. config.write(configfile)
  36.  
  37. def sanitize_filename(filename):
  38. # 許可する文字:英数字、ハイフン、アンダースコア、ドット、ひらがな、カタカナ、漢字、全角スペース、全角英字数字、全角カッコ、全角カギカッコ
  39. 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]')
  40. sanitized_name = allowed_chars.sub('_', filename)
  41. return sanitized_name
  42. def rename_files_in_directory(directory, filename):
  43. sanitized_name = sanitize_filename(filename)
  44. old_path = filename
  45. new_path = sanitized_name
  46. if old_path != new_path:
  47. os.rename(os.path.join(directory, old_path), os.path.join(directory, new_path))
  48. label4['text'] =f'Rename(expand): {filename} -> {sanitized_name}'
  49. else:
  50. label4['text'] =f'No change needed: {filename}'
  51. return new_path
  52.  
  53. # Program START
  54. if not os.path.exists('dumptsGUI.ini'):
  55. write_ini('', '')
  56. # Load paths from ini file
  57. default_path, mpc_hc_path = read_ini()
  58.  
  59. readers = get_readers()
  60. print(readers)
  61.  
  62. # Main window
  63. main_win = tkinter.Tk()
  64. main_win.title("DumpTS GUI, code generated by ChatGPT")
  65. main_win.geometry("700x350")
  66.  
  67. # Main frame
  68. main_frm = ttk.Frame(main_win)
  69. main_frm.grid(column=0, row=0, sticky=tkinter.NSEW, padx=5, pady=10)
  70.  
  71. if len(readers)!=0:
  72. conn = readers[0].createConnection()
  73. try:
  74. conn.connect()
  75. recv_data=conn.getATR()
  76. print(toHexString(recv_data))
  77.  
  78. # widget line 1
  79. label1 = ttk.Label(main_frm,text=readers, foreground='orange', background='black')
  80.  
  81.  
  82. # widget line 2
  83. label2 = ttk.Label(main_frm,text=toHexString(recv_data), foreground='orange', background='black')
  84.  
  85. if toHexString(recv_data[:4]) == '3B F0 13 00':
  86. # 4バイトが一致する場合の処理
  87. label2 ['text']= toHexString(recv_data)
  88. pass
  89. else:
  90. label2 ['text']= "Error: Confirm/Re-insert IC card"
  91. except:
  92. print('No card')
  93. label1 = ttk.Label(main_frm,text='No card', foreground='red', background='black')
  94. label2 = ttk.Label(main_frm,text=' ', foreground='orange', background='black')
  95.  
  96. else:
  97. label1 = ttk.Label(main_frm,text='No IC readers', foreground='red', background='black')
  98. label2 = ttk.Label(main_frm,text=' ', foreground='orange', background='black')
  99.  
  100.  
  101.  
  102. def btnReconnect_click():
  103. global readers,conn
  104. readers = get_readers()
  105. conn = readers[0].createConnection()
  106. conn.connect()
  107. recv_data=conn.getATR()
  108. label1 ['text'] =readers
  109. if toHexString(recv_data[:4]) == '3B F0 13 00':
  110. # 4バイトが一致する場合の処理
  111. label2 ['text']= toHexString(recv_data)
  112. pass
  113. else:
  114. label2 ['text']= "Error: Confirm/Re-insert IC card"
  115. main_win.mainloop()
  116.  
  117. def select_file_and_run():
  118. global selected_file, AACmatches, HEVCmatches
  119. # ファイル選択ダイアログを表示し、ユーザからファイル名を取得
  120. selected_file = tkinter.filedialog.askopenfilename()
  121. directory = os.path.dirname(selected_file)
  122. if selected_file:
  123. selected_filename =rename_files_in_directory(directory, os.path.basename(selected_file) )
  124. selected_file= os.path.join(directory, selected_filename)
  125. # 選択されたファイル名とファイルパスを表示
  126. label_selected_file['text'] = f"Selected File: {selected_filename}\nFile Path: {selected_file}"
  127.  
  128. # Dumpts.exeを実行し、選択されたファイル名を引数に渡す
  129. result = subprocess.run(["Dumpts.exe", selected_file, "--MAXMB=100", "--CID=1", "--showinfo"], stdout=subprocess.PIPE)
  130.  
  131. if result.stdout is not None:
  132. # 出力を取得して処理する
  133. output_lines = result.stdout.decode('utf-8').splitlines()
  134. last_25_lines = '\n'.join(output_lines[-26:])
  135. label5['text'] = last_25_lines
  136.  
  137. # パターンにマッチする部分を検索
  138. pattern = r"CID: (0x[0-9A-F]+), packet_id: (0x[0-9A-F]+).*HEVC Video Stream"
  139. HEVCmatches = re.findall(pattern, last_25_lines)
  140. cid, packet_id = HEVCmatches[0]
  141. label5['text'] = f"HEVC Video Stream: CID: {cid}, packet_id: {packet_id}\n"
  142.  
  143. pattern = r"CID: (0x[0-9A-F]+), packet_id: (0x[0-9A-F]+).*MPEG-4 AAC Audio Stream"
  144. AACmatches = re.findall(pattern, last_25_lines)
  145. for match in AACmatches:
  146. cid, packet_id = match[0], match[1]
  147. label5['text'] += f"MPEG-4 AAC Audio Stream: CID: {cid}, packet_id: {packet_id}\n"
  148. else:
  149. label5['text'] = "Error: Unable to retrieve output from Dumpts.exe"
  150.  
  151. def btnGetKey_click():
  152. global selected_file, AACmatches, HEVCmatches
  153. result = subprocess.run(["Dumpts.exe", "8k.mmts", "--MAXMB=100", "--CID=1", "--showinfo"], stdout=subprocess.PIPE)
  154.  
  155. if result.stdout is not None:
  156. output_lines = result.stdout.decode('utf-8').splitlines() # バイナリデータをUTF-8でデコードして行に分割
  157. last_25_lines = '\n'.join(output_lines[-26:]) # 最後の25行を取得
  158. label5['text'] = last_25_lines
  159. # パターンにマッチする部分を検索
  160. # テキストからCIDとpacket_idを抽出する正規表現パターン
  161. pattern = r"CID: (0x[0-9A-F]+), packet_id: (0x[0-9A-F]+).*HEVC Video Stream"
  162. # 正規表現パターンにマッチする全てのCIDとpacket_idのペアを抽出
  163. HEVCmatches = re.findall(pattern, last_25_lines)
  164. # HEVC Video StreamとMPEG-4 AAC Audio StreamのCIDとpacket_idの値を取得
  165. cid, packet_id = HEVCmatches[0]
  166. print(f"HEVC Video Stream: CID: {cid}, packet_id: {packet_id}")
  167. pattern = r"CID: (0x[0-9A-F]+), packet_id: (0x[0-9A-F]+).*MPEG-4 AAC Audio Stream"
  168. # 正規表現パターンにマッチする全てのCIDとpacket_idのペアを抽出
  169. AACmatches = re.findall(pattern, last_25_lines)
  170. for match in AACmatches:
  171. cid, packet_id = match[0], match[1]
  172. print(f"MPEG-4 AAC Audio Stream: CID: {cid}, packet_id: {packet_id}")
  173.  
  174.  
  175. else:
  176. label5['text'] = "Error: Unable to retrieve output from AA.exe"
  177. main_win.mainloop()
  178.  
  179. def btnWriteID_click():
  180. global AACmatches, HEVCmatches,output_filename, default_path, mpc_hc_path
  181.  
  182. # 選択されたファイルがない場合は処理を中止
  183. if not selected_file:
  184. label5['text'] = "Error: No file selected"
  185. return
  186. # プログラムの実行場所を取得
  187. current_directory = os.getcwd()
  188. # デフォルトのパスを使用するか、iniファイルから読み込んだパスを使用するかを決定する
  189. current_directory = default_path if default_path else current_directory
  190. default_output_path = os.path.join(current_directory, f"out_{os.path.basename(selected_file)}")
  191. # ファイル名の入力を取得
  192. output_filename = default_output_path#tkinter.simpledialog.askstring("Input", "Enter the output filename:", initialvalue=default_output_path)
  193. if not output_filename:
  194. label5['text'] = "Error: No output filename entered"
  195. return
  196.  
  197. # Dumpts.exe 実行のためのパケット ID リストを初期化
  198. packet_ids = []
  199.  
  200. # HEVC パケット ID を取得
  201. for cid, packet_id in HEVCmatches:
  202. packet_ids.append(packet_id)
  203.  
  204. # AAC パケット ID を取得
  205. for cid, packet_id in AACmatches:
  206. packet_ids.append(packet_id)
  207. # パケット ID を & でつなげる
  208. packet_ids_str = "&".join(packet_ids)
  209.  
  210. process = subprocess.Popen(["Dumpts.exe", selected_file, f"--CID={cid}", f"--pid={packet_ids_str}", f"--output={output_filename}"], stdout=subprocess.PIPE)
  211. label4['text'] = "DumpTS.exe is running..."
  212.  
  213. # パスをiniファイルに保存
  214. write_ini(current_directory, mpc_hc_path)
  215.  
  216. # ファイルサイズの変化をチェックするスレッドを開始
  217. check_size_thread = threading.Thread(target=check_file_size)
  218. check_size_thread.start()
  219.  
  220. def check_file_size():
  221. global output_filename, HEVCmatches
  222. output_filename_without_extension = output_filename.rsplit('.', 1)[0]
  223. # 映像ファイルのパスを生成
  224. video_file_path = f"{output_filename_without_extension}_{HEVCmatches[0][1]}.{output_filename.rsplit('.', 1)[1]}"
  225. time.sleep(10)
  226. # 初期のファイルサイズを取得
  227. initial_size = os.path.getsize(video_file_path)
  228.  
  229. while True:
  230. # 10秒待機
  231. time.sleep(10)
  232. # 現在のファイルサイズを取得
  233. current_size = os.path.getsize(video_file_path)
  234. # ファイルサイズが変化しなくなった場合
  235. if current_size == initial_size:
  236. # "DumpTS.exe Completed"とラベルを更新
  237. label4['text'] = "DumpTS.exe Completed"
  238. # 効果音を鳴らす
  239. winsound.PlaySound("SystemExit", winsound.SND_ALIAS)
  240. break
  241. else:
  242. initial_size =current_size
  243.  
  244.  
  245. def playFile_click():
  246. global output_filename, HEVCmatches, AACmatches, default_path, mpc_hc_path
  247. if output_filename and HEVCmatches and AACmatches:
  248. try:
  249. output_filename_without_extension = output_filename.rsplit('.', 1)[0]
  250. # 映像ファイルのパスを生成
  251. video_file_path = f"{output_filename_without_extension}_{HEVCmatches[0][1]}.{output_filename.rsplit('.', 1)[1]}"
  252.  
  253. # 音声ファイルのパスを生成(AACmatchesの2つ目のパケットIDを使用)
  254. original_audio_file_path = f"{output_filename_without_extension}_{AACmatches[0][1]}.{output_filename.rsplit('.', 1)[1]}"
  255. renamed_audio_file_path = f"{output_filename_without_extension}_{AACmatches[0][1]}.dts"
  256. #shutil.copyfile(original_audio_file_path, renamed_audio_file_path)
  257. mpc_hc_path_ini=mpc_hc_path
  258. # mpc-hc64.exe のパスを取得
  259. mpc_hc_path = "C:\\Program Files\\MPC-HC\\mpc-hc64.exe"
  260. # デフォルトのパスを使用するか、iniファイルから読み込んだパスを使用するかを決定する
  261. mpc_hc_path = mpc_hc_path_ini if mpc_hc_path_ini else mpc_hc_path
  262.  
  263. # mpc-hc64.exe を実行し、映像ファイルと音声ファイルのパスを引数として渡す
  264. subprocess.Popen([mpc_hc_path, video_file_path])#subprocess.run([mpc_hc_path, video_file_path, f"/dub \"{renamed_audio_file_path}\""])
  265.  
  266. # 実行成功時のメッセージを表示
  267. play_file_label['text'] = "MPC-HC has been executed successfully"
  268. mpc_hc_path_label['text'] = f"MPC-HC Location: {mpc_hc_path}"
  269. except FileNotFoundError:
  270. # ファイルが見つからない場合のエラーメッセージを表示
  271. play_file_label['text'] = "Error: MPC-HC not found"
  272. else:
  273. # 必要なファイルやマッチが見つからない場合のエラーメッセージを表示
  274. play_file_label['text'] = "Error: Missing output filename or matches"
  275. mpc_hc_path_label['text'] = ""
  276.  
  277. mpc_hc_path_label= ttk.Label(main_frm, text='', foreground='white', background='black')
  278. mpc_hc_path_label.grid(column=1, row=6, sticky=tkinter.EW, padx=5)
  279. button_play_file = ttk.Button(main_frm, text="Play File", command=playFile_click)
  280. button_play_file.grid(column=0, row=5, pady=10)
  281. play_file_label= ttk.Label(main_frm, text='', foreground='white', background='black')
  282. play_file_label.grid(column=1, row=5, sticky=tkinter.EW, padx=5)
  283. # ファイル選択ボタンの作成
  284. button_select_file = ttk.Button(main_frm, text="Select File", command=select_file_and_run)
  285. button_select_file.grid(column=0, row=2, pady=10)
  286. # 選択されたファイルを表示するラベルの作成
  287. label_selected_file = ttk.Label(main_frm, text='', foreground='white', background='black')
  288. label_selected_file.grid(column=1, row=2, sticky=tkinter.EW, padx=5)
  289. # widget line 4
  290. label5 = ttk.Label(main_frm, text='', foreground='white', background='black')
  291.  
  292. # widget line 1
  293. label3 = ttk.Label(main_frm,text='Card Reader')
  294.  
  295. # widget line 2
  296. buttonA = ttk.Button(
  297. main_frm, text = 'Re-analyze file', command=btnGetKey_click)
  298.  
  299. # widget line 3
  300. buttonB = ttk.Button(
  301. main_frm, text = 'DumpTS', command=btnWriteID_click)
  302.  
  303. # widget line 3
  304. label4 = ttk.Label(main_frm, text='Select mmts file, then click DumpTS', foreground='white', background='black')
  305.  
  306. # widget line 4
  307. buttonC = ttk.Button(
  308. main_frm, text = 'Connect IC card', command=btnReconnect_click)
  309.  
  310.  
  311. label3.grid(column=0, row=0, pady=10)
  312. label1.grid(column=1, row=0, sticky=tkinter.EW, padx=5)
  313. buttonA.grid(column=0, row=4)
  314. label2.grid(column=1, row=1, sticky=tkinter.EW, padx=5)
  315. buttonB.grid(column=0, row=3, pady=10)
  316. label4.grid(column=1, row=3, sticky=tkinter.EW, padx=5)
  317. buttonC.grid(column=0, row=1, pady=10)
  318. label5.grid(column=1, row=4, sticky=tkinter.EW, padx=5)
  319.  
  320. # place settings
  321. main_win.columnconfigure(0, weight=1)
  322. main_win.rowconfigure(0, weight=1)
  323. main_frm.columnconfigure(1, weight=1)
  324. main_win.mainloop()
  325.  
  326.  
  327.  
Advertisement
Add Comment
Please, Sign In to add comment