Skip to content

Commit

Permalink
add new option, --add_in and new choice for edit
Browse files Browse the repository at this point in the history
`--edit` has a new choice, `all`, the inverse of `none`, to
go along with `--add_in`.

`--mark_as_loud` and `--mark_as_silent` now get applied frame margin
as they were always supposed to.

debug messages are also now prettified a bit.
  • Loading branch information
WyattBlue committed Aug 1, 2021
1 parent 2e2f1c9 commit 5503331
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 30 deletions.
31 changes: 19 additions & 12 deletions auto_editor/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ def main_options(parser):
parser.add_argument('--cut_out', type=range_type, nargs='*',
help='the range of media that will be removed completely, regardless of the '\
'value of silent speed.')
parser.add_argument('--add_in', type=range_type, nargs='*',
help='the range of media that will be added in, opposite of --cut_out')
parser.add_argument('--set_speed_for_range', type=speed_range_type, nargs='*',
help='set an arbitrary speed for a given range.',
extra='The arguments are: speed,start,end')
Expand All @@ -155,9 +157,9 @@ def main_options(parser):
range='0 to 1',
help='how much motion is required to be considered "moving"')
parser.add_argument('--edit_based_on', '--edit', default='audio',
choices=['audio', 'motion', 'none', 'not_audio', 'not_motion', 'audio_or_motion',
'audio_and_motion', 'audio_xor_motion', 'audio_and_not_motion',
'not_audio_and_motion', 'not_audio_and_not_motion'],
choices=['audio', 'motion', 'none', 'all', 'not_audio', 'not_motion',
'audio_or_motion', 'audio_and_motion', 'audio_xor_motion',
'audio_and_not_motion', 'not_audio_and_motion', 'not_audio_and_not_motion'],
help='decide which method to use when making edits.')

parser.add_argument('--cut_by_this_audio', '-ca', type=file_type,
Expand Down Expand Up @@ -238,29 +240,32 @@ def main_options(parser):

def get_chunks(inp, speeds, segment, fps, args, log, audioData=None, sampleRate=None):
from auto_editor.cutting import (combine_audio_motion, combine_segment,
apply_spacing_rules, apply_frame_margin, seconds_to_frames, cook, chunkify)
apply_spacing_rules, apply_mark_as, apply_frame_margin, seconds_to_frames, cook, chunkify)

frame_margin = seconds_to_frames(args.frame_margin, fps)
min_clip = seconds_to_frames(args.min_clip_length, fps)
min_cut = seconds_to_frames(args.min_cut_length, fps)

def get_has_loud(inp, args, fps, audioData, sampleRate, log):
from auto_editor.analyze import get_blank_list, audio_detection, motion_detection
import numpy as np
from auto_editor.analyze import get_np_list, audio_detection, motion_detection
if(args.edit_based_on == 'none'):
return get_blank_list(inp, audioData, sampleRate, fps)
return get_np_list(inp, audioData, sampleRate, fps, np.ones)
if(args.edit_based_on == 'all'):
return get_np_list(inp, audioData, sampleRate, fps, np.zeros)

audioList, motionList = None, None

if('audio' in args.edit_based_on):
if(audioData is None):
audioList = get_blank_list(inp, audioData, sampleRate, fps)
audioList = get_np_list(inp, audioData, sampleRate, fps, np.ones)
else:
audioList = audio_detection(audioData, sampleRate, args.silent_threshold,
fps, log)

if('motion' in args.edit_based_on):
if(len(inp.video_streams) == 0):
motionList = get_blank_list(inp, audioData, sampleRate, fps)
motionList = get_np_list(inp, audioData, sampleRate, fps, np.ones)
else:
motionList = motion_detection(inp, args.motion_threshold, log,
width=args.width, dilates=args.dilates, blur=args.blur)
Expand All @@ -274,12 +279,15 @@ def get_has_loud(inp, args, fps, audioData, sampleRate, log):
return combine_audio_motion(audioList, motionList, args.edit_based_on, log)

has_loud = get_has_loud(inp, args, fps, audioData, sampleRate, log)
has_loud = cook(has_loud, min_clip, min_cut)
has_loud_length = len(has_loud)
has_loud = apply_mark_as(has_loud, has_loud_length, fps, args, log)
has_loud = cook(has_loud, min_clip, min_cut)
has_loud = apply_frame_margin(has_loud, has_loud_length, frame_margin)

if(segment is not None):
has_loud = combine_segment(has_loud, segment, fps)
# Remove small clips/cuts created by applying other rules.
has_loud = cook(has_loud, min_clip, min_cut)
return apply_spacing_rules(has_loud, has_loud_length, min_clip, min_cut, speeds,
fps, args, log)

