diff --git a/.gitignore b/.gitignore index 596b761..fd879af 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,8 @@ *.pyc +.idea + +mugen/testing.py + output/ segments/ rejected_segments/ diff --git a/README.md b/README.md index f9ef72b..46b0587 100644 --- a/README.md +++ b/README.md @@ -37,18 +37,18 @@ Below, an installation walthrough is provided for Mac OS X to give you a better ## Installation Walkthrough (Mac OS X) -**1 - [Install Miniconda 3.5](http://conda.pydata.org/miniconda.html) (A Python virtual environment and package manager)** +**1 - [Install Homebrew](http://brew.sh/) (General purpose package manager for mac)** -**2 - [Install Homebrew](http://brew.sh/) (General purpose package manager for mac)** +**2 - [Install Miniconda 3.5](http://conda.pydata.org/miniconda.html) (A Python virtual environment and package manager)** -**3 - Ensure Miniconda & Homebrew are at top of path by appending below text to `~/.bash_profile`** +**3 - Ensure Homebrew & Miniconda are at top of path by appending below text to `~/.bash_profile`** ``` -#Homebrew -export PATH=/usr/local/bin:/usr/local/sbin:$PATH - #Miniconda export PATH="~/miniconda/bin:$PATH" + +#Homebrew +export PATH=/usr/local/bin:/usr/local/sbin:$PATH ``` **4 - [Install tesseract](https://github.com/tesseract-ocr/tesseract) via Homebrew** diff --git a/mugen/audio/audio.py b/mugen/audio/audio.py index 9c00f08..aa9ac10 100644 --- a/mugen/audio/audio.py +++ b/mugen/audio/audio.py @@ -1,4 +1,3 @@ -import sys import shutil import pprint import logging diff --git a/mugen/audio/utility.py b/mugen/audio/utility.py index 046b3d0..077af3b 100644 --- a/mugen/audio/utility.py +++ b/mugen/audio/utility.py @@ -9,5 +9,5 @@ def load_audio(audio_file): print("Error reading audio file '{}'. Cannot continue. Error: {}".format(audio_file, e)) sys.exit(1) else: - audio = loader() - return audio + audio = loader() + return audio diff --git a/mugen/make_music_video.py b/mugen/make_music_video.py index c58665b..ce2ac9e 100644 --- a/mugen/make_music_video.py +++ b/mugen/make_music_video.py @@ -175,7 +175,7 @@ def parse_args(args): common_parser.add_argument('-db', '--debug', dest='debug', action='store_true', default=False, help='Pass in this argument to print useful debug info and save all rejected segments.') # Video Common Parameters - video_parser.add_argument('-o', '--output-name', dest='output_name', help='The name for the music video. Otherwise will output music_video_0' + s.OUTPUT_EXTENSION + ', music_video_1' + s.OUTPUT_EXTENSION + ', etc...') + video_parser.add_argument('-o', '--output-name', dest='output_name', help='The name for the music video. Otherwise will output ' + s.MUSIC_VIDEO_NAME_DEFAULT + '_0' + s.VIDEO_OUTPUT_EXTENSION + ', ' + s.MUSIC_VIDEO_NAME_DEFAULT + '_1' + s.VIDEO_OUTPUT_EXTENSION + ', etc...') video_parser.add_argument('-crf', '--crf', dest='crf', type=int, default=s.music_video_crf, help='The crf quality value for the music video. Takes an integer from 0 (lossless) to 51 (lossy). Defaults to 18.') video_parser.add_argument('-vd', '--video-dimensions', dest='video_dimensions', type=int, nargs=2, help='Pass in this argument to manually set the pixel dimensions for the music video, width and height. All video segments will be resized (cropped and/or scaled) appropriately to match these dimensions. Otherwise, the best dimensions for the music video are calculated automatically. Takes width then height integer values separated by spaces e.g., 1920 1080') video_parser.add_argument('-pvd', '--preserve-video-dimensions', dest='preserve_video_dimensions', action='store_true', default=False, help='Pass in this argument to preserve the various screen dimensions of the videos, and not perform any resizing.') diff --git a/mugen/settings.py b/mugen/settings.py index 759620a..b8aeb0a 100644 --- a/mugen/settings.py +++ b/mugen/settings.py @@ -9,9 +9,9 @@ VERSION = "1.0" HELP = " Please review supported inputs and values on the help menu via --help" -FILE_TYPE_AUDIO = "audio" +FILE_TYPE_AUDIO = 'audio' FILE_TYPE_VIDEO = 'video' -FILE_TYPE_SPEC = "spec" +FILE_TYPE_SPEC = 'spec' ### VIDEO ### WIDESCREEN_ASPECT_RATIO = 16/float(9) @@ -34,21 +34,22 @@ AUDIO_TRACK_BEAT_LOCATIONS = 'beat_locations' SUBS_TRACK_SEGMENT_NUMBERS = 'segment_numbers' SUBS_TRACK_SEGMENT_DURATIONS = 'segment_durations' -SUBS_TRACK_SPEC ='spec' +SUBS_TRACK_SPEC = 'spec' ### PATHS ### TEMP_PATH_BASE = 'temp/' +TEMP_MOVIEPY_AUDIOFILE = TEMP_PATH_BASE + 'moviepy_temp_audio.mp3' OUTPUT_PATH_BASE = 'output/' -OUTPUT_NAME_DEFAULT = 'music_video' -OUTPUT_EXTENSION = '.mkv' +MUSIC_VIDEO_NAME_DEFAULT = 'music_video' +VIDEO_OUTPUT_EXTENSION = '.mkv' SUBTITLES_EXTENSION = '.srt' SPEC_EXTENSION = '.json' ESSENTIA_ONSETS_AUDIO_EXTENSION = '.wav' SEGMENTS_PATH_BASE = OUTPUT_PATH_BASE + 'segments/' RS_PATH_BASE = OUTPUT_PATH_BASE + 'rejected_segments/' -RS_PATH_REPEAT = RS_PATH_BASE + RS_TYPE_REPEAT +'/' +RS_PATH_REPEAT = RS_PATH_BASE + RS_TYPE_REPEAT + '/' RS_PATH_SCENE_CHANGE = RS_PATH_BASE + RS_TYPE_SCENE_CHANGE + '/' RS_PATH_TEXT_DETECTED = RS_PATH_BASE + RS_TYPE_TEXT_DETECTED + '/' -RS_PATH_SOLID_COLOR = RS_PATH_BASE + RS_TYPE_SOLID_COLOR +'/' \ No newline at end of file +RS_PATH_SOLID_COLOR = RS_PATH_BASE + RS_TYPE_SOLID_COLOR + '/' \ No newline at end of file diff --git a/mugen/utility.py b/mugen/utility.py index 0c31eee..1f0c843 100644 --- a/mugen/utility.py +++ b/mugen/utility.py @@ -6,7 +6,6 @@ import Tkinter as tk import tkFileDialog import subprocess as sp -from fractions import Fraction from collections import OrderedDict # Project modules @@ -21,7 +20,7 @@ def get_music_video_name(output_name, is_regenerated): count = 0 while True: music_video_name = 'regenerated_' if is_regenerated else "" - music_video_name += s.OUTPUT_NAME_DEFAULT + "_%s" % count + music_video_name += s.MUSIC_VIDEO_NAME_DEFAULT + "_%s" % count if not os.path.exists(get_output_path(music_video_name)): break else: @@ -107,10 +106,10 @@ def get_files(file_type, *sources): files.extend([file.encode('utf-8') for file in source]) if len(files) == 0: - print("No {} files were selected.".format(file_type, source)) + print("No {} files were selected.".format(file_type)) sys.exit(1) - logging.debug("{}_source {}".format(file_type, source)) + logging.debug("{}_source {}".format(file_type, sources)) for file in files: logging.debug("{}_file: {}".format(file_type, file)) return files @@ -166,7 +165,7 @@ def get_segments_dir(music_video_name): return s.SEGMENTS_PATH_BASE + music_video_name + '/' def get_output_path(music_video_name): - return s.OUTPUT_PATH_BASE + music_video_name + s.OUTPUT_EXTENSION + return s.OUTPUT_PATH_BASE + music_video_name + s.VIDEO_OUTPUT_EXTENSION def get_spec_path(music_video_name): return s.OUTPUT_PATH_BASE + music_video_name + '_spec' + s.SPEC_EXTENSION @@ -175,7 +174,7 @@ def get_audio_preview_path(audio_file): return s.OUTPUT_PATH_BASE + filename_from_path(audio_file) + "_marked_audio_preview" + s.ESSENTIA_ONSETS_AUDIO_EXTENSION def get_temp_output_path(music_video_name): - return s.TEMP_PATH_BASE + 'temp_' + music_video_name + s.OUTPUT_EXTENSION + return s.TEMP_PATH_BASE + 'temp_' + music_video_name + s.VIDEO_OUTPUT_EXTENSION def get_temp_subtitle_path(music_video_name, track_type): return s.TEMP_PATH_BASE + music_video_name + '_' + track_type + '_subs' + s.SUBTITLES_EXTENSION @@ -184,7 +183,7 @@ def get_temp_audio_onsets_path(audio_file): return s.TEMP_PATH_BASE + filename_from_path(audio_file) + '_marked_audio' + s.ESSENTIA_ONSETS_AUDIO_EXTENSION def get_temp_audio_offset_path(audio_file): - return s.TEMP_PATH_BASE + music_video_name + '_offset_audio' + os.path.splitext(audio_file)[1] + return s.TEMP_PATH_BASE + filename_from_path(audio_file) + '_offset_audio' + os.path.splitext(audio_file)[1] def filename_from_path(path): """ diff --git a/mugen/video/io.py b/mugen/video/io.py index 8d20fa3..7391884 100644 --- a/mugen/video/io.py +++ b/mugen/video/io.py @@ -20,7 +20,7 @@ def save_video_segments(video_segments): count = 0 for video_segment in video_segments: - segment_path = segments_dir + "%s" % count + s.OUTPUT_EXTENSION + segment_path = segments_dir + "%s" % count + s.VIDEO_OUTPUT_EXTENSION video_segment.write_videofile(segment_path, fps=s.MOVIEPY_FPS, codec=s.MOVIEPY_CODEC, ffmpeg_params=['-crf', s.music_video_crf]) count += 1 @@ -44,22 +44,22 @@ def save_rejected_segments(rejected_segments): video_segment = rejected_segment['video_segment'] if reject_type == s.RS_TYPE_REPEAT: - segment_path = s.RS_PATH_REPEAT + "%s" % rs_repeat_count + s.OUTPUT_EXTENSION + segment_path = s.RS_PATH_REPEAT + "%s" % rs_repeat_count + s.VIDEO_OUTPUT_EXTENSION video_segment.write_videofile(segment_path, fps=s.MOVIEPY_FPS, codec=s.MOVIEPY_CODEC, ffmpeg_params=['-crf', s.music_video_crf]) rs_repeat_count += 1 elif reject_type == s.RS_TYPE_SCENE_CHANGE: - segment_path = s.RS_PATH_SCENE_CHANGE + "%s" % rs_scene_change_count + s.OUTPUT_EXTENSION + segment_path = s.RS_PATH_SCENE_CHANGE + "%s" % rs_scene_change_count + s.VIDEO_OUTPUT_EXTENSION video_segment.write_videofile(segment_path, fps=s.MOVIEPY_FPS, codec=s.MOVIEPY_CODEC, ffmpeg_params=['-crf', s.music_video_crf]) rs_scene_change_count += 1 elif reject_type == s.RS_TYPE_TEXT_DETECTED: - segment_path = s.RS_PATH_TEXT_DETECTED + "%s" % rs_text_detected_count + s.OUTPUT_EXTENSION + segment_path = s.RS_PATH_TEXT_DETECTED + "%s" % rs_text_detected_count + s.VIDEO_OUTPUT_EXTENSION video_segment.write_videofile(segment_path, fps=s.MOVIEPY_FPS, codec=s.MOVIEPY_CODEC, ffmpeg_params=['-crf', s.music_video_crf]) rs_text_detected_count += 1 else: - segment_path = s.RS_PATH_SOLID_COLOR + "%s" % rs_solid_color_count + s.OUTPUT_EXTENSION + segment_path = s.RS_PATH_SOLID_COLOR + "%s" % rs_solid_color_count + s.VIDEO_OUTPUT_EXTENSION video_segment.write_videofile(segment_path, fps=s.MOVIEPY_FPS, codec=s.MOVIEPY_CODEC, ffmpeg_params=['-crf', s.music_video_crf]) rs_solid_color_count += 1 diff --git a/mugen/video/sizing.py b/mugen/video/sizing.py index dea7783..439bde0 100644 --- a/mugen/video/sizing.py +++ b/mugen/video/sizing.py @@ -29,7 +29,6 @@ def resize_video_segments(video_segments): # Crop top & bottom cropped_height = int(width/music_video_aspect_ratio) height_difference = height - cropped_height - cropped_dimensions = (width, cropped_height) video_segment = video_segment.crop(y1 = height_difference/2, y2 = height - height_difference/2) # Resize video if needed, to match music video dimensions diff --git a/mugen/video/video.py b/mugen/video/video.py index f7a50c7..cdf8583 100644 --- a/mugen/video/video.py +++ b/mugen/video/video.py @@ -1,6 +1,4 @@ -import sys import random -import logging import moviepy.editor as moviepy from tqdm import tqdm @@ -22,7 +20,8 @@ def create_music_video(video_segments, audio_file, spec): music_video = moviepy.concatenate_videoclips(video_segments, method="compose") music_video = music_video.set_audio(audio) music_video.write_videofile(temp_output_path, fps=s.MOVIEPY_FPS, codec=s.MOVIEPY_CODEC, - audio_bitrate=s.MOVIEPY_AUDIO_BITRATE, ffmpeg_params=['-crf', s.music_video_crf]) + audio_bitrate=s.MOVIEPY_AUDIO_BITRATE, ffmpeg_params=['-crf', s.music_video_crf], + temp_audiofile=s.TEMP_MOVIEPY_AUDIOFILE) v_io.add_auxiliary_tracks(temp_output_path, spec) def generate_video_segments(video_files, beat_interval_groups):