mirror of
				https://github.com/chev2/shitpost-video-generator.git
				synced 2025-10-30 08:12:03 +00:00 
			
		
		
		
	Major changes
- Update .gitignore - Rename input and output folders to be lowercase - Add some basic configuration capability - Rename a lot of variables
This commit is contained in:
		
							parent
							
								
									0cef20d304
								
							
						
					
					
						commit
						37b261c668
					
				
					 9 changed files with 268 additions and 198 deletions
				
			
		
							
								
								
									
										35
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							|  | @ -1,22 +1,37 @@ | ||||||
| # Repository-specific | # Repository-specific | ||||||
| VideoSources/*.mp4 | recodevideofiles.py | ||||||
| AudioSources/*.mp3 | *.7z | ||||||
| VideoToBeConverted/*.mp4 |  | ||||||
| RecodeVideoFiles.py |  | ||||||
| 
 | 
 | ||||||
|  | # Video file formats | ||||||
| *.mp4 | *.mp4 | ||||||
|  | *.webm | ||||||
|  | *.mkv | ||||||
|  | *.mov | ||||||
|  | 
 | ||||||
|  | # Audio file formats | ||||||
|  | *.mp3 | ||||||
|  | *.ogg | ||||||
|  | *.wav | ||||||
|  | *.flac | ||||||
| 
 | 
 | ||||||
| # Repository-specific - only allow these video and audio sources | # Repository-specific - only allow these video and audio sources | ||||||
| !VideoSources/DOOR STUCK! DOOR STUCK!.mp4 | !input_video_sources/DOOR STUCK! DOOR STUCK!.mp4 | ||||||
| !VideoSources/FUS RO DAH!!!.mp4 | !input_video_sources/FUS RO DAH!!!.mp4 | ||||||
| !VideoSources/Me at the zoo.mp4 | !input_video_sources/Me at the zoo.mp4 | ||||||
| !AudioSources/BOOM.mp3 | !input_audio_sources/BOOM.mp3 | ||||||
| !AudioSources/Bruh Sound Effect #2.mp3 | !input_audio_sources/Bruh Sound Effect #2.mp3 | ||||||
| !AudioSources/Damn Son.mp3 | !input_audio_sources/Damn Son.mp3 | ||||||
|  | 
 | ||||||
|  | # Linux | ||||||
|  | .directory | ||||||
| 
 | 
 | ||||||
| # Visual Studio Code | # Visual Studio Code | ||||||
| *.code-workspace | *.code-workspace | ||||||
| 
 | 
 | ||||||
|  | # | ||||||
|  | # GitHub Python .gitignore | ||||||
|  | # | ||||||
|  | 
 | ||||||
| # Byte-compiled / optimized / DLL files | # Byte-compiled / optimized / DLL files | ||||||
| __pycache__/ | __pycache__/ | ||||||
| *.py[cod] | *.py[cod] | ||||||
|  |  | ||||||
|  | @ -1,188 +0,0 @@ | ||||||
| import moviepy.audio |  | ||||||
| import random |  | ||||||
| from sys import maxsize |  | ||||||
| from os import listdir |  | ||||||
| from moviepy import editor |  | ||||||
| from moviepy.video import fx |  | ||||||
| 
 |  | ||||||
| videoSourceFolder = "VideoSources" |  | ||||||
| audioSourceFolder = "AudioSources" |  | ||||||
| 
 |  | ||||||
| videoFiles = [videoSourceFolder + "/" + vid for vid in listdir(videoSourceFolder)] |  | ||||||
| audioFiles = [audioSourceFolder + "/" + vid for vid in listdir(audioSourceFolder)] |  | ||||||
| 
 |  | ||||||
| chosenSeed = input("Video seed (or 'any' to use system time): ") |  | ||||||
| while not chosenSeed.isdecimal() and not chosenSeed in ["any", "skip", "default", "time"]: |  | ||||||
|     chosenSeed = input("Video seed (or 'any' to use system time): ") |  | ||||||
| 
 |  | ||||||
| seed = int(chosenSeed) if chosenSeed.isdecimal() else random.randrange(maxsize) #get a chosen or random seed to use and reference later |  | ||||||
| 
 |  | ||||||
| print(f'Chose seed: {seed}') |  | ||||||
| 
 |  | ||||||
| rng = random.Random(seed) |  | ||||||
| 
 |  | ||||||
| print(f'Found {len(videoFiles)} videos and {len(audioFiles)} sounds') |  | ||||||
| 
 |  | ||||||
| def ContinuousFlipVideo(clip): #flip a video multiple times over its duration |  | ||||||
|     flipAmount = rng.randint(1, 7) #how many times the clip will be flipped |  | ||||||
|     flipPeriods = [rng.uniform(0, clip.duration) for _ in range(flipAmount)] #random periods at which to shuffle |  | ||||||
| 
 |  | ||||||
|     flipPeriods.sort() #in ascending order |  | ||||||
|     allClips = [] |  | ||||||
|     lastPeriod = 0 |  | ||||||
| 
 |  | ||||||
|     for period in flipPeriods: |  | ||||||
|         newClip = clip.subclip(lastPeriod, period) |  | ||||||
|         allClips.append(newClip) |  | ||||||
|         lastPeriod = period |  | ||||||
| 
 |  | ||||||
|     newClip = clip.subclip(lastPeriod, clip.duration) |  | ||||||
|     allClips.append(newClip) |  | ||||||
| 
 |  | ||||||
|     for i in range(len(allClips)): |  | ||||||
|         clip = allClips[i] |  | ||||||
|         allClips[i] = rng.choice([fx.mirror_x.mirror_x, fx.mirror_y.mirror_y, lambda v: v])(allClips[i]) #flip on the x, or y, or don't flip |  | ||||||
| 
 |  | ||||||
|     finalClip = editor.concatenate_videoclips(allClips) |  | ||||||
| 
 |  | ||||||
|     return finalClip |  | ||||||
| 
 |  | ||||||
| def RepeatVideo(clip): #repeat a video multiple times |  | ||||||
|     randomDuration = rng.uniform(0.01, 0.2) |  | ||||||
|     repeatAmount = int((clip.duration/randomDuration)*0.5) |  | ||||||
| 
 |  | ||||||
|     startOffset = rng.uniform(0, clip.duration - randomDuration) |  | ||||||
|     newClip = clip.subclip(startOffset, startOffset+randomDuration) |  | ||||||
| 
 |  | ||||||
|     finalClip = editor.concatenate_videoclips([newClip]*repeatAmount) |  | ||||||
|     return finalClip |  | ||||||
| 
 |  | ||||||
| def ShuffleVideo(clip): #take a clip, split it into multiple parts, shuffle those parts |  | ||||||
|     shuffleAmount = rng.randint(20, 50) #how many times the clip will be split and shuffled |  | ||||||
|     shufflePeriods = [rng.uniform(0, clip.duration) for _ in range(shuffleAmount)] #random periods at which to shuffle |  | ||||||
| 
 |  | ||||||
|     shufflePeriods.sort() #in ascending order |  | ||||||
|     allClips = [] |  | ||||||
|     lastPeriod = 0 |  | ||||||
| 
 |  | ||||||
|     for period in shufflePeriods: |  | ||||||
|         newClip = clip.subclip(lastPeriod, period) |  | ||||||
|         allClips.append(newClip) |  | ||||||
|         lastPeriod = period |  | ||||||
| 
 |  | ||||||
|     newClip = clip.subclip(lastPeriod, clip.duration) |  | ||||||
|     allClips.append(newClip) |  | ||||||
|     rng.shuffle(allClips) #shuffle around the clips to get the final result |  | ||||||
|     finalClip = editor.concatenate_videoclips(allClips) |  | ||||||
| 
 |  | ||||||
|     return finalClip |  | ||||||
| 
 |  | ||||||
| videoEffects = [ |  | ||||||
|     lambda v: fx.speedx.speedx(v, rng.uniform(0.7, 3)), #speed up/slow down |  | ||||||
|     lambda v: fx.mirror_x.mirror_x(v), #mirror on the x axis |  | ||||||
|     lambda v: fx.time_mirror.time_mirror(v), #reverse the video |  | ||||||
|     lambda v: v.fx(fx.time_symmetrize.time_symmetrize).fx(fx.speedx.speedx, factor=rng.uniform(1.4, 2.3)), #forward + reverse with speed up |  | ||||||
|     lambda v: RepeatVideo(v), #repeat the video multiple times |  | ||||||
|     lambda v: ShuffleVideo(v), #shuffle up parts of the video for a glitch-like effect |  | ||||||
|     lambda v: ContinuousFlipVideo(v), #flip the video on the x and y axis multiple times |  | ||||||
|     lambda v: fx.lum_contrast.lum_contrast(v, lum=0, contrast=rng.uniform(0.3, 2)) #change contrast |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| videoObjects = [] |  | ||||||
| audioObjects = [] |  | ||||||
| 
 |  | ||||||
| videoAmount = input("Amount of videos: ") |  | ||||||
| while not videoAmount.isdecimal(): |  | ||||||
|     videoAmount = input("Amount of videos: ") |  | ||||||
| 
 |  | ||||||
| videoAmount = int(videoAmount) |  | ||||||
| 
 |  | ||||||
| shouldUseEffects = input("Apply video effects? (y/n): ") |  | ||||||
| while not shouldUseEffects in ["y", "yes", "true", "n", "no", "false"]: |  | ||||||
|     shouldUseEffects = input("Apply video effects? (y/n): ") |  | ||||||
| 
 |  | ||||||
| shouldUseEffects = True if shouldUseEffects in ["y", "yes", "true"] else False |  | ||||||
| 
 |  | ||||||
| randomVideos = rng.sample(videoFiles, min(videoAmount, len(videoFiles))) |  | ||||||
| if videoAmount > len(videoFiles): #if there is a higher chosen amount than total, re-use videos |  | ||||||
|     videoAmountToAdd = videoAmount - len(videoFiles) |  | ||||||
|     print(f'Chosen video amount is higher than available video amount - re-using {videoAmountToAdd} videos...') |  | ||||||
|     additionalVideos = rng.choices(videoFiles, k=videoAmountToAdd) |  | ||||||
|     randomVideos += additionalVideos |  | ||||||
| 
 |  | ||||||
| print(f"Compiling {videoAmount} videos...", end="") |  | ||||||
| 
 |  | ||||||
| for video in randomVideos: |  | ||||||
|     print(".", end="") |  | ||||||
| 
 |  | ||||||
|     newClip = editor.VideoFileClip(video).resize(height=480) #target_resolution=(512, 512) |  | ||||||
| 
 |  | ||||||
|     randomDuration = rng.uniform(0.5, 3.5) #0.5, 2.6 |  | ||||||
|     if newClip.duration > randomDuration: |  | ||||||
|         startOffset = rng.uniform(0, newClip.duration - randomDuration) |  | ||||||
|         newClip = newClip.subclip(startOffset, startOffset+randomDuration) |  | ||||||
| 
 |  | ||||||
|     if rng.choice([True, True, False]) and shouldUseEffects: |  | ||||||
|         newClip = rng.choice(videoEffects)(newClip) #apply a random effect |  | ||||||
| 
 |  | ||||||
|     videoObjects.append(newClip) |  | ||||||
| 
 |  | ||||||
| print("Finished compiling videos.") |  | ||||||
| 
 |  | ||||||
| finalVideo = editor.concatenate_videoclips(videoObjects, method="compose") # method="compose" |  | ||||||
| 
 |  | ||||||
| audioAmount = int(videoAmount*0.75) |  | ||||||
| 
 |  | ||||||
| randomSounds = rng.sample(audioFiles, min(audioAmount, len(audioFiles))) |  | ||||||
| 
 |  | ||||||
| if audioAmount > len(audioFiles): |  | ||||||
|     audioAmountToAdd = audioAmount - len(audioFiles) |  | ||||||
|     print(f'Chosen audio amount is higher than available audio amount - re-using {audioAmountToAdd} audio sources...') |  | ||||||
|     additionalAudio = rng.choices(audioFiles, k=audioAmountToAdd) |  | ||||||
|     randomSounds += additionalAudio |  | ||||||
| 
 |  | ||||||
| print(f"Compiling {audioAmount} sounds...", end="") |  | ||||||
| 
 |  | ||||||
| copiedSoundAmount = 0 |  | ||||||
| for audio in randomSounds: |  | ||||||
|     print(".", end="") |  | ||||||
| 
 |  | ||||||
|     newClip = editor.AudioFileClip(audio) |  | ||||||
|     newClip = moviepy.audio.fx.volumex.volumex(newClip, 0.5) # modify volume |  | ||||||
| 
 |  | ||||||
|     if newClip.duration > 5: #for long clips |  | ||||||
|         randomDuration = rng.uniform(0.7, 13) # crop audio duration |  | ||||||
|         if newClip.duration > randomDuration: # if the audio is longer than the cropped duration, crop the audio at a random position |  | ||||||
|             startOffset = rng.choice([rng.uniform(0, newClip.duration - randomDuration), 0]) #either use a random offset, or start at beginning of audio clip |  | ||||||
|             newClip = newClip.subclip(startOffset, startOffset+randomDuration) |  | ||||||
| 
 |  | ||||||
|         newClip = newClip.set_start(rng.uniform(0, finalVideo.duration-newClip.duration)) # move audio around video length |  | ||||||
|         audioObjects.append(newClip) |  | ||||||
|     else: |  | ||||||
|         clipPosition = rng.uniform(0, finalVideo.duration-newClip.duration) |  | ||||||
| 
 |  | ||||||
|         newClip = newClip.set_start(clipPosition) # move audio around video length |  | ||||||
|         audioObjects.append(newClip) |  | ||||||
|         for i in range(rng.randint(1, 5)): #add a copy of the clip near the original clip |  | ||||||
|             print(".", end="") |  | ||||||
|             copiedSoundAmount += 1 |  | ||||||
| 
 |  | ||||||
|             minimumRange = max(0, clipPosition-2) |  | ||||||
|             maximumRange = min(finalVideo.duration, clipPosition+2) - newClip.duration |  | ||||||
| 
 |  | ||||||
|             copiedClip = newClip.set_start(rng.uniform(minimumRange, maximumRange)) # move audio around video length |  | ||||||
|             audioObjects.append(copiedClip) |  | ||||||
| 
 |  | ||||||
| print(f"Finished compiling audio. Added {copiedSoundAmount} duplicate sounds, total {audioAmount+copiedSoundAmount}.") |  | ||||||
| 
 |  | ||||||
| newAudioClip = editor.CompositeAudioClip([finalVideo.audio] + audioObjects) |  | ||||||
| 
 |  | ||||||
| finalVideoFilename = f'final_result_{seed}_{videoAmount}{"_effects" if shouldUseEffects else ""}.mp4' |  | ||||||
| 
 |  | ||||||
| finalVideo.audio = newAudioClip |  | ||||||
| finalVideo.write_videofile(finalVideoFilename, fps=30, audio_bitrate="96k") |  | ||||||
| 
 |  | ||||||
| for video in videoObjects: |  | ||||||
|     video.close() |  | ||||||
| for audio in audioObjects: |  | ||||||
|     audio.close() |  | ||||||
							
								
								
									
										243
									
								
								main.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										243
									
								
								main.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,243 @@ | ||||||
|  | import moviepy.audio | ||||||
|  | import random | ||||||
|  | from sys import maxsize | ||||||
|  | from os import listdir, mkdir, path | ||||||
|  | from moviepy import editor | ||||||
|  | from moviepy.video import fx | ||||||
|  | 
 | ||||||
|  | ''' | ||||||
|  |     TODO: | ||||||
|  |         flash random images in short bursts at long intervals | ||||||
|  |         try to overlap videos more and distort them | ||||||
|  |         spread out audio duplication a bit, so they don't end up directly next to one another | ||||||
|  | 
 | ||||||
|  | ''' | ||||||
|  | 
 | ||||||
|  | videoSourceFolder = "input_video_sources" | ||||||
|  | audioSourceFolder = "input_audio_sources" | ||||||
|  | 
 | ||||||
|  | videoFiles = [videoSourceFolder + "/" + vid for vid in listdir(videoSourceFolder)] | ||||||
|  | audioFiles = [audioSourceFolder + "/" + vid for vid in listdir(audioSourceFolder)] | ||||||
|  | 
 | ||||||
|  | video_clip_times = (1.0, 2.5) #default: 0.5, 3.5. chaos: 0.3, 1.2 | ||||||
|  | audio_clip_times = (0.7, 3) #default: 0.7, 13. chaos: 0.7, 3.0 | ||||||
|  | 
 | ||||||
|  | audio_multiplier = 1.5 #audio amount multiplier (based off the amount of videos), e.g. 60 videos with a multiplier of 0.75 means 45 audio cues. default: 0.75. chaos: 1.5 | ||||||
|  | 
 | ||||||
|  | #(min, max) random values range, inclusive | ||||||
|  | continuous_flip_amount = (7, 14) #integer. default: 1, 7 | ||||||
|  | repeat_video_amount = (0.01, 0.2) #float. default: 0.01, 0.2 | ||||||
|  | shuffle_video_amount = (20, 50) #integer. default: 20, 50 | ||||||
|  | flip_rotation_amount = (1, 4) #integer. default: 1, 4 | ||||||
|  | random_speed_amount = (0.7, 3) #float. default: 0.7, 3 | ||||||
|  | contrast_amount = (0.3, 2) #float. default: 0.3, 2 | ||||||
|  | 
 | ||||||
|  | chosenSeed = input("Video seed (or 'any' to use system time): ") | ||||||
|  | while not chosenSeed.isdecimal() and not chosenSeed in ["any", "skip", "default", "time"]: | ||||||
|  |     chosenSeed = input("Video seed (or 'any' to use system time): ") | ||||||
|  | 
 | ||||||
|  | seed = int(chosenSeed) if chosenSeed.isdecimal() else random.randrange(maxsize) #get a chosen or random seed to use and reference later | ||||||
|  | 
 | ||||||
|  | print(f'Chose seed: {seed}') | ||||||
|  | 
 | ||||||
|  | rng = random.Random(seed) | ||||||
|  | 
 | ||||||
|  | print(f'Found {len(videoFiles)} videos and {len(audioFiles)} sounds') | ||||||
|  | 
 | ||||||
|  | # Returns a progress bar string, useful for measuring progress in command-line | ||||||
|  | def ProgressBar(current_index, max_index, progress_bar_len:int = 20, include_percent:bool = True, percent_digits:int = 2, | ||||||
|  |                 symbol_middle:str = "█", symbol_begin:str = "|", symbol_end:str = "|"): | ||||||
|  |     # Used for the progress bar - gets progress 0-1 range, | ||||||
|  |     # then multiplies it by the progress bar length | ||||||
|  |     percent_done = int(current_index / max_index * progress_bar_len) | ||||||
|  | 
 | ||||||
|  |     percentage = f" {round((current_index / max_index) * 100, percent_digits)}%" if include_percent else "" | ||||||
|  | 
 | ||||||
|  |     return symbol_begin + (symbol_middle * percent_done + " " * (progress_bar_len - percent_done)) + symbol_end + percentage | ||||||
|  | 
 | ||||||
|  | def ContinuousFlipVideo(clip): #flip a video multiple times over its duration | ||||||
|  |     flip_amt = rng.randint(*continuous_flip_amount) #how many times the clip will be flipped | ||||||
|  |     flip_periods = [rng.uniform(0, clip.duration) for _ in range(flip_amt)] #random periods at which to shuffle | ||||||
|  | 
 | ||||||
|  |     flip_periods.sort() #in ascending order | ||||||
|  |     all_clips = [] | ||||||
|  |     last_period = 0 | ||||||
|  | 
 | ||||||
|  |     for period in flip_periods: | ||||||
|  |         new_clip = clip.subclip(last_period, period) | ||||||
|  |         all_clips.append(new_clip) | ||||||
|  |         last_period = period | ||||||
|  | 
 | ||||||
|  |     new_clip = clip.subclip(last_period, clip.duration) | ||||||
|  |     all_clips.append(new_clip) | ||||||
|  | 
 | ||||||
|  |     for i in range(len(all_clips)): | ||||||
|  |         clip = all_clips[i] | ||||||
|  |         all_clips[i] = rng.choice([fx.mirror_x.mirror_x, fx.mirror_y.mirror_y, lambda v: v])(all_clips[i]) #flip on the x, or y, or don't flip | ||||||
|  | 
 | ||||||
|  |     final_clip = editor.concatenate_videoclips(all_clips) | ||||||
|  | 
 | ||||||
|  |     return final_clip | ||||||
|  | 
 | ||||||
|  | def RepeatVideo(clip): #repeat a video multiple times | ||||||
|  |     random_dur = rng.uniform(*repeat_video_amount) | ||||||
|  |     repeat_amt = int((clip.duration/random_dur)*0.5) | ||||||
|  | 
 | ||||||
|  |     start_offset = rng.uniform(0, clip.duration - random_dur) | ||||||
|  |     new_clip = clip.subclip(start_offset, start_offset+random_dur) | ||||||
|  | 
 | ||||||
|  |     final_clip = editor.concatenate_videoclips([new_clip]*repeat_amt) | ||||||
|  |     return final_clip | ||||||
|  | 
 | ||||||
|  | def ShuffleVideo(clip): #take a clip, split it into multiple parts, shuffle those parts | ||||||
|  |     shuffle_amt = rng.randint(*shuffle_video_amount) #how many times the clip will be split and shuffled | ||||||
|  |     shuffle_periods = [rng.uniform(0, clip.duration) for _ in range(shuffle_amt)] #random periods at which to shuffle | ||||||
|  | 
 | ||||||
|  |     shuffle_periods.sort() #in ascending order | ||||||
|  |     all_clips = [] | ||||||
|  |     last_period = 0 | ||||||
|  | 
 | ||||||
|  |     for period in shuffle_periods: | ||||||
|  |         new_clip = clip.subclip(last_period, period) | ||||||
|  |         all_clips.append(new_clip) | ||||||
|  |         last_period = period | ||||||
|  | 
 | ||||||
|  |     new_clip = clip.subclip(last_period, clip.duration) | ||||||
|  |     all_clips.append(new_clip) | ||||||
|  |     rng.shuffle(all_clips) #shuffle around the clips to get the final result | ||||||
|  |     final_clip = editor.concatenate_videoclips(all_clips) | ||||||
|  | 
 | ||||||
|  |     return final_clip | ||||||
|  | 
 | ||||||
|  | def FlipRotationVideo(clip): #makes the clip "rotate" by flipping and reversing the second part of the clip | ||||||
|  |     random_duration = rng.uniform(0.1, 0.3) | ||||||
|  | 
 | ||||||
|  |     start_offset = rng.uniform(0, clip.duration - random_duration) | ||||||
|  |     first_clip = clip.subclip(start_offset, start_offset+random_duration) | ||||||
|  | 
 | ||||||
|  |     second_clip = fx.time_mirror.time_mirror(fx.mirror_x.mirror_x(first_clip.copy())) #flip horizontal, then reverse video | ||||||
|  | 
 | ||||||
|  |     both_clips = [fx.speedx.speedx(first_clip, 1.5), fx.speedx.speedx(second_clip, 1.5)] | ||||||
|  | 
 | ||||||
|  |     return editor.concatenate_videoclips(both_clips*random.randint(*flip_rotation_amount)) | ||||||
|  | 
 | ||||||
|  | videoEffects = [ | ||||||
|  |     lambda v: fx.speedx.speedx(v, rng.uniform(*random_speed_amount)), #speed up/slow down | ||||||
|  |     lambda v: fx.mirror_x.mirror_x(v), #mirror on the x axis | ||||||
|  |     lambda v: fx.time_mirror.time_mirror(v), #reverse the video | ||||||
|  |     lambda v: v.fx(fx.time_symmetrize.time_symmetrize).fx(fx.speedx.speedx, factor=rng.uniform(1.4, 2.3)), #forward + reverse with speed up | ||||||
|  |     lambda v: RepeatVideo(v), #repeat the video multiple times | ||||||
|  |     lambda v: ShuffleVideo(v), #shuffle up parts of the video for a glitch-like effect | ||||||
|  |     lambda v: ContinuousFlipVideo(v), #flip the video on the x and y axis multiple times | ||||||
|  |     lambda v: FlipRotationVideo(v), | ||||||
|  |     lambda v: fx.lum_contrast.lum_contrast(v, lum=0, contrast=rng.uniform(*contrast_amount)) #change contrast | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | videoObjects = [] | ||||||
|  | audioObjects = [] | ||||||
|  | 
 | ||||||
|  | videoAmount = input("Amount of videos: ") | ||||||
|  | while not videoAmount.isdecimal(): | ||||||
|  |     videoAmount = input("Amount of videos: ") | ||||||
|  | 
 | ||||||
|  | videoAmount = int(videoAmount) | ||||||
|  | 
 | ||||||
|  | shouldUseEffects = input("Apply video effects? (y/n): ") | ||||||
|  | while not shouldUseEffects.lower() in ["y", "yes", "true", "n", "no", "false"]: | ||||||
|  |     shouldUseEffects = input("Apply video effects? (y/n): ") | ||||||
|  | 
 | ||||||
|  | shouldUseEffects = True if shouldUseEffects.lower() in ["y", "yes", "true"] else False | ||||||
|  | 
 | ||||||
|  | randomVideos = rng.sample(videoFiles, min(videoAmount, len(videoFiles))) | ||||||
|  | #randomVideos = rng.choices(videoFiles, k=min(videoAmount, len(videoFiles))) | ||||||
|  | if videoAmount > len(videoFiles): #if there is a higher chosen amount than total, re-use videos | ||||||
|  |     videoAmountToAdd = videoAmount - len(videoFiles) | ||||||
|  |     print(f'Chosen video amount is higher than available video amount - re-using {videoAmountToAdd} videos...') | ||||||
|  |     additionalVideos = rng.choices(videoFiles, k=videoAmountToAdd) | ||||||
|  |     randomVideos += additionalVideos | ||||||
|  | 
 | ||||||
|  | print(f"Compiling {videoAmount} videos... ", end="\r") | ||||||
|  | 
 | ||||||
|  | for index, video in enumerate(randomVideos): | ||||||
|  |     print(f"Compiling {videoAmount} videos... {ProgressBar(index, len(randomVideos), progress_bar_len=40)}", end="\r") | ||||||
|  | 
 | ||||||
|  |     newClip = editor.VideoFileClip(video).resize(height=480) #target_resolution=(512, 512) | ||||||
|  | 
 | ||||||
|  |     randomDuration = rng.uniform(*video_clip_times) | ||||||
|  |     if newClip.duration > randomDuration: | ||||||
|  |         startOffset = rng.uniform(0, newClip.duration - randomDuration) | ||||||
|  |         newClip = newClip.subclip(startOffset, startOffset+randomDuration) | ||||||
|  | 
 | ||||||
|  |     if rng.choice([True, True, False]) and shouldUseEffects: | ||||||
|  |         newClip = rng.choice(videoEffects)(newClip) #apply a random effect | ||||||
|  | 
 | ||||||
|  |     videoObjects.append(newClip) | ||||||
|  | 
 | ||||||
|  | print(f"Compiling {videoAmount} videos... {ProgressBar(1, 1, progress_bar_len=40)}") | ||||||
|  | print("Finished compiling videos.") | ||||||
|  | 
 | ||||||
|  | finalVideo = editor.concatenate_videoclips(videoObjects, method="compose") # method="compose" | ||||||
|  | 
 | ||||||
|  | audioAmount = int(videoAmount*audio_multiplier) | ||||||
|  | 
 | ||||||
|  | randomSounds = rng.sample(audioFiles, min(audioAmount, len(audioFiles))) | ||||||
|  | 
 | ||||||
|  | if audioAmount > len(audioFiles): | ||||||
|  |     audioAmountToAdd = audioAmount - len(audioFiles) | ||||||
|  |     print(f'Chosen audio amount is higher than available audio amount - re-using {audioAmountToAdd} audio sources...') | ||||||
|  |     additionalAudio = rng.choices(audioFiles, k=audioAmountToAdd) | ||||||
|  |     randomSounds += additionalAudio | ||||||
|  | 
 | ||||||
|  | print(f"Compiling {audioAmount} sounds...", end="\r") | ||||||
|  | 
 | ||||||
|  | copiedSoundAmount = 0 | ||||||
|  | for index, audio in enumerate(randomSounds): | ||||||
|  |     print(f"Compiling {audioAmount} sounds... {ProgressBar(index, len(randomSounds), progress_bar_len=40)}", end="\r") | ||||||
|  | 
 | ||||||
|  |     newClip = editor.AudioFileClip(audio) | ||||||
|  |     newClip = moviepy.audio.fx.volumex.volumex(newClip, 0.8) # modify volume | ||||||
|  | 
 | ||||||
|  |     if newClip.duration > 5: #for long clips | ||||||
|  |         randomDuration = rng.uniform(*audio_clip_times) # crop audio duration | ||||||
|  |         if newClip.duration > randomDuration: # if the audio is longer than the cropped duration, crop the audio at a random position | ||||||
|  |             startOffset = rng.choice([rng.uniform(0, newClip.duration - randomDuration), 0]) #either use a random offset, or start at beginning of audio clip | ||||||
|  |             newClip = newClip.subclip(startOffset, startOffset+randomDuration) | ||||||
|  | 
 | ||||||
|  |         newClip = newClip.set_start(rng.uniform(0, finalVideo.duration-newClip.duration)) # move audio around video length | ||||||
|  |         audioObjects.append(newClip) | ||||||
|  |     else: | ||||||
|  |         # Place to position the audio clip - could be anywhere from the final video's start all the way to its full duration | ||||||
|  |         clipPosition = rng.uniform(0, finalVideo.duration-newClip.duration) | ||||||
|  | 
 | ||||||
|  |         newClip = newClip.set_start(clipPosition) # move audio around video length | ||||||
|  |         audioObjects.append(newClip) | ||||||
|  | 
 | ||||||
|  |         # Add duplicates of this audio clip | ||||||
|  |         for i in range(rng.randint(1, 5)): | ||||||
|  |             copiedSoundAmount += 1 | ||||||
|  | 
 | ||||||
|  |             # Max 0 and clip position - 2 so it doesn't go into negative clip position (if near beginning of video) | ||||||
|  |             minimumRange = max(0, clipPosition - 2) | ||||||
|  |             # Minimum between final video duration and clip position + 2 so it doesn't go over video length (if near end of video) | ||||||
|  |             maximumRange = min(finalVideo.duration, clipPosition + 2) - newClip.duration | ||||||
|  | 
 | ||||||
|  |             copiedClip = newClip.set_start(rng.uniform(minimumRange, maximumRange)) # move audio around video length | ||||||
|  |             audioObjects.append(copiedClip) | ||||||
|  | 
 | ||||||
|  | print(f"Compiling {audioAmount} sounds... {ProgressBar(1, 1, progress_bar_len=40)}") | ||||||
|  | print(f"Finished compiling audio. Added {copiedSoundAmount} duplicate sounds, total {audioAmount+copiedSoundAmount}.") | ||||||
|  | 
 | ||||||
|  | # The video's filename | ||||||
|  | finalVideoFilename = f'output/result_seed-{seed}_{videoAmount}{"_effects" if shouldUseEffects else ""}.mp4' | ||||||
|  | 
 | ||||||
|  | # Create output directory if it doesn't exist | ||||||
|  | if not path.exists("output"): mkdir("output") | ||||||
|  | 
 | ||||||
|  | finalVideo.audio = editor.CompositeAudioClip([finalVideo.audio] + audioObjects) | ||||||
|  | finalVideo.write_videofile(finalVideoFilename, fps=30, audio_bitrate="96k") | ||||||
|  | 
 | ||||||
|  | # Close all file streams | ||||||
|  | for video in videoObjects: | ||||||
|  |     video.close() | ||||||
|  | for audio in audioObjects: | ||||||
|  |     audio.close() | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue