def main(): scriptname = path.basename(__file__) log(scriptname) print( "(Although the prompt asks for a YT link, a path to a local video file can also be used)" ) youtube_link = None while youtube_link == None: value = input("Link to YT video/path to video file: ") # Valid Youtube link if "youtube.com/watch?v=" in value or "youtu.be/" in value: log("debug", "Mode", "Downloading file from Youtube") youtube_link = value # Valid local file elif path.isfile(value): filename = value filedir = path.join( path.dirname(filename), "Clips {0} {1}\\".format( path.splitext(path.basename(filename))[0], functions.current_datetime)) # Move logfile & cleanup rename(functions.video_output_dir, filedir) functions.video_output_dir = filedir functions.video_output_path = filename log("debug", "Mode", "Using local file") log("debug", "video_output_dir", functions.video_output_dir) log("debug", "video_output_path", functions.video_output_path) # Set title in Windows console if name == "nt": system("title {0}".format(path.basename(filename))) return else: print("{0} is not a valid youtube url (nor a file on your HDD)". format(value)) log("debug", "youtube_link", youtube_link) ydl_opts = { "logger": ydlLogger(), "progress_hooks": [ydl_hook], "format": "bestvideo+bestaudio", "outtmpl": functions.video_output_dir + "%(title)s.%(ext)s", } log("debug", "ydl_opts", ydl_opts) print("Downloading...") with YoutubeDL(ydl_opts) as ydl: try: info = ydl.extract_info(youtube_link) # After download, FFMPEG converts the file depending on the format from ydl_opts # However, this is not consistently to the same format, nor does it appear in prepare_filename # Hence: discover the extension # output vars are gotten from ydl output_path = ydl.prepare_filename( info) # output/*-*-*--*-*-*/{videofilename}.{ext} output_dirname = path.dirname(output_path) # output/*-*-*--*-*-*/ output_videoname = path.splitext( path.basename(output_path))[0] # {videofilename} (no ext) output_filename = path.basename( glob(path.join(output_dirname, output_videoname + "*"))[0]) # {videofilename}.{ext} output_videoname = sub( "[^a-zA-Z0-9 \"'-]", "", output_videoname).replace( " ", " ") # Clean filename for use in folder name # Set title in Windows console if name == "nt": system("title {0}".format(output_videoname)) # Create new dirname for video file new_video_output_dir = functions.video_output_dir.replace( functions.current_datetime, "{0} {1}".format(output_videoname, functions.current_datetime)) # Apply new dirname to global vars functions.video_output_dir = new_video_output_dir functions.video_output_path = new_video_output_dir + output_filename rename(output_dirname, functions.video_output_dir) log("debug", "output_path", output_path) log("debug", "video_output_dir", functions.video_output_dir) log("debug", "video_output_path", functions.video_output_path) # Write source.txt with original youtube link, title and uploader. Give credit where it's due! with open(new_video_output_dir + "/../sources.txt", "a+", encoding="utf-8") as sources: line = "" seperator = " - " for data in [info["title"], info["uploader"], youtube_link]: line += data + " - " line = line.strip(seperator) sources.write(line + "\n") except DownloadError as e: log("error", "DownloadError", e)
def error(self, msg): log("error", "ydlLogger", msg)
def debug(self, msg): log("debug", "ydlLogger", msg)
def warning(self, msg): log("warning", "ydlLogger", msg)
def main(): scriptname = path.basename(__file__) log(scriptname) log("debug", "functions.video_output_path", functions.video_output_path) choosing_clips = True chosen_clips = [] threads = [] print( "Do you want to generate random clips, or set a specific start and endtime?" ) mode = prompt_mode() print("Insert desired clip {0} in mm:ss or seconds".format( "length" if mode == random else "start")) print( "You can make as many clips as liked, leave clip length empty (just press ENTER) to stop making clips" ) while choosing_clips: clip_length_or_start = prompt_time(mode.clip_length_prompt) # If no value returned, finish clipping # Do note: 0 is also a False value, so double check that the clip_length_or_start isn't 0 when stopping the clipping process if clip_length_or_start == False and str(clip_length_or_start) != str( float(0)): log("debug", "clip_length_or_start", "\"{0}\", done clipping".format(clip_length_or_start)) choosing_clips = False else: from moviepy.editor import VideoFileClip full_video = VideoFileClip(functions.video_output_path) full_duration = full_video.duration log("debug", "full_duration", full_duration) if mode == random: clip_start, clip_end = random_subclip(clip_length_or_start, chosen_clips, full_duration) if clip_start == False or clip_end == False: # If no valid clip could be found, prompt again continue elif mode == exact: if clip_length_or_start > full_duration: print( "The start of the clip has to be smaller than the video's full duration" ) continue clip_start, clip_end = exact_subclip(mode, clip_length_or_start) if clip_end > full_duration: print( "The end of the clip has to be smaller than the video's full duration" ) continue if clip_end <= clip_start: print( "The end of the clip has to be larger than the start of the clip" ) continue log("debug", "clip_start", clip_start) log("debug", "clip_end", clip_end) clip = full_video.subclip(clip_start, clip_end) if (clip_end - clip_start) > 10: print( "The application will now show the first 5 and last 5 seconds of the clip" ) clip.subclip(0, 5).preview() clip.subclip(clip.duration - 5, clip.duration).preview() else: print( "Since this is a short clip, it will be viewed in its entirety" ) clip.preview() clip_approved = input( "Is this clip good? (y or empty if Yes, n if no): ").lower( ).strip() if clip_approved in ["", "y", "ye", "yes", "ys"]: clip_filename, clip_ext = path.splitext( path.basename(functions.video_output_path)) # clip_ext includes '.' chosen_clips.append((clip_start, clip_end)) clip_path = functions.video_output_dir +\ "clip {0} ({1}-{2}) {3}{4}".format(len(chosen_clips), clip_start, clip_end, clip_filename, clip_ext) write_videofile = Thread(target=write_video, args=(clip, clip_path)) print( "Clip selected, writing in the background. Feel free to continue making clips!" ) write_videofile.start() threads.append(write_videofile) print("Making sure all clips are finished writing") for i in range(0, len(threads)): print("Waiting for thread {0}...".format(i)) threads[i].join() print("Thread {0} done!".format(i)) # Startfile only works in Windows if name == "nt": from os import startfile log("debug", "os", "Windows, opening output in explorer") startfile(path.realpath(functions.video_output_dir)) log("debug", "status", "done")