Guest User

Untitled

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