diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..77055c4 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,19 @@ +name: CI + +on: [push] + +jobs: + ci: + name: CI + runs-on: ubuntu-latest + env: + COMPOSE_FILE: docker-compose.yaml + steps: + - name: Checkout code + uses: actions/checkout@v2 + - name: Build docker image + run: make build + - name: Lint Check + run: make lint + - name: Type Check + run: make check-type-annotations diff --git a/Makefile b/Makefile index 847ce40..fc00683 100644 --- a/Makefile +++ b/Makefile @@ -40,15 +40,20 @@ clean: ## Lint using pylama, isort and black lint: - $(DOCKER_COMPOSE_RUN) bash -c "pylama && isort --check-only --atomic . && black --check ." + $(DOCKER_COMPOSE_RUN) bash -c "pylama && isort --check-only --atomic ./jumpcutter && black --check ./jumpcutter" ## Sort imports sort: - $(DOCKER_COMPOSE_RUN) isort --atomic . + $(DOCKER_COMPOSE_RUN) isort --atomic ./jumpcutter ## Format code with black format: - $(DOCKER_COMPOSE_RUN) black . + $(DOCKER_COMPOSE_RUN) black ./jumpcutter + + +## Check type annotations +check-type-annotations: + $(DOCKER_COMPOSE_RUN) mypy ./jumpcutter ## Lock dependencies with pipenv lock_dependencies: diff --git a/docker-compose.yml b/docker-compose.yaml similarity index 100% rename from docker-compose.yml rename to docker-compose.yaml diff --git a/jumpcutter/__main__.py b/jumpcutter/__main__.py index 0885e30..2653f0c 100644 --- a/jumpcutter/__main__.py +++ b/jumpcutter/__main__.py @@ -5,7 +5,7 @@ from jumpcutter.clip import Clip -def main(): +def main() -> None: parser = argparse.ArgumentParser() parser.add_argument( diff --git a/jumpcutter/clip.py b/jumpcutter/clip.py index 5bfa3b3..bbcc7f3 100644 --- a/jumpcutter/clip.py +++ b/jumpcutter/clip.py @@ -1,12 +1,18 @@ +from typing import Dict, List, Tuple + import numpy as np +from moviepy.audio.io.AudioFileClip import AudioFileClip from moviepy.editor import VideoFileClip, concatenate_videoclips from moviepy.video.fx.all import speedx +from moviepy.video.io.VideoFileClip import VideoFileClip from tqdm import tqdm class Clip: - def __init__(self, clip_path, min_loud_part_duration, silence_part_speed): + def __init__( + self, clip_path: str, min_loud_part_duration: int, silence_part_speed: int + ) -> None: self.clip = VideoFileClip(clip_path) self.audio = Audio(self.clip.audio) self.cut_to_method = { @@ -16,17 +22,14 @@ def __init__(self, clip_path, min_loud_part_duration, silence_part_speed): self.min_loud_part_duration = min_loud_part_duration self.silence_part_speed = silence_part_speed - def get_duration(self): - return self.clip.duration - def jumpcut( self, - cuts, - magnitude_threshold_ratio, - duration_threshold_in_seconds, - failure_tolerance_ratio, - space_on_edges, - ): + cuts: List[str], + magnitude_threshold_ratio: float, + duration_threshold_in_seconds: float, + failure_tolerance_ratio: float, + space_on_edges: float, + ) -> Dict[str, VideoFileClip]: intervals_to_cut = self.audio.get_intervals_to_cut( magnitude_threshold_ratio, @@ -41,7 +44,9 @@ def jumpcut( return outputs - def jumpcut_silent_parts(self, intervals_to_cut): + def jumpcut_silent_parts( + self, intervals_to_cut: List[Tuple[float, float]] + ) -> List[VideoFileClip]: jumpcutted_clips = [] previous_stop = 0 for start, stop in tqdm(intervals_to_cut, desc="Cutting silent intervals"): @@ -64,7 +69,9 @@ def jumpcut_silent_parts(self, intervals_to_cut): jumpcutted_clips.append(last_clip) return jumpcutted_clips - def jumpcut_voiced_parts(self, intervals_to_cut): + def jumpcut_voiced_parts( + self, intervals_to_cut: List[Tuple[float, float]] + ) -> List[VideoFileClip]: jumpcutted_clips = [] for start, stop in tqdm(intervals_to_cut, desc="Cutting voiced intervals"): if start < stop: @@ -74,7 +81,7 @@ def jumpcut_voiced_parts(self, intervals_to_cut): class Audio: - def __init__(self, audio): + def __init__(self, audio: AudioFileClip) -> None: self.audio = audio self.fps = audio.fps @@ -84,11 +91,11 @@ def __init__(self, audio): def get_intervals_to_cut( self, - magnitude_threshold_ratio, - duration_threshold_in_seconds, - failure_tolerance_ratio, - space_on_edges, - ): + magnitude_threshold_ratio: float, + duration_threshold_in_seconds: float, + failure_tolerance_ratio: float, + space_on_edges: float, + ) -> List[Tuple[float, float]]: min_magnitude = min(abs(np.min(self.signal)), np.max(self.signal)) magnitude_threshold = min_magnitude * magnitude_threshold_ratio failure_tolerance = self.fps * failure_tolerance_ratio diff --git a/setup.cfg b/setup.cfg index 0b6d346..df7bf30 100644 --- a/setup.cfg +++ b/setup.cfg @@ -24,7 +24,7 @@ show_closures = True no_assert = True [mypy] -python_version = 3.6 +python_version = 3.8 warn_redundant_casts = False warn_unused_ignores = True warn_unused_configs = True