concatGOPRO.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import os
  2. import shutil
  3. import sys
  4. try:
  5. import PySimpleGUI as sg
  6. except ImportError:
  7. print("Looks like you don't have PySimpleGUI installed, do you want me to install for you?\nyes/no")
  8. yes_or_no = input()
  9. yes_set = {'yes', 'YES', 'Y', 'y', 'Yes'}
  10. if yes_or_no in yes_set:
  11. os.system('pip install pysimplegui')
  12. else:
  13. raise ImportWarning('No PySimpleGUI package found')
  14. def get_video_list(dir: str):
  15. all_videos = dict()
  16. video_formats = {"mp4", "MP4"}
  17. all_files = os.listdir(dir)
  18. for file_name in all_files:
  19. try:
  20. isG = file_name[0]
  21. code_type = file_name[1]
  22. ext_name = file_name[-3:]
  23. # video_chapter = file_name[2:4]
  24. video_idx = file_name[4:8]
  25. except IndexError:
  26. continue
  27. # GoPro files start with "G"
  28. if isG == 'G' and ext_name in video_formats:
  29. try:
  30. all_videos[video_idx][0].append(file_name)
  31. except KeyError:
  32. all_videos[video_idx] = [[file_name], code_type]
  33. # sort the chapters
  34. for video in all_videos.keys():
  35. all_videos[video][0] = sorted(all_videos[video][0])
  36. return all_videos
  37. def path_validation(source_dir, output_dir):
  38. if not os.path.isdir(source_dir):
  39. return False
  40. if not os.path.isdir(output_dir):
  41. try:
  42. os.mkdir(output_dir)
  43. except:
  44. raise OSError("Faild to create the output folder.")
  45. return True
  46. def do_the_job(source_dir, output_dir):
  47. if path_validation(source_dir, output_dir):
  48. os.chdir(input_dir)
  49. videos = get_video_list(source_dir)
  50. chaptered_video_num = 0
  51. # print(videos)
  52. try:
  53. os.mkdir("temp")
  54. except FileExistsError:
  55. pass
  56. for name in videos.keys():
  57. if len(videos[name][0]) > 1:
  58. chaptered_video_num += 1
  59. os.chdir(output_dir)
  60. os.chdir("temp")
  61. with open(f"{name}.join", 'w') as file:
  62. chapters = videos[name][0]
  63. for c in chapters:
  64. file.write(f"file '{source_dir}/{c}'\n")
  65. status = os.system(
  66. f"ffmpeg -f concat -safe 0 -i {name}.join -c copy ../GX01{name}.mp4")
  67. if status:
  68. raise OSError("Something Goes Wrong With FFmpeg.")
  69. os.chdir(output_dir)
  70. try:
  71. shutil.rmtree('temp')
  72. except FileNotFoundError:
  73. pass
  74. sg.Window('Done', [[sg.T(f"Detected {len(videos.keys())} videos, {chaptered_video_num} are(is) sliced.")], [
  75. sg.Ok()]], disable_close=True).read(close=True)
  76. else:
  77. sg.popup_ok("Invalid Path")
  78. raise FileNotFoundError("Invalid Path")
  79. if __name__ == "__main__":
  80. try:
  81. _, source_dir, output_dir = sys.argv
  82. do_the_job(source_dir, output_dir)
  83. except ValueError:
  84. sg.theme('SystemDefault') # please make your windows colorful
  85. # layout = [[sg.Text('Input Folder')],
  86. # [sg.Input(), sg.FolderBrowse()],
  87. # [sg.Text('Output Folder')],
  88. # [sg.Input(), sg.FolderBrowse()],
  89. # [sg.OK(), sg.Cancel()]]
  90. layout = [[sg.Text(' Input Folder', size=(10, 1)), sg.InputText(), sg.FolderBrowse()],
  91. [sg.Text('Output Folder', size=(10, 1)), sg.InputText(), sg.FolderBrowse()],
  92. [sg.Ok(), sg.Cancel()]]
  93. window = sg.Window('GoPro Video Concatenator', layout)
  94. event, values = window.read()
  95. if event == 'OK':
  96. input_dir, output_dir = values[0], values[1]
  97. if input_dir == output_dir:
  98. event = sg.popup_yes_no("Can't output to the same folder as input, please change the output folder.\n"
  99. "Press Yes to create an output folder")
  100. if event == "Yes":
  101. os.chdir(input_dir)
  102. try:
  103. os.mkdir('Output')
  104. except FileExistsError:
  105. pass
  106. output_dir += '/Output'
  107. else:
  108. window.close()
  109. do_the_job(input_dir, output_dir)
  110. elif event in (sg.WIN_CLOSED, 'Cancel'):
  111. window.close()