diff --git a/2024-03-03_009TEMP_MPY_wvf_snd.mp4 b/2024-03-03_009TEMP_MPY_wvf_snd.mp4 new file mode 100644 index 0000000..d5d6f73 Binary files /dev/null and b/2024-03-03_009TEMP_MPY_wvf_snd.mp4 differ diff --git a/GPTRequest.py b/GPTRequest.py new file mode 100644 index 0000000..fb83d47 --- /dev/null +++ b/GPTRequest.py @@ -0,0 +1,94 @@ +# 코드를 작성하기 전에 전체적인 구조를 계획해 보겠습니다. + +# 1. 필요한 라이브러리를 불러옵니다. +import os +import datetime +import openai # OpenAI API를 사용하기 위한 라이브러리 + +# 2. ChatGPT와의 소통을 담당할 함수를 정의합니다. +def ask_chatgpt(question, api_key): + openai.api_key = api_key + response = openai.Completion.create( + model="gpt-3.5-turbo", # 이 모델은 최신 버전에서 사용됩니다. + messages=[ + {"role": "system", "content": "You are a helpful assistant."}, + {"role": "user", "content": question} + ] + ) + # 응답 형식에 따라 적절한 필드를 반환해야 합니다. + # 새로운 API에 따라, 응답 형식이 달라질 수 있으므로, 정확한 필드를 확인해야 합니다. + return response.choices[0].text.strip() # 'message' 대신 'text'를 사용 + + + +# 3. 응답을 분석하여 파일 제목을 결정하는 함수를 정의합니다. +def determine_filename(response): + """ + 응답 텍스트를 분석하여 파일 제목을 결정하는 함수. + :param response: ChatGPT로부터 받은 응답 텍스트. + :return: 결정된 파일 제목. + """ + # "제목"으로 시작하는 문장을 찾습니다. + for sentence in response.split('.'): + if sentence.strip().lower().startswith("제목"): + return sentence.strip() + ".txt" # 제목이 있는 경우 파일 이름을 결정합니다. + + # 제목이 없는 경우 현재 날짜로 파일 이름을 결정합니다. + current_date = datetime.datetime.now().strftime("%Y%m%d") + return f"{current_date}-Response.txt" + +# 4. 응답과 이미지(있는 경우)를 저장하는 함수를 정의합니다. +def save_response_and_images(response, folder_path, filename): + """ + 응답 텍스트와 이미지(있는 경우)를 파일에 저장하는 함수. + :param response: ChatGPT로부터 받은 응답 텍스트. + :param folder_path: 저장할 폴더의 경로. + :param filename: 파일 제목. + """ + # GPT_Response 폴더가 없으면 생성합니다. + if not os.path.exists(folder_path): + os.makedirs(folder_path) + + # 응답을 텍스트 파일로 저장합니다. + file_path = os.path.join(folder_path, filename) + with open(file_path, 'w') as file: + file.write(response) + + # TODO: 이미지 처리 로직은 사용자의 추가 요구 사항에 따라 결정되어야 합니다. + +# 주석 처리된 함수 호출들을 제외하고, 이 구조를 기반으로 구체적인 구현을 진행하겠습니다. +# 참고: 실제 코드 실행은 주석 처리되어 있으므로, 여기에서는 실행되지 않습니다. + + +# 파이썬 코드 수정: 사용자로부터 질문을 입력 받는 기능 추가 + +# 함수 정의 부분은 그대로 둡니다. 주요 변경은 스크립트 실행 부분에 있습니다. + +# 사용자로부터 질문을 입력 받는 코드를 추가합니다. +def main(api_key): + # 사용자로부터 질문을 입력 받습니다. + question = input("ChatGPT에게 물어볼 질문을 입력하세요: ") + + # ChatGPT에게 질문을 하고 응답을 받습니다. + response = ask_chatgpt(question, api_key) + + # 응답으로부터 파일 제목을 결정합니다. + filename = determine_filename(response) + + # 응답과 이미지(있는 경우)를 저장합니다. + folder_path = os.path.join(os.getcwd(), "GPT_Response") + save_response_and_images(response, folder_path, filename) + + # 사용자에게 응답이 저장된 위치를 알려줍니다. + print(f"응답이 {folder_path} 폴더에 저장되었습니다, 파일명: {filename}") + +# 이제 main 함수를 실행할 준비가 되었습니다. +# 참고: 실제 환경에서 API 키와 함께 main 함수를 호출해야 합니다. +# 예: main('your_openai_api_key_here') + +# 주석 처리된 함수 호출들을 제외하고, 이 구조를 기반으로 구체적인 구현을 진행하겠습니다. +# 참고: 실제 코드 실행은 주석 처리되어 있으므로, 여기에서는 실행되지 않습니다. + + +if __name__ == "__main__": + main("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") diff --git a/MakeVideo.py b/MakeVideo.py new file mode 100644 index 0000000..ccf1987 --- /dev/null +++ b/MakeVideo.py @@ -0,0 +1,164 @@ +import tkinter as tk +from tkinter import ttk, filedialog, simpledialog, Label +from gtts import gTTS +from moviepy.editor import * +from PIL import Image, ImageTk +import os +from datetime import datetime +from tkinter import messagebox +from moviepy.config import change_settings +change_settings({"IMAGEMAGICK_BINARY": r"C:\Program Files\ImageMagick-7.1.1-Q16-HDRI\magick.exe"}) + +class VideoCreatorApp: + def __init__(self, root): + self.root = root + self.setup_ui() + self.text_image_pairs = [] + self.bgm_path = '' + self.save_path = "C:/Users/thdtl/Desktop/python/AutoYoutubeProject/Result" # 초기 저장 경로는 비워둡니다. + self.selected_item_index = None + + def setup_ui(self): + self.root.title("YouTube Shorts Video Creator") + self.root.geometry("800x600") # Adjust the size of the window + self.listbox = tk.Listbox(self.root, width=70, height=20) + self.listbox.pack() + tk.Button(self.root, text="Add Text and Image", command=self.add_text_image_sequence).pack() + tk.Button(self.root, text="Edit Selected Text and Image", command=self.edit_selected_sequence).pack() + tk.Button(self.root, text="Delete Selected Text and Image", command=self.delete_selected_sequence).pack() + tk.Button(self.root, text="Set BGM", command=self.set_bgm).pack() + tk.Button(self.root, text="Remove BGM", command=self.remove_bgm).pack() + tk.Button(self.root, text="Set Save Path", command=self.set_save_path).pack() + tk.Button(self.root, text="Create Video", command=self.create_video).pack() + + self.save_path_label = tk.Label(self.root, text="No path set") + self.save_path_label.pack() + + self.image_label = Label(self.root) + self.image_label.pack() + + self.progress = ttk.Progressbar(self.root, length=300, mode='determinate') + self.progress.pack() + + self.listbox.bind('<>', self.on_select) + + def set_save_path(self): + # 사용자가 비디오를 저장할 경로를 선택할 수 있게 합니다. + path = filedialog.askdirectory() # 폴더 선택 다이얼로그를 엽니다. + if path: + self.save_path = path + self.save_path_label.config(text=path) # 선택된 경로를 레이블에 표시합니다. + + def remove_bgm(self): + self.bgm_path = '' # 배경음악 경로를 빈 문자열로 설정 + print("Background music removed") # 콘솔에 배경음악 제거 메시지 출력 + + def add_text_image_sequence(self): + text = simpledialog.askstring("Input", "Enter your text:", parent=self.root) + if text: # 텍스트가 입력되었다면 + image_path = filedialog.askopenfilename( + title="Select related image", + filetypes=[("Image files", "*.jpg *.jpeg *.png *.gif")], # 이미지 파일 형식을 모두 허용 + parent=self.root + ) + # 이미지 선택을 취소하거나 비워둔 경우 None 또는 빈 문자열('')이 될 수 있습니다. + # 이 경우에도 텍스트는 저장되지만, 이미지 경로는 빈 문자열로 처리됩니다. + self.text_image_pairs.append((text, image_path if image_path else "")) + self.listbox.insert(tk.END, text) + else: + messagebox.showwarning("Warning", "No text was entered.") + + + def edit_selected_sequence(self): + if self.selected_item_index is not None: + new_text = simpledialog.askstring("Edit text", "Enter new text:", parent=self.root, initialvalue=self.text_image_pairs[self.selected_item_index][0]) + if new_text: + new_image_path = filedialog.askopenfilename(title="Select new related image", filetypes=[("Image files", "*.jpg *.jpeg *.png")]) + if new_image_path: + self.text_image_pairs[self.selected_item_index] = (new_text, new_image_path) + self.listbox.delete(self.selected_item_index) + self.listbox.insert(self.selected_item_index, new_text) + + def delete_selected_sequence(self): + if self.selected_item_index is not None: + del self.text_image_pairs[self.selected_item_index] + self.listbox.delete(self.selected_item_index) + + def on_select(self, event): + widget = event.widget + if widget.curselection(): + index = int(widget.curselection()[0]) + self.selected_item_index = index + # 선택된 항목에 대한 이미지 미리보기 표시 + img_path = self.text_image_pairs[index][1] + self.display_image(img_path) + + def set_bgm(self): + self.bgm_path = filedialog.askopenfilename(title="Select BGM file", filetypes=[("Audio files", "*.mp3 *.wav")]) + + def create_video(self): + self.progress['value'] = 0 + total_steps = len(self.text_image_pairs) + current_step = 0 + + video_clips = [] # 최종 비디오 클립들을 저장할 리스트 + + for text, img_path in self.text_image_pairs: + # TTS 생성 및 오디오 클립 저장 + tts = gTTS(text=text, lang='ko') + tts_file = f"temp_audio_{current_step}.mp3" + tts.save(tts_file) + tts_audio_clip = AudioFileClip(tts_file).volumex(2.0) + + # 이미지 경로가 없는 경우, 투명한 배경의 클립 생성 + if not img_path: + img_clip = ColorClip(size=(1080, 1920), color=(0, 0, 0, 0), duration=tts_audio_clip.duration) + else: + img_clip = ImageClip(img_path).set_duration(tts_audio_clip.duration).resize(newsize=(1080, 1920)).set_position('center') + + # 자막 클립 생성 + txt_clip = TextClip(text, font='Arial', fontsize=24, color='white', bg_color=None).set_pos('bottom').set_duration(tts_audio_clip.duration) + + # 이미지 클립과 자막 클립을 합성 + video_clip = CompositeVideoClip([img_clip, txt_clip], size=(1080, 1920)).set_duration(tts_audio_clip.duration).set_audio(tts_audio_clip) + video_clips.append(video_clip) + + os.remove(tts_file) + current_step += 1 + self.progress['value'] = (current_step / total_steps) * 100 + self.root.update_idletasks() + + # 모든 비디오 클립을 순차적으로 결합 + final_video_clip = concatenate_videoclips(video_clips, method="compose") + + # 배경음악 설정 + if self.bgm_path: + bgm = AudioFileClip(self.bgm_path).volumex(0.5) + final_video_clip = final_video_clip.set_audio(CompositeAudioClip([final_video_clip.audio, bgm.set_duration(final_video_clip.duration)])) + + # 최종 비디오 저장 경로 설정 + if not self.save_path: + messagebox.showerror("Error", "Please set a save path first.") + return + + if not os.path.exists("Result"): + os.makedirs("Result") + current_time = datetime.now().strftime("%Y%m%d%H%M%S") + final_video_file = os.path.join(self.save_path, f"{current_time}.mp4") + final_video_clip.write_videofile(final_video_file, fps=24, codec="libx264", audio_codec="aac") + + self.progress['value'] = 100 + messagebox.showinfo("Video Creator", f"Video creation completed successfully! Saved to {final_video_file}") + + def display_image(self, img_path): + img = Image.open(img_path) + img = img.resize((200, 200), Image.Resampling.LANCZOS) # 이미지 크기 조정 + img_tk = ImageTk.PhotoImage(img) + self.image_label.configure(image=img_tk) + self.image_label.image = img_tk # 참조 추가 + + +if __name__ == "__main__": + root = tk.Tk() + app = VideoCreatorApp(root) + root.mainloop() \ No newline at end of file diff --git a/MakeVideo2.py b/MakeVideo2.py new file mode 100644 index 0000000..ebae9e5 --- /dev/null +++ b/MakeVideo2.py @@ -0,0 +1,115 @@ +from tkinter import Tk, Label, Button, Entry, filedialog, messagebox, Listbox, simpledialog, OptionMenu, StringVar +import os +from gtts import gTTS +from moviepy.editor import concatenate_videoclips, AudioFileClip, ImageClip, CompositeVideoClip, TextClip +import tempfile +from datetime import datetime + +class VideoProject: + def __init__(self): + self.texts = [] + self.images = [] + self.background_music = None + self.video_type = "참교육" + + def add_text(self, text): + self.texts.append(text) + + def add_image(self, image_path): + self.images.append(image_path) + + def set_background_music(self, music_path): + self.background_music = music_path + + def set_video_type(self, video_type): + self.video_type = video_type + +class VideoMakerApp: + def __init__(self, master): + self.master = master + master.title("유튜브 쇼츠 제작기") + + self.project = VideoProject() + + self.label = Label(master, text="유튜브 쇼츠 제작기에 오신 것을 환영합니다!") + self.label.pack() + + self.text_entry = Entry(master) + self.text_entry.pack() + + self.add_text_button = Button(master, text="텍스트 추가", command=self.add_text) + self.add_text_button.pack() + + self.add_image_button = Button(master, text="이미지 추가", command=self.add_image) + self.add_image_button.pack() + + self.add_music_button = Button(master, text="배경음 추가", command=self.add_background_music) + self.add_music_button.pack() + + self.type_var = StringVar(master) + self.type_var.set("참교육") + self.type_dropdown = OptionMenu(master, self.type_var, "참교육", "야썰", "어이없음", "감동", command=self.project.set_video_type) + self.type_dropdown.pack() + + self.create_video_button = Button(master, text="동영상 만들기", command=self.create_video_with_speech) + self.create_video_button.pack() + + self.item_listbox = Listbox(master) + self.item_listbox.pack() + + def add_text(self): + text = self.text_entry.get() + if text: + self.project.add_text(text) + self.item_listbox.insert('end', f"텍스트: {text}") + messagebox.showinfo("성공", "텍스트가 추가되었습니다.") + + def add_image(self): + file_path = filedialog.askopenfilename() + if file_path: + self.project.add_image(file_path) + self.item_listbox.insert('end', f"이미지: {os.path.basename(file_path)}") + messagebox.showinfo("성공", "이미지가 추가되었습니다.") + + def add_background_music(self): + file_path = filedialog.askopenfilename() + if file_path: + self.project.set_background_music(file_path) + messagebox.showinfo("성공", "배경음이 설정되었습니다.") + + def create_video_with_speech(self): + clips = [] + for text, image_path in zip(self.project.texts, self.project.images): + tts = gTTS(text=text, lang='ko') + temp_file = tempfile.NamedTemporaryFile(delete=False) + tts.save(temp_file.name) + temp_file.close() + + audio_clip = AudioFileClip(temp_file.name) + image_clip = ImageClip(image_path).set_duration(audio_clip.duration).set_fps(24) + text_clip = TextClip(text, fontsize=24, color='white').set_position('bottom').set_duration(audio_clip.duration) + composite_clip = CompositeVideoClip([image_clip, text_clip]).set_duration(audio_clip.duration).set_fps(24).set_audio(audio_clip) + clips.append(composite_clip) + + os.unlink(temp_file.name) + + final_clip = concatenate_videoclips(clips) + + if self.project.background_music: + background_audio = AudioFileClip(self.project.background_music).set_duration(final_clip.duration).set_fps(24) + final_clip = final_clip.set_audio(background_audio) + + result_dir = "Result" + if not os.path.exists(result_dir): + os.makedirs(result_dir) + today = datetime.now().strftime("%Y%m%d") + file_name = f"{today}_{self.project.video_type}.mp4" + final_path = os.path.join(result_dir, file_name) + + final_clip.write_videofile(final_path, fps=24) + + messagebox.showinfo("완료", "동영상이 성공적으로 생성되었습니다.") + +root = Tk() +my_gui = VideoMakerApp(root) +root.mainloop() diff --git a/MakeVideo3.py b/MakeVideo3.py new file mode 100644 index 0000000..36ef507 --- /dev/null +++ b/MakeVideo3.py @@ -0,0 +1,127 @@ +import tkinter as tk +from tkinter import ttk, filedialog, messagebox, simpledialog +from gtts import gTTS +from moviepy.editor import * +import os +from datetime import datetime +from PIL import Image + +class VideoCreatorApp: + def __init__(self, master): + self.master = master + self.master.title('Video Creator') + self.init_ui() + + # 데이터 관리를 위한 리스트 + self.scripts = [] + self.images = [] + self.actions = [] + self.background_music = None + + # 임시 및 결과 폴더 확인 + self.temp_folder = "temp" + self.result_folder = "Result" + for folder in [self.temp_folder, self.result_folder]: + if not os.path.exists(folder): + os.makedirs(folder) + + def init_ui(self): + # UI 구성 요소 + self.main_frame = ttk.Frame(self.master) + self.main_frame.pack(fill=tk.BOTH, expand=True) + + # 스크립트, 이미지, 액션 목록 및 추가 버튼 + self.list_frame = ttk.Frame(self.main_frame) + self.list_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) + + self.script_listbox = tk.Listbox(self.list_frame) + self.script_listbox.pack(fill=tk.X) + ttk.Button(self.list_frame, text='Add Script', command=self.add_script).pack(fill=tk.X) + + self.image_listbox = tk.Listbox(self.list_frame) + self.image_listbox.pack(fill=tk.X) + ttk.Button(self.list_frame, text='Add Image', command=self.add_image).pack(fill=tk.X) + + # 액션 추가 예시는 생략 + # self.action_listbox = tk.Listbox(self.list_frame) + # self.action_listbox.pack(fill=tk.X) + # ttk.Button(self.list_frame, text='Add Action', command=self.add_action).pack(fill=tk.X) + + self.preview_frame = ttk.Frame(self.main_frame, width=200) + self.preview_frame.pack(side=tk.RIGHT, fill=tk.Y) + self.preview_frame.pack_propagate(False) + + ttk.Button(self.preview_frame, text='Set Background Music', command=self.set_background_music).pack(fill=tk.X) + ttk.Button(self.preview_frame, text='Create Video', command=self.create_video).pack(fill=tk.X) + + def add_script(self): + script_text = simpledialog.askstring("Input", "Enter your script:") + if script_text: + self.scripts.append(script_text) + self.script_listbox.insert(tk.END, script_text) + + def add_image(self): + file_path = filedialog.askopenfilename(filetypes=(("Image files", "*.jpg;*.png;*.gif;*.webp"), ("All files", "*.*"))) + if file_path: + self.images.append(file_path) + self.image_listbox.insert(tk.END, file_path) + + # 배경음악 설정 및 동영상 생성 기능은 위에서 제공한 설명에 따라 구현됩니다. + # 이 부분의 코드는 이전에 제공된 `create_video_clips` 및 `create_video` 메서드 내용을 참고하여 구현할 수 있습니다. + + def set_background_music(self): + file_path = filedialog.askopenfilename(filetypes=(("Audio files", "*.mp3;*.wav"), ("All files", "*.*"))) + if file_path: + self.background_music = file_path + messagebox.showinfo("Background Music Set", f"Background music set to: {file_path}") + + def create_video(self): + clips = [] + + # 스크립트를 TTS로 변환하고 비디오 클립으로 추가 + for script in self.scripts: + tts = gTTS(script, lang='ko') + tts_file = os.path.join(self.temp_folder, "tts.mp3") + tts.save(tts_file) + + audioclip = AudioFileClip(tts_file) + txt_clip = TextClip(script, fontsize=24, color='white', bg_color='black', size=audioclip.size) + txt_clip = txt_clip.set_duration(audioclip.duration) + clip = CompositeVideoClip([txt_clip.set_pos('center')], size=audioclip.size).set_audio(audioclip) + clips.append(clip) + + # 이미지를 비디오 클립으로 추가 + for image in self.images: + img_clip = ImageClip(image).set_duration(3) # 예시로 3초 동안 표시 + img_clip = resize(img_clip, height=720) # 이미지 크기 조정 + clips.append(img_clip) + + # 모든 클립을 하나의 비디오로 결합 + final_clip = concatenate_videoclips(clips, method="compose") + + # 배경음악 추가 + if self.background_music: + background_music = AudioFileClip(self.background_music) + final_clip = final_clip.set_audio(background_music) + + # Result 폴더 내 오늘 날짜로 시작하는 파일들의 개수를 세어 n 구하기 + today_str = datetime.now().strftime("%Y-%m-%d") + existing_files = glob.glob(os.path.join(self.result_folder, f"{today_str}_*.mp4")) + file_number = len(existing_files) + 1 + + # 최종 비디오 파일 이름 설정 + output_filename = f"{today_str}_{file_number:03d}.mp4" + output_path = os.path.join(self.result_folder, output_filename) + + # 비디오 파일 저장 + final_clip.write_videofile(output_path, fps=24) + + messagebox.showinfo("Success", f"Video created successfully: {output_filename}") + +def main(): + root = tk.Tk() + app = VideoCreatorApp(root) + root.mainloop() + +if __name__ == '__main__': + main() diff --git a/MakeVideo4.py b/MakeVideo4.py new file mode 100644 index 0000000..e6d95c8 --- /dev/null +++ b/MakeVideo4.py @@ -0,0 +1,76 @@ +import tkinter as tk +from tkinter import ttk, filedialog, messagebox, simpledialog + +class VideoCreatorApp: + def __init__(self, master): + self.master = master + self.master.title('Video Creator') + self.init_ui() + + # 시퀀스 데이터 관리 + self.sequence = [] # 스크립트, 이미지, 액션을 포함하는 시퀀스 + + def init_ui(self): + self.sequence_frame = ttk.Frame(self.master) + self.sequence_frame.pack(fill=tk.BOTH, expand=True) + + self.add_script_button = ttk.Button(self.sequence_frame, text="Insert Script", command=self.insert_script) + self.add_script_button.pack(fill=tk.X) + + self.add_image_button = ttk.Button(self.sequence_frame, text="Insert Image", command=self.insert_image) + self.add_image_button.pack(fill=tk.X) + + self.add_action_button = ttk.Button(self.sequence_frame, text="Insert Action", command=self.insert_action) + self.add_action_button.pack(fill=tk.X) + + self.create_video_button = ttk.Button(self.sequence_frame, text="Create Video", command=self.create_video) + self.create_video_button.pack(fill=tk.X) + + self.sequence_listbox = tk.Listbox(self.sequence_frame) + self.sequence_listbox.pack(fill=tk.BOTH, expand=True) + + def insert_script(self): + script_text = simpledialog.askstring("Input", "Enter your script:") + if script_text: + self.sequence.append({'type': 'script', 'content': script_text}) + self.update_sequence_listbox() + + def insert_image(self): + file_path = filedialog.askopenfilename(filetypes=(("Image files", "*.jpg;*.png;*.gif;*.webp"), ("All files", "*.*"))) + if file_path: + self.sequence.append({'type': 'image', 'content': file_path}) + self.update_sequence_listbox() + + def insert_action(self): + action_type = simpledialog.askstring("Input", "Enter action type (e.g., 'sleep', 'clean'):") + if action_type == "sleep": + duration = simpledialog.askinteger("Input", "Enter duration (seconds):") + self.sequence.append({'type': 'action', 'action': action_type, 'duration': duration}) + elif action_type == "clean": + self.sequence.append({'type': 'action', 'action': action_type}) + self.update_sequence_listbox() + + def update_sequence_listbox(self): + self.sequence_listbox.delete(0, tk.END) + for item in self.sequence: + if item['type'] == 'script': + self.sequence_listbox.insert(tk.END, f"script {item['content'][:50]}...") + elif item['type'] == 'image': + self.sequence_listbox.insert(tk.END, f"image {item['content']}") + elif item['type'] == 'action': + if item['action'] == 'sleep': + self.sequence_listbox.insert(tk.END, f"action sleep {item['duration']}") + elif item['action'] == 'clean': + self.sequence_listbox.insert(tk.END, "action clean screen") + + def create_video(self): + # 여기에 비디오 생성 로직을 구현 + pass + +def main(): + root = tk.Tk() + app = VideoCreatorApp(root) + root.mainloop() + +if __name__ == '__main__': + main() diff --git a/MakeVideo5.py b/MakeVideo5.py new file mode 100644 index 0000000..b950457 --- /dev/null +++ b/MakeVideo5.py @@ -0,0 +1,245 @@ +import os +import glob +from moviepy.editor import ImageClip, AudioFileClip, concatenate_videoclips, TextClip, CompositeVideoClip +import moviepy.editor as mpe +from gtts import gTTS +from datetime import datetime +import tkinter as tk +from tkinter import ttk, filedialog, messagebox, simpledialog +from PIL import Image, ImageTk +import re + + +class VideoCreatorApp: + def __init__(self, master): + self.master = master + self.master.title('Video Creator') + self.sequence = [] + self.image_thumbnails = {} + self.current_image = None + self.background_music = None + self.animation_after_id = None # 이 부분을 추가 + self.init_ui() + + + def init_ui(self): + self.list_frame = ttk.Frame(self.master) + self.list_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) + + self.control_frame = ttk.Frame(self.master) + self.control_frame.pack(side=tk.RIGHT, fill=tk.Y) + + self.sequence_listbox = tk.Listbox(self.list_frame, width=50, height=20) + self.sequence_listbox.pack(padx=10, pady=10) + self.sequence_listbox.bind('<>', self.show_image_preview) + + ttk.Button(self.control_frame, text="Insert Script", command=self.insert_script).pack(pady=5) + ttk.Button(self.control_frame, text="Insert Image", command=self.insert_image).pack(pady=5) + ttk.Button(self.control_frame, text="Insert Action", command=self.insert_action).pack(pady=5) + ttk.Button(self.control_frame, text="Set Background Music", command=self.set_background_music).pack(pady=5) + ttk.Button(self.control_frame, text="Create Video", command=self.create_video).pack(pady=5) + # 'Update' 버튼 추가 + ttk.Button(self.control_frame, text="Update Item", command=self.update_item).pack(pady=5) + # 'Delete' 버튼 추가 + ttk.Button(self.control_frame, text="Delete Item", command=self.delete_item).pack(pady=5) + + self.preview_canvas = tk.Canvas(self.list_frame, width=100, height=100) + self.preview_canvas.pack(padx=10, pady=10) + + def update_item(self): + selection = self.sequence_listbox.curselection() + if selection: + index = selection[0] + item = self.sequence[index] + + # 스크립트나 이미지에 따라 다른 입력 요청 + if item['type'] == 'script': + new_text = simpledialog.askstring("Update Script", "Enter new script:", initialvalue=item['content']) + if new_text is not None: + self.sequence[index]['content'] = new_text + elif item['type'] == 'image': + new_path = filedialog.askopenfilename(filetypes=(("Image files", "*.jpg;*.png;*.gif;*.webp"), ("All files", "*.*")), initialdir="/", title="Select file") + if new_path: + self.sequence[index]['content'] = new_path + + self.update_sequence_listbox() # 리스트 박스 업데이트 + + def delete_item(self): + selection = self.sequence_listbox.curselection() + if selection: + index = selection[0] + del self.sequence[index] # 선택된 항목 삭제 + self.update_sequence_listbox() # 리스트 박스 업데이트 + + def update_sequence_listbox(self): + self.sequence_listbox.delete(0, tk.END) + for item in self.sequence: + if item['type'] == 'script': + self.sequence_listbox.insert(tk.END, f"Script: {item['content'][:30]}") + elif item['type'] == 'image': + # 파일 이름만 표시 + file_name = os.path.basename(item['content']) + self.sequence_listbox.insert(tk.END, f"Image: {file_name}") + + + def insert_script(self): + script_text = simpledialog.askstring("Input", "Enter your script:") + if script_text: + self.sequence.append({'type': 'script', 'content': script_text}) + self.update_sequence_listbox() + + def insert_image(self): + file_path = filedialog.askopenfilename(filetypes=(("Image files", "*.jpg;*.png;*.gif;*.webp"), ("All files", "*.*"))) + if file_path: + self.sequence.append({'type': 'image', 'content': file_path}) + self.update_sequence_listbox() + + def insert_action(self): + action = simpledialog.askstring("Insert Action", "Enter action (clean or sleep):") + if action == "sleep": + duration = simpledialog.askinteger("Sleep Duration", "Enter duration in seconds:", parent=self.master) + if duration is not None: + self.sequence.append({'type': 'action', 'action': action, 'duration': duration}) + elif action == "clean": + self.sequence.append({'type': 'action', 'action': action}) + self.update_sequence_listbox() + + + def set_background_music(self): + file_path = filedialog.askopenfilename(filetypes=(("Audio files", "*.mp3;*.wav"), ("All files", "*.*"))) + if file_path: + self.background_music = file_path + messagebox.showinfo("Background Music Set", f"Background music set to: {file_path}") + + def create_tts_audio(self, text, filename): + # 자음만 있는 한글 문자열 패턴 확인 및 건너뜀 + if re.fullmatch(r'[ㄱ-ㅎ]+', text): + print("자음만 있는 문자열은 TTS에서 제외됩니다:", text) + return False + + # TTS 생성 + try: + tts = gTTS(text=text, lang='ko', slow=False) + tts.save(filename) + return True + except Exception as e: + print(f"TTS 생성 중 오류 발생: {e}") + return False + + def create_video(self): + clips = [] + last_clip_end_time = 0 # 마지막 클립의 종료 시간을 추적합니다. + + for index, item in enumerate(self.sequence): + if item['type'] == 'script': + tts_filename = f'temp_{datetime.now().strftime("%Y%m%d%H%M%S")}.mp3' + if self.create_tts_audio(item['content'], tts_filename): + audio_clip = AudioFileClip(tts_filename).set_start(last_clip_end_time) + txt_clip = TextClip(item['content'], fontsize=24, color='white', bg_color='black', align='South')\ + .set_position(('center', 'bottom'))\ + .set_duration(audio_clip.duration)\ + .set_start(last_clip_end_time) + # 자막이 항상 최상위 레이어에 오도록 설정합니다. + video_clip = CompositeVideoClip([txt_clip], size=(1080,1920)).set_duration(audio_clip.duration).set_start(last_clip_end_time).set_audio(audio_clip) + clips.append(video_clip) + last_clip_end_time += audio_clip.duration + os.remove(tts_filename) + + elif item['type'] == 'image': + if index > 0 and self.sequence[index - 1]['type'] == 'script': + # 이미지 클립의 지속 시간을 다음 스크립트 시작까지로 설정 + next_script_start_time = last_clip_end_time + img_clip = ImageClip(item['content']).set_start(last_clip_end_time).set_duration(next_script_start_time - last_clip_end_time).resize(newsize=(1080, 1920)) + clips.append(img_clip) + + if clips: + final_clip = concatenate_videoclips(clips, method="chain", padding=-1) + output_path = self.generate_output_path() + final_clip.write_videofile(output_path, fps=24) + messagebox.showinfo("Video Creation", f"Video created successfully: {output_path}") + else: + messagebox.showerror("Video Creation", "No clips to create a video.") + + + + def generate_output_path(self): + # 파일 경로 생성 로직 (변경 없음) + date_str = datetime.now().strftime("%Y-%m-%d") + output_dir = os.path.join("Result", date_str) + os.makedirs(output_dir, exist_ok=True) + file_count = len(os.listdir(output_dir)) # 이미 있는 파일의 개수를 기준으로 파일 이름 결정 + return os.path.join(output_dir, f"{date_str}_{file_count + 1:03d}.mp4") + + def update_sequence_listbox(self): + self.sequence_listbox.delete(0, tk.END) + for item in self.sequence: + item_desc = f"{item['type']}: {item.get('action', '')} {item.get('content', '')[:50]}" + self.sequence_listbox.insert(tk.END, item_desc) + + def show_image_preview(self, event=None): + selection = self.sequence_listbox.curselection() + if selection: + selected_index = selection[0] + selected_item = self.sequence[selected_index] + if selected_item['type'] == 'image': + self.display_image_thumbnail(selected_item['content']) + + + def display_image_thumbnail(self, image_path): + self.preview_canvas.delete("all") # 이전 이미지 삭제 + if self.animation_after_id: + self.master.after_cancel(self.animation_after_id) # 기존 애니메이션 타이머 취소 + self.animation_after_id = None # 타이머 ID 초기화 + + if image_path.lower().endswith('.gif'): # 애니메이션 GIF 처리 + self.process_gif(image_path) + else: # 정적 이미지 처리 + img = Image.open(image_path) + img.thumbnail((100, 100), getattr(Image, 'Resampling', Image).LANCZOS) + photo = ImageTk.PhotoImage(img) + self.preview_canvas.create_image(50, 50, image=photo, anchor=tk.CENTER) + self.image_thumbnails[image_path] = photo # 참조 유지 + + def process_gif(self, image_path): + gif = Image.open(image_path) + self.gif_frames = [] + try: + while True: + self.gif_frames.append(ImageTk.PhotoImage(gif.copy())) + gif.seek(len(self.gif_frames)) # 다음 프레임으로 이동 + except EOFError: + pass # 모든 프레임을 처리했음 + + self.current_frame = 0 + self.update_gif_frame() # GIF 애니메이션 시작 + + def update_gif_frame(self): + if self.gif_frames: + frame = self.gif_frames[self.current_frame] + self.preview_canvas.create_image(50, 50, image=frame, anchor=tk.CENTER) + self.current_frame = (self.current_frame + 1) % len(self.gif_frames) + self.animation_after_id = self.master.after(100, self.update_gif_frame) + + def preview_gif(self, img, image_path, frame_number=0): + try: + img.seek(frame_number) + frame = ImageTk.PhotoImage(img) + self.preview_canvas.delete("all") + self.preview_canvas.create_image(50, 50, image=frame, anchor=tk.CENTER) + self.image_thumbnails[image_path] = frame # 참조 유지 + self.current_image = image_path # 현재 GIF 이미지 경로 저장 + + frame_number += 1 + delay = img.info.get('duration', 100) # 다음 프레임까지의 지연 시간, 기본값 100ms + self.master.after(delay, self.preview_gif, img, image_path, frame_number) + except EOFError: # 마지막 프레임에 도달하면 다시 시작 + if self.current_image == image_path: # 현재 이미지가 여전히 같은 GIF인 경우에만 재시작 + self.preview_gif(img, image_path, 0) + +def main(): + root = tk.Tk() + app = VideoCreatorApp(root) + root.mainloop() + +if __name__ == '__main__': + main() diff --git a/Resource/0303/2.webp b/Resource/0303/2.webp new file mode 100644 index 0000000..aaf0fc5 Binary files /dev/null and b/Resource/0303/2.webp differ diff --git a/Resource/0303/3.webp b/Resource/0303/3.webp new file mode 100644 index 0000000..0bfda88 Binary files /dev/null and b/Resource/0303/3.webp differ diff --git a/Resource/0303/4.webp b/Resource/0303/4.webp new file mode 100644 index 0000000..c79e61e Binary files /dev/null and b/Resource/0303/4.webp differ diff --git a/Resource/0303/5.webp b/Resource/0303/5.webp new file mode 100644 index 0000000..479498b Binary files /dev/null and b/Resource/0303/5.webp differ diff --git a/Resource/0303/6.webp b/Resource/0303/6.webp new file mode 100644 index 0000000..de49fb2 Binary files /dev/null and b/Resource/0303/6.webp differ diff --git a/Resource/0303/6672e07c-74ab-4539-87e7-12b69fb31519.webp b/Resource/0303/6672e07c-74ab-4539-87e7-12b69fb31519.webp new file mode 100644 index 0000000..7b94c33 Binary files /dev/null and b/Resource/0303/6672e07c-74ab-4539-87e7-12b69fb31519.webp differ diff --git a/Resource/0303/7.webp b/Resource/0303/7.webp new file mode 100644 index 0000000..e62b9a9 Binary files /dev/null and b/Resource/0303/7.webp differ diff --git a/Resource/13d7a1a5b829427699a2371b69bf0f07_1628432520.gif b/Resource/13d7a1a5b829427699a2371b69bf0f07_1628432520.gif new file mode 100644 index 0000000..2f13e4e Binary files /dev/null and b/Resource/13d7a1a5b829427699a2371b69bf0f07_1628432520.gif differ diff --git a/Resource/original.jpg b/Resource/original.jpg new file mode 100644 index 0000000..41bad92 Binary files /dev/null and b/Resource/original.jpg differ diff --git a/Resource/스크린샷 2023-09-30 204611.png b/Resource/스크린샷 2023-09-30 204611.png new file mode 100644 index 0000000..88cd87c Binary files /dev/null and b/Resource/스크린샷 2023-09-30 204611.png differ diff --git a/Resource/스크린샷 2023-09-30 235533.png b/Resource/스크린샷 2023-09-30 235533.png new file mode 100644 index 0000000..545c4dd Binary files /dev/null and b/Resource/스크린샷 2023-09-30 235533.png differ diff --git a/Resource/스크린샷 2023-10-01 024817.png b/Resource/스크린샷 2023-10-01 024817.png new file mode 100644 index 0000000..3bd90ee Binary files /dev/null and b/Resource/스크린샷 2023-10-01 024817.png differ diff --git a/Resource/스크린샷 2023-10-01 025033.png b/Resource/스크린샷 2023-10-01 025033.png new file mode 100644 index 0000000..e558262 Binary files /dev/null and b/Resource/스크린샷 2023-10-01 025033.png differ diff --git a/Resource/스크린샷 2023-10-01 025110.png b/Resource/스크린샷 2023-10-01 025110.png new file mode 100644 index 0000000..8370868 Binary files /dev/null and b/Resource/스크린샷 2023-10-01 025110.png differ diff --git a/Resource/스크린샷 2023-10-01 174716.png b/Resource/스크린샷 2023-10-01 174716.png new file mode 100644 index 0000000..a8a0247 Binary files /dev/null and b/Resource/스크린샷 2023-10-01 174716.png differ diff --git a/Resource/스크린샷 2023-10-01 200146.png b/Resource/스크린샷 2023-10-01 200146.png new file mode 100644 index 0000000..4214218 Binary files /dev/null and b/Resource/스크린샷 2023-10-01 200146.png differ diff --git a/Resource/스크린샷 2023-10-01 200257.png b/Resource/스크린샷 2023-10-01 200257.png new file mode 100644 index 0000000..6323471 Binary files /dev/null and b/Resource/스크린샷 2023-10-01 200257.png differ diff --git a/Resource/스크린샷 2023-10-01 211759.png b/Resource/스크린샷 2023-10-01 211759.png new file mode 100644 index 0000000..9cfcba5 Binary files /dev/null and b/Resource/스크린샷 2023-10-01 211759.png differ diff --git a/Resource/스크린샷 2023-10-01 211959.png b/Resource/스크린샷 2023-10-01 211959.png new file mode 100644 index 0000000..b0382b9 Binary files /dev/null and b/Resource/스크린샷 2023-10-01 211959.png differ diff --git a/Resource/스크린샷 2023-10-01 212021.png b/Resource/스크린샷 2023-10-01 212021.png new file mode 100644 index 0000000..d06e3c2 Binary files /dev/null and b/Resource/스크린샷 2023-10-01 212021.png differ diff --git a/Resource/스크린샷 2023-10-01 212827.png b/Resource/스크린샷 2023-10-01 212827.png new file mode 100644 index 0000000..859b515 Binary files /dev/null and b/Resource/스크린샷 2023-10-01 212827.png differ diff --git a/Resource/스크린샷 2023-10-01 212905.png b/Resource/스크린샷 2023-10-01 212905.png new file mode 100644 index 0000000..611d7ab Binary files /dev/null and b/Resource/스크린샷 2023-10-01 212905.png differ diff --git a/Resource/스크린샷 2023-10-02 171753.png b/Resource/스크린샷 2023-10-02 171753.png new file mode 100644 index 0000000..51e23b5 Binary files /dev/null and b/Resource/스크린샷 2023-10-02 171753.png differ diff --git a/Resource/스크린샷 2023-10-02 171815.png b/Resource/스크린샷 2023-10-02 171815.png new file mode 100644 index 0000000..f496179 Binary files /dev/null and b/Resource/스크린샷 2023-10-02 171815.png differ diff --git a/Resource/스크린샷 2023-10-02 220411.png b/Resource/스크린샷 2023-10-02 220411.png new file mode 100644 index 0000000..996e6bb Binary files /dev/null and b/Resource/스크린샷 2023-10-02 220411.png differ diff --git a/Resource/스크린샷 2023-10-07 135005.png b/Resource/스크린샷 2023-10-07 135005.png new file mode 100644 index 0000000..1e44bc3 Binary files /dev/null and b/Resource/스크린샷 2023-10-07 135005.png differ diff --git a/Resource/스크린샷 2023-10-07 192931.png b/Resource/스크린샷 2023-10-07 192931.png new file mode 100644 index 0000000..9ff7b43 Binary files /dev/null and b/Resource/스크린샷 2023-10-07 192931.png differ diff --git a/Resource/스크린샷 2023-10-07 201135.png b/Resource/스크린샷 2023-10-07 201135.png new file mode 100644 index 0000000..bbe9db9 Binary files /dev/null and b/Resource/스크린샷 2023-10-07 201135.png differ diff --git a/Resource/스크린샷 2023-10-08 144642.png b/Resource/스크린샷 2023-10-08 144642.png new file mode 100644 index 0000000..74ed5ad Binary files /dev/null and b/Resource/스크린샷 2023-10-08 144642.png differ diff --git a/Resource/스크린샷 2023-10-08 144737.png b/Resource/스크린샷 2023-10-08 144737.png new file mode 100644 index 0000000..83f848c Binary files /dev/null and b/Resource/스크린샷 2023-10-08 144737.png differ diff --git a/Resource/스크린샷 2023-10-08 145301.png b/Resource/스크린샷 2023-10-08 145301.png new file mode 100644 index 0000000..da2dfaa Binary files /dev/null and b/Resource/스크린샷 2023-10-08 145301.png differ diff --git a/Resource/스크린샷 2023-10-08 154149.png b/Resource/스크린샷 2023-10-08 154149.png new file mode 100644 index 0000000..94c9f52 Binary files /dev/null and b/Resource/스크린샷 2023-10-08 154149.png differ diff --git a/Resource/스크린샷 2023-10-08 154201.png b/Resource/스크린샷 2023-10-08 154201.png new file mode 100644 index 0000000..8e6a686 Binary files /dev/null and b/Resource/스크린샷 2023-10-08 154201.png differ diff --git a/Resource/스크린샷 2023-10-08 182355.png b/Resource/스크린샷 2023-10-08 182355.png new file mode 100644 index 0000000..770ad00 Binary files /dev/null and b/Resource/스크린샷 2023-10-08 182355.png differ diff --git a/Resource/스크린샷 2023-10-08 182402.png b/Resource/스크린샷 2023-10-08 182402.png new file mode 100644 index 0000000..6e847e4 Binary files /dev/null and b/Resource/스크린샷 2023-10-08 182402.png differ diff --git a/Resource/스크린샷 2023-10-08 215751.png b/Resource/스크린샷 2023-10-08 215751.png new file mode 100644 index 0000000..0419958 Binary files /dev/null and b/Resource/스크린샷 2023-10-08 215751.png differ diff --git a/Resource/스크린샷 2023-10-09 021006.png b/Resource/스크린샷 2023-10-09 021006.png new file mode 100644 index 0000000..b3f890f Binary files /dev/null and b/Resource/스크린샷 2023-10-09 021006.png differ diff --git a/Resource/스크린샷 2023-10-09 190343.png b/Resource/스크린샷 2023-10-09 190343.png new file mode 100644 index 0000000..5d0278f Binary files /dev/null and b/Resource/스크린샷 2023-10-09 190343.png differ diff --git a/Resource/스크린샷 2023-10-09 195122.png b/Resource/스크린샷 2023-10-09 195122.png new file mode 100644 index 0000000..bbcd8d8 Binary files /dev/null and b/Resource/스크린샷 2023-10-09 195122.png differ diff --git a/Resource/스크린샷 2023-10-09 195150.png b/Resource/스크린샷 2023-10-09 195150.png new file mode 100644 index 0000000..40dc2b0 Binary files /dev/null and b/Resource/스크린샷 2023-10-09 195150.png differ diff --git a/Resource/스크린샷 2023-10-09 202912.png b/Resource/스크린샷 2023-10-09 202912.png new file mode 100644 index 0000000..13e7a72 Binary files /dev/null and b/Resource/스크린샷 2023-10-09 202912.png differ diff --git a/Resource/스크린샷 2023-10-09 205645.png b/Resource/스크린샷 2023-10-09 205645.png new file mode 100644 index 0000000..57548fa Binary files /dev/null and b/Resource/스크린샷 2023-10-09 205645.png differ diff --git a/Resource/스크린샷 2023-10-09 231610.png b/Resource/스크린샷 2023-10-09 231610.png new file mode 100644 index 0000000..fcb1d0c Binary files /dev/null and b/Resource/스크린샷 2023-10-09 231610.png differ diff --git a/Resource/스크린샷 2023-10-09 233318.png b/Resource/스크린샷 2023-10-09 233318.png new file mode 100644 index 0000000..7fa3e40 Binary files /dev/null and b/Resource/스크린샷 2023-10-09 233318.png differ diff --git a/Resource/스크린샷 2023-10-15 212804.png b/Resource/스크린샷 2023-10-15 212804.png new file mode 100644 index 0000000..e889d67 Binary files /dev/null and b/Resource/스크린샷 2023-10-15 212804.png differ diff --git a/Resource/스크린샷 2023-10-16 212759.png b/Resource/스크린샷 2023-10-16 212759.png new file mode 100644 index 0000000..edcdb91 Binary files /dev/null and b/Resource/스크린샷 2023-10-16 212759.png differ diff --git a/Resource/스크린샷 2023-10-17 001708.png b/Resource/스크린샷 2023-10-17 001708.png new file mode 100644 index 0000000..909a022 Binary files /dev/null and b/Resource/스크린샷 2023-10-17 001708.png differ diff --git a/Resource/스크린샷 2023-10-19 223215.png b/Resource/스크린샷 2023-10-19 223215.png new file mode 100644 index 0000000..150b45f Binary files /dev/null and b/Resource/스크린샷 2023-10-19 223215.png differ diff --git a/Resource/스크린샷 2023-10-19 223227.png b/Resource/스크린샷 2023-10-19 223227.png new file mode 100644 index 0000000..47d9c50 Binary files /dev/null and b/Resource/스크린샷 2023-10-19 223227.png differ diff --git a/Resource/스크린샷 2023-10-19 224036.png b/Resource/스크린샷 2023-10-19 224036.png new file mode 100644 index 0000000..d7df61a Binary files /dev/null and b/Resource/스크린샷 2023-10-19 224036.png differ diff --git a/Resource/스크린샷 2023-10-21 153925.png b/Resource/스크린샷 2023-10-21 153925.png new file mode 100644 index 0000000..c18f3a8 Binary files /dev/null and b/Resource/스크린샷 2023-10-21 153925.png differ diff --git a/Resource/스크린샷 2023-10-21 195644.png b/Resource/스크린샷 2023-10-21 195644.png new file mode 100644 index 0000000..47c1ba8 Binary files /dev/null and b/Resource/스크린샷 2023-10-21 195644.png differ diff --git a/Resource/스크린샷 2023-10-22 114419.png b/Resource/스크린샷 2023-10-22 114419.png new file mode 100644 index 0000000..f9a9fd4 Binary files /dev/null and b/Resource/스크린샷 2023-10-22 114419.png differ diff --git a/Resource/스크린샷 2023-10-22 212528.png b/Resource/스크린샷 2023-10-22 212528.png new file mode 100644 index 0000000..b3aa256 Binary files /dev/null and b/Resource/스크린샷 2023-10-22 212528.png differ diff --git a/Resource/스크린샷 2023-10-23 083934.png b/Resource/스크린샷 2023-10-23 083934.png new file mode 100644 index 0000000..d7918ea Binary files /dev/null and b/Resource/스크린샷 2023-10-23 083934.png differ diff --git a/Resource/스크린샷 2023-10-23 121003.png b/Resource/스크린샷 2023-10-23 121003.png new file mode 100644 index 0000000..7abfc28 Binary files /dev/null and b/Resource/스크린샷 2023-10-23 121003.png differ diff --git a/Resource/스크린샷 2023-10-23 121016.png b/Resource/스크린샷 2023-10-23 121016.png new file mode 100644 index 0000000..91a6a12 Binary files /dev/null and b/Resource/스크린샷 2023-10-23 121016.png differ diff --git a/Resource/스크린샷 2023-10-23 121427.png b/Resource/스크린샷 2023-10-23 121427.png new file mode 100644 index 0000000..11e68b3 Binary files /dev/null and b/Resource/스크린샷 2023-10-23 121427.png differ diff --git a/Resource/스크린샷 2023-10-23 144313.png b/Resource/스크린샷 2023-10-23 144313.png new file mode 100644 index 0000000..08801f5 Binary files /dev/null and b/Resource/스크린샷 2023-10-23 144313.png differ diff --git a/Resource/스크린샷 2023-10-23 144924.png b/Resource/스크린샷 2023-10-23 144924.png new file mode 100644 index 0000000..8706712 Binary files /dev/null and b/Resource/스크린샷 2023-10-23 144924.png differ diff --git a/Resource/스크린샷 2023-10-23 150435.png b/Resource/스크린샷 2023-10-23 150435.png new file mode 100644 index 0000000..abc0533 Binary files /dev/null and b/Resource/스크린샷 2023-10-23 150435.png differ diff --git a/Resource/스크린샷 2023-10-23 150603.png b/Resource/스크린샷 2023-10-23 150603.png new file mode 100644 index 0000000..d3d4819 Binary files /dev/null and b/Resource/스크린샷 2023-10-23 150603.png differ diff --git a/Resource/스크린샷 2023-10-24 210640.png b/Resource/스크린샷 2023-10-24 210640.png new file mode 100644 index 0000000..126a821 Binary files /dev/null and b/Resource/스크린샷 2023-10-24 210640.png differ diff --git a/Resource/스크린샷 2023-10-24 231655.png b/Resource/스크린샷 2023-10-24 231655.png new file mode 100644 index 0000000..a5d58cc Binary files /dev/null and b/Resource/스크린샷 2023-10-24 231655.png differ diff --git a/Resource/스크린샷 2023-10-25 214308.png b/Resource/스크린샷 2023-10-25 214308.png new file mode 100644 index 0000000..3d8e1f7 Binary files /dev/null and b/Resource/스크린샷 2023-10-25 214308.png differ diff --git a/Resource/스크린샷 2023-10-25 233641.png b/Resource/스크린샷 2023-10-25 233641.png new file mode 100644 index 0000000..350e491 Binary files /dev/null and b/Resource/스크린샷 2023-10-25 233641.png differ diff --git a/Resource/스크린샷 2023-10-25 233733.png b/Resource/스크린샷 2023-10-25 233733.png new file mode 100644 index 0000000..2a79193 Binary files /dev/null and b/Resource/스크린샷 2023-10-25 233733.png differ diff --git a/Resource/스크린샷 2023-10-25 233801.png b/Resource/스크린샷 2023-10-25 233801.png new file mode 100644 index 0000000..6620b63 Binary files /dev/null and b/Resource/스크린샷 2023-10-25 233801.png differ diff --git a/Resource/스크린샷 2023-10-25 233814.png b/Resource/스크린샷 2023-10-25 233814.png new file mode 100644 index 0000000..c71f92f Binary files /dev/null and b/Resource/스크린샷 2023-10-25 233814.png differ diff --git a/Resource/스크린샷 2023-10-25 233829.png b/Resource/스크린샷 2023-10-25 233829.png new file mode 100644 index 0000000..56c363c Binary files /dev/null and b/Resource/스크린샷 2023-10-25 233829.png differ diff --git a/Resource/스크린샷 2023-10-26 004337.png b/Resource/스크린샷 2023-10-26 004337.png new file mode 100644 index 0000000..42f8852 Binary files /dev/null and b/Resource/스크린샷 2023-10-26 004337.png differ diff --git a/Resource/스크린샷 2023-10-27 202520.png b/Resource/스크린샷 2023-10-27 202520.png new file mode 100644 index 0000000..e9afd0e Binary files /dev/null and b/Resource/스크린샷 2023-10-27 202520.png differ diff --git a/Resource/스크린샷 2023-10-27 204753.png b/Resource/스크린샷 2023-10-27 204753.png new file mode 100644 index 0000000..a642564 Binary files /dev/null and b/Resource/스크린샷 2023-10-27 204753.png differ diff --git a/Resource/스크린샷 2023-10-27 204802.png b/Resource/스크린샷 2023-10-27 204802.png new file mode 100644 index 0000000..da8166b Binary files /dev/null and b/Resource/스크린샷 2023-10-27 204802.png differ diff --git a/Resource/스크린샷 2023-10-28 224942.png b/Resource/스크린샷 2023-10-28 224942.png new file mode 100644 index 0000000..386559b Binary files /dev/null and b/Resource/스크린샷 2023-10-28 224942.png differ diff --git a/Resource/스크린샷 2023-10-29 190114.png b/Resource/스크린샷 2023-10-29 190114.png new file mode 100644 index 0000000..298d3f7 Binary files /dev/null and b/Resource/스크린샷 2023-10-29 190114.png differ diff --git a/Resource/스크린샷 2023-10-29 190311.png b/Resource/스크린샷 2023-10-29 190311.png new file mode 100644 index 0000000..7f6530c Binary files /dev/null and b/Resource/스크린샷 2023-10-29 190311.png differ diff --git a/Resource/스크린샷 2023-10-29 190840.png b/Resource/스크린샷 2023-10-29 190840.png new file mode 100644 index 0000000..e14cdcb Binary files /dev/null and b/Resource/스크린샷 2023-10-29 190840.png differ diff --git a/Resource/스크린샷 2023-10-29 230240.png b/Resource/스크린샷 2023-10-29 230240.png new file mode 100644 index 0000000..3434864 Binary files /dev/null and b/Resource/스크린샷 2023-10-29 230240.png differ diff --git a/Resource/스크린샷 2023-10-30 222842.png b/Resource/스크린샷 2023-10-30 222842.png new file mode 100644 index 0000000..b4d7531 Binary files /dev/null and b/Resource/스크린샷 2023-10-30 222842.png differ diff --git a/Resource/스크린샷 2023-10-31 212957.png b/Resource/스크린샷 2023-10-31 212957.png new file mode 100644 index 0000000..ad95a82 Binary files /dev/null and b/Resource/스크린샷 2023-10-31 212957.png differ diff --git a/Resource/스크린샷 2023-10-31 223906.png b/Resource/스크린샷 2023-10-31 223906.png new file mode 100644 index 0000000..67f52d4 Binary files /dev/null and b/Resource/스크린샷 2023-10-31 223906.png differ diff --git a/Resource/스크린샷 2023-11-02 215904.png b/Resource/스크린샷 2023-11-02 215904.png new file mode 100644 index 0000000..901bca1 Binary files /dev/null and b/Resource/스크린샷 2023-11-02 215904.png differ diff --git a/Resource/스크린샷 2023-11-04 210518.png b/Resource/스크린샷 2023-11-04 210518.png new file mode 100644 index 0000000..ae384a8 Binary files /dev/null and b/Resource/스크린샷 2023-11-04 210518.png differ diff --git a/Resource/스크린샷 2023-11-04 231306.png b/Resource/스크린샷 2023-11-04 231306.png new file mode 100644 index 0000000..99b4444 Binary files /dev/null and b/Resource/스크린샷 2023-11-04 231306.png differ diff --git a/Resource/스크린샷 2023-11-04 231512.png b/Resource/스크린샷 2023-11-04 231512.png new file mode 100644 index 0000000..0a7d5b9 Binary files /dev/null and b/Resource/스크린샷 2023-11-04 231512.png differ diff --git a/Result/2024-03-03/2024-03-03_001.mp4 b/Result/2024-03-03/2024-03-03_001.mp4 new file mode 100644 index 0000000..f4d0af1 Binary files /dev/null and b/Result/2024-03-03/2024-03-03_001.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_002.mp4 b/Result/2024-03-03/2024-03-03_002.mp4 new file mode 100644 index 0000000..d1c2b7c Binary files /dev/null and b/Result/2024-03-03/2024-03-03_002.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_003.mp4 b/Result/2024-03-03/2024-03-03_003.mp4 new file mode 100644 index 0000000..d1c2b7c Binary files /dev/null and b/Result/2024-03-03/2024-03-03_003.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_004.mp4 b/Result/2024-03-03/2024-03-03_004.mp4 new file mode 100644 index 0000000..582cfcc Binary files /dev/null and b/Result/2024-03-03/2024-03-03_004.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_005.mp4 b/Result/2024-03-03/2024-03-03_005.mp4 new file mode 100644 index 0000000..c960a50 Binary files /dev/null and b/Result/2024-03-03/2024-03-03_005.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_006.mp4 b/Result/2024-03-03/2024-03-03_006.mp4 new file mode 100644 index 0000000..a041379 Binary files /dev/null and b/Result/2024-03-03/2024-03-03_006.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_007.mp4 b/Result/2024-03-03/2024-03-03_007.mp4 new file mode 100644 index 0000000..09596d9 Binary files /dev/null and b/Result/2024-03-03/2024-03-03_007.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_008.mp4 b/Result/2024-03-03/2024-03-03_008.mp4 new file mode 100644 index 0000000..d63ac5f Binary files /dev/null and b/Result/2024-03-03/2024-03-03_008.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_009.mp4 b/Result/2024-03-03/2024-03-03_009.mp4 new file mode 100644 index 0000000..f3f248a Binary files /dev/null and b/Result/2024-03-03/2024-03-03_009.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_010.mp4 b/Result/2024-03-03/2024-03-03_010.mp4 new file mode 100644 index 0000000..1761793 Binary files /dev/null and b/Result/2024-03-03/2024-03-03_010.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_011.mp4 b/Result/2024-03-03/2024-03-03_011.mp4 new file mode 100644 index 0000000..1761793 Binary files /dev/null and b/Result/2024-03-03/2024-03-03_011.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_012.mp4 b/Result/2024-03-03/2024-03-03_012.mp4 new file mode 100644 index 0000000..1e08377 Binary files /dev/null and b/Result/2024-03-03/2024-03-03_012.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_013.mp4 b/Result/2024-03-03/2024-03-03_013.mp4 new file mode 100644 index 0000000..b70184b Binary files /dev/null and b/Result/2024-03-03/2024-03-03_013.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_014.mp4 b/Result/2024-03-03/2024-03-03_014.mp4 new file mode 100644 index 0000000..565b31a Binary files /dev/null and b/Result/2024-03-03/2024-03-03_014.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_015.mp4 b/Result/2024-03-03/2024-03-03_015.mp4 new file mode 100644 index 0000000..a6bf7b1 Binary files /dev/null and b/Result/2024-03-03/2024-03-03_015.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_016.mp4 b/Result/2024-03-03/2024-03-03_016.mp4 new file mode 100644 index 0000000..0319b7a Binary files /dev/null and b/Result/2024-03-03/2024-03-03_016.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_017.mp4 b/Result/2024-03-03/2024-03-03_017.mp4 new file mode 100644 index 0000000..4347f50 Binary files /dev/null and b/Result/2024-03-03/2024-03-03_017.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_018.mp4 b/Result/2024-03-03/2024-03-03_018.mp4 new file mode 100644 index 0000000..cf8630e Binary files /dev/null and b/Result/2024-03-03/2024-03-03_018.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_019.mp4 b/Result/2024-03-03/2024-03-03_019.mp4 new file mode 100644 index 0000000..d769f5a Binary files /dev/null and b/Result/2024-03-03/2024-03-03_019.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_020.mp4 b/Result/2024-03-03/2024-03-03_020.mp4 new file mode 100644 index 0000000..6c777c3 Binary files /dev/null and b/Result/2024-03-03/2024-03-03_020.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_021.mp4 b/Result/2024-03-03/2024-03-03_021.mp4 new file mode 100644 index 0000000..77fb31b Binary files /dev/null and b/Result/2024-03-03/2024-03-03_021.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_022.mp4 b/Result/2024-03-03/2024-03-03_022.mp4 new file mode 100644 index 0000000..d6f1b55 Binary files /dev/null and b/Result/2024-03-03/2024-03-03_022.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_023.mp4 b/Result/2024-03-03/2024-03-03_023.mp4 new file mode 100644 index 0000000..e9a225b Binary files /dev/null and b/Result/2024-03-03/2024-03-03_023.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_024.mp4 b/Result/2024-03-03/2024-03-03_024.mp4 new file mode 100644 index 0000000..1fce67e Binary files /dev/null and b/Result/2024-03-03/2024-03-03_024.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_025.mp4 b/Result/2024-03-03/2024-03-03_025.mp4 new file mode 100644 index 0000000..bb2bd43 Binary files /dev/null and b/Result/2024-03-03/2024-03-03_025.mp4 differ diff --git a/Result/2024-03-03/2024-03-03_026.mp4 b/Result/2024-03-03/2024-03-03_026.mp4 new file mode 100644 index 0000000..c444621 Binary files /dev/null and b/Result/2024-03-03/2024-03-03_026.mp4 differ diff --git a/Result/20240301032034.mp4 b/Result/20240301032034.mp4 new file mode 100644 index 0000000..f1790e0 Binary files /dev/null and b/Result/20240301032034.mp4 differ diff --git a/Result/20240301032319.mp4 b/Result/20240301032319.mp4 new file mode 100644 index 0000000..831cc5a Binary files /dev/null and b/Result/20240301032319.mp4 differ diff --git a/Result/20240301181634.mp4 b/Result/20240301181634.mp4 new file mode 100644 index 0000000..527ba4b Binary files /dev/null and b/Result/20240301181634.mp4 differ diff --git a/Result/20240301182242.mp4 b/Result/20240301182242.mp4 new file mode 100644 index 0000000..bcff668 Binary files /dev/null and b/Result/20240301182242.mp4 differ diff --git a/Result/20240302021805.mp4 b/Result/20240302021805.mp4 new file mode 100644 index 0000000..885343f Binary files /dev/null and b/Result/20240302021805.mp4 differ diff --git a/Result/20240302022157.mp4 b/Result/20240302022157.mp4 new file mode 100644 index 0000000..ed30d76 Binary files /dev/null and b/Result/20240302022157.mp4 differ diff --git a/Result/20240302022540.mp4 b/Result/20240302022540.mp4 new file mode 100644 index 0000000..e9b970c Binary files /dev/null and b/Result/20240302022540.mp4 differ diff --git a/Result/20240302023653.mp4 b/Result/20240302023653.mp4 new file mode 100644 index 0000000..1fec99d Binary files /dev/null and b/Result/20240302023653.mp4 differ diff --git a/Result/20240302023812.mp4 b/Result/20240302023812.mp4 new file mode 100644 index 0000000..d6fdaf5 Binary files /dev/null and b/Result/20240302023812.mp4 differ diff --git a/Result/20240302024212.mp4 b/Result/20240302024212.mp4 new file mode 100644 index 0000000..1f315d5 Binary files /dev/null and b/Result/20240302024212.mp4 differ diff --git a/Result/20240302024633.mp4 b/Result/20240302024633.mp4 new file mode 100644 index 0000000..faff763 Binary files /dev/null and b/Result/20240302024633.mp4 differ diff --git a/Result/20240302025224.mp4 b/Result/20240302025224.mp4 new file mode 100644 index 0000000..70ac69e Binary files /dev/null and b/Result/20240302025224.mp4 differ diff --git a/Result/20240302025618.mp4 b/Result/20240302025618.mp4 new file mode 100644 index 0000000..b9877da Binary files /dev/null and b/Result/20240302025618.mp4 differ diff --git a/Result/20240302025939.mp4 b/Result/20240302025939.mp4 new file mode 100644 index 0000000..c89c3ab Binary files /dev/null and b/Result/20240302025939.mp4 differ diff --git a/Result/20240302032013.mp4 b/Result/20240302032013.mp4 new file mode 100644 index 0000000..5e608c9 Binary files /dev/null and b/Result/20240302032013.mp4 differ diff --git a/Result/20240302032408.mp4 b/Result/20240302032408.mp4 new file mode 100644 index 0000000..7416715 Binary files /dev/null and b/Result/20240302032408.mp4 differ diff --git a/Result/20240302_야썰.mp4 b/Result/20240302_야썰.mp4 new file mode 100644 index 0000000..64cd851 Binary files /dev/null and b/Result/20240302_야썰.mp4 differ diff --git a/Result/20240302_참교육.mp4 b/Result/20240302_참교육.mp4 new file mode 100644 index 0000000..98aed04 Binary files /dev/null and b/Result/20240302_참교육.mp4 differ diff --git a/bgm/SellBuyMusic - hiro-out.mp3 b/bgm/SellBuyMusic - hiro-out.mp3 new file mode 100644 index 0000000..389d263 Binary files /dev/null and b/bgm/SellBuyMusic - hiro-out.mp3 differ diff --git a/iluste.png b/iluste.png new file mode 100644 index 0000000..357ac52 Binary files /dev/null and b/iluste.png differ diff --git a/resize_backup.py b/resize_backup.py new file mode 100644 index 0000000..8636e74 --- /dev/null +++ b/resize_backup.py @@ -0,0 +1,165 @@ +resize_possible = True + +try: + # TRY USING OpenCV AS RESIZER + #raise ImportError #debugging + import cv2 + import numpy as np + def resizer (pic, newsize): + lx, ly = int(newsize[0]), int(newsize[1]) + if lx > pic.shape[1] or ly > pic.shape[0]: + # For upsizing use linear for good quality & decent speed + interpolation = cv2.INTER_LINEAR + else: + # For dowsizing use area to prevent aliasing + interpolation = cv2.INTER_AREA + return cv2.resize(+pic.astype('uint8'), (lx, ly), + interpolation=interpolation) + + resizer.origin = "cv2" + +except ImportError: + + + try: + # TRY USING PIL/PILLOW AS RESIZER + from PIL import Image + import numpy as np + def resizer(pic, newsize): + newsize = list(map(int, newsize))[::-1] + shape = pic.shape + if len(shape)==3: + newshape = (newsize[0],newsize[1], shape[2] ) + else: + newshape = (newsize[0],newsize[1]) + + pilim = Image.fromarray(pic) + resized_pil = pilim.resize(newsize[::-1], Image.ANTIALIAS) + #arr = np.fromstring(resized_pil.tostring(), dtype='uint8') + #arr.reshape(newshape) + return np.array(resized_pil) + + resizer.origin = "PIL" + + except ImportError: + # TRY USING SCIPY AS RESIZER + try: + from scipy.misc import imresize + resizer = lambda pic, newsize : imresize(pic, + map(int, newsize[::-1])) + resizer.origin = "Scipy" + + except ImportError: + resize_possible = False + + + + +from moviepy.decorators import apply_to_mask + + +def resize(clip, newsize=None, height=None, width=None, apply_to_mask=True): + """ + Returns a video clip that is a resized version of the clip. + + Parameters + ------------ + + newsize: + Can be either + - ``(width,height)`` in pixels or a float representing + - A scaling factor, like 0.5 + - A function of time returning one of these. + + width: + width of the new clip in pixel. The height is then computed so + that the width/height ratio is conserved. + + height: + height of the new clip in pixel. The width is then computed so + that the width/height ratio is conserved. + + Examples + ---------- + + >>> myClip.resize( (460,720) ) # New resolution: (460,720) + >>> myClip.resize(0.6) # width and heigth multiplied by 0.6 + >>> myClip.resize(width=800) # height computed automatically. + >>> myClip.resize(lambda t : 1+0.02*t) # slow swelling of the clip + + """ + + w, h = clip.size + + if newsize is not None: + + def trans_newsize(ns): + + if isinstance(ns, (int, float)): + return [ns * w, ns * h] + else: + return ns + + if hasattr(newsize, "__call__"): + + newsize2 = lambda t : trans_newsize(newsize(t)) + + if clip.ismask: + + fun = lambda gf,t: (1.0*resizer((255 * gf(t)).astype('uint8'), + newsize2(t))/255) + else: + + fun = lambda gf,t: resizer(gf(t).astype('uint8'), + newsize2(t)) + + return clip.fl(fun, keep_duration=True, + apply_to= (["mask"] if apply_to_mask else [])) + + else: + + newsize = trans_newsize(newsize) + + + elif height is not None: + + if hasattr(height, "__call__"): + fun = lambda t : 1.0*int(height(t))/h + return resize(clip, fun) + + + else: + + newsize = [w * height / h, height] + + elif width is not None: + + if hasattr(width, "__call__"): + fun = lambda t : 1.0*width(t)/w + return resize(clip, fun) + + newsize = [width, h * width / w] + + + # From here, the resizing is constant (not a function of time), size=newsize + + if clip.ismask: + fl = lambda pic: 1.0*resizer((255 * pic).astype('uint8'), newsize)/255.0 + + else: + fl = lambda pic: resizer(pic.astype('uint8'), newsize) + + newclip = clip.fl_image(fl) + + if apply_to_mask and clip.mask is not None: + newclip.mask = resize(clip.mask, newsize, apply_to_mask=False) + + return newclip + + +if not resize_possible: + + doc = resize.__doc__ + def resize(clip, newsize=None, height=None, width=None): + raise ImportError("fx resize needs OpenCV or Scipy or PIL") + resize.__doc__ = doc