Expand Down Expand Up @@ -310,8 +318,7 @@ def edit_media(i, inp, ffmpeg, args, speeds, segment, exporting_to_editor, data_
if(not os.path.isdir(inp.path) and '.' not in newOutput):
newOutput = set_output_name(newOutput, data_file, args)

log.debug('Input File: {}'.format(inp.path))
log.debug('Output File: {}'.format(newOutput))
log.debug('{} -> {}'.format(inp.path, newOutput))

if(os.path.isfile(newOutput) and inp.path != newOutput):
log.debug('Removing already existing file: {}'.format(newOutput))
Expand Down Expand Up @@ -379,7 +386,7 @@ def NumberOfVrfFrames(text, log):
return 0
else:
nums = re.search(r'\d+\/\d+', search.group()).group(0)
log.debug(nums)
log.debug('VFR Frames: {}'.format(nums))
return int(nums.split('/')[0])

def hasVFR(cmd, log):
Expand Down
8 changes: 5 additions & 3 deletions auto_editor/analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@

import numpy as np

def get_blank_list(inp, audioData, sampleRate, fps):


def get_np_list(inp, audioData, sampleRate, fps, func):
if(audioData is not None):
audioSampleCount = audioData.shape[0]
samplesPerFrame = sampleRate / fps
audioFrameCount = int(math.ceil(audioSampleCount / samplesPerFrame))
return np.ones((audioFrameCount), dtype=np.bool_)
return func((audioFrameCount), dtype=np.bool_)

import cv2
cap = cv2.VideoCapture(inp.path)
totalFrames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) + 1
return np.ones((totalFrames), dtype=np.bool_)
return func((totalFrames), dtype=np.bool_)

def audio_detection(audioData, sampleRate, silent_threshold, fps, log):
# type: (np.ndarray, int, float, float, Any) -> np.ndarray
Expand Down
17 changes: 10 additions & 7 deletions auto_editor/cutting.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,20 +172,23 @@ def apply_frame_margin(has_loud, has_loud_length, frame_margin):
new[i] = min(1, np.max(has_loud[start:end]))
return new

def apply_spacing_rules(has_loud, has_loud_length, minClip, minCut, speeds, fps, args, log):
# type: (...) -> list[list[int]]

def apply_mark_as(has_loud, has_loud_length, fps, args, log):
# type: (...) -> np.ndarray
if(args.mark_as_loud != []):
has_loud = setRange(has_loud, args.mark_as_loud, fps, 1, log)

if(args.mark_as_silent != []):
has_loud = setRange(has_loud, args.mark_as_silent, fps, 0, log)
return has_loud

# Remove small clips/cuts created by applying other rules.
has_loud = cook(has_loud, minClip, minCut)

def apply_spacing_rules(has_loud, has_loud_length, minClip, minCut, speeds, fps, args, log):
# type: (...) -> list[list[int]]
if(args.cut_out != []):
cut_speed_index = speeds.index(99999)
has_loud = setRange(has_loud, args.cut_out, fps, cut_speed_index, log)
has_loud = setRange(has_loud, args.cut_out, fps, speeds.index(99999), log)

if(args.add_in != []):
has_loud = setRange(has_loud, args.add_in, fps, speeds.index(args.video_speed), log)

if(args.set_speed_for_range != []):
for item in args.set_speed_for_range:
Expand Down
22 changes: 14 additions & 8 deletions auto_editor/preview.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,21 @@ def preview(inp, chunks, speeds, log):
cut_lens.append(leng)

print('Number of clips: {}'.format(clips))
printTimeFrame('Smallest clip length', min(clip_lens), fps)
printTimeFrame('Largest clip length', max(clip_lens), fps)
printTimeFrame('Average clip length', sum(clip_lens) / len(clip_lens), fps)
print('\nNumber of cuts: {}'.format(cuts))
if(len(clip_lens) == 1):
printTimeFrame('Clip length', clip_lens[0], fps)
else:
printTimeFrame('Smallest clip length', min(clip_lens), fps)
printTimeFrame('Largest clip length', max(clip_lens), fps)
printTimeFrame('Average clip length', sum(clip_lens) / len(clip_lens), fps)
print('\nNumber of cuts: {}'.format(cuts))

if(cut_lens != []):
printTimeFrame('Smallest cut length', min(cut_lens), fps)
printTimeFrame('Largest cut length', max(cut_lens), fps)
printTimeFrame('Average cut length', sum(cut_lens) / len(cut_lens), fps)
if(len(cut_lens) == 1):
printTimeFrame('Cut length', cut_lens[0], fps)
else:
printTimeFrame('Smallest cut length', min(cut_lens), fps)
printTimeFrame('Largest cut length', max(cut_lens), fps)
printTimeFrame('Average cut length', sum(cut_lens) / len(cut_lens), fps)
print('')

log.debug('Chunks:\n{}'.format(chunks))
log.debug('Chunks: {}'.format(chunks))
8 changes: 8 additions & 0 deletions auto_editor/subcommands/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,19 @@ def unit_tests():

def backwards_range_test():
run_program(['example.mp4', '--edit', 'none', '--cut_out', '-5secs,end'])
run_program(['example.mp4', '--edit', 'all', '--add_in', '-5secs,end'])
tester.run_test('backwards_range_test', backwards_range_test, description='''
Cut out the last 5 seconds of a media file by using negative number in the
range.
''')

def cut_out_test():
run_program(['example.mp4', '--edit', 'none', '--video_speed', '2',
'--silent_speed', '3', '--cut_out', '2secs,10secs'])
run_program(['example.mp4', '--edit', 'all', '--video_speed', '2',
'--add_in', '2secs,10secs'])
tester.run_test('cut_out_test', cut_out_test)

def gif_test():
run_program(['resources/man_on_green_screen.gif', '--edit', 'none'])
tester.run_test('gif_test', gif_test, description='''
Expand Down

0 comments on commit 5503331

Please sign in to comment.