From 43d35e62d28ee2b6f931470eaa9cbfe393e6611f Mon Sep 17 00:00:00 2001 From: Tolmachev Igor Date: Sat, 14 Sep 2024 16:15:19 +0300 Subject: Add video processing --- poetry.lock | 30 +---------------------------- pyproject.toml | 1 - video2story/__main__.py | 40 +++++++++++++++++++++++++++++++++++++-- video2story/cutter.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 86 insertions(+), 35 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4760091..88c60ac 100644 --- a/poetry.lock +++ b/poetry.lock @@ -71,34 +71,6 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] -[[package]] -name = "ffmpeg-python" -version = "0.2.0" -description = "Python bindings for FFmpeg - with complex filtering support" -optional = false -python-versions = "*" -files = [ - {file = "ffmpeg-python-0.2.0.tar.gz", hash = "sha256:65225db34627c578ef0e11c8b1eb528bb35e024752f6f10b78c011f6f64c4127"}, - {file = "ffmpeg_python-0.2.0-py3-none-any.whl", hash = "sha256:ac441a0404e053f8b6a1113a77c0f452f1cfc62f6344a769475ffdc0f56c23c5"}, -] - -[package.dependencies] -future = "*" - -[package.extras] -dev = ["Sphinx (==2.1.0)", "future (==0.17.1)", "numpy (==1.16.4)", "pytest (==4.6.1)", "pytest-mock (==1.10.4)", "tox (==3.12.1)"] - -[[package]] -name = "future" -version = "1.0.0" -description = "Clean single-source support for Python 3 and 2" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "future-1.0.0-py3-none-any.whl", hash = "sha256:929292d34f5872e70396626ef385ec22355a1fae8ad29e1a734c3e43f9fbc216"}, - {file = "future-1.0.0.tar.gz", hash = "sha256:bd2968309307861edae1458a4f8a4f3598c03be43b97521076aebf5d94c07b05"}, -] - [[package]] name = "isort" version = "5.13.2" @@ -259,4 +231,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "57d800ac4f8df8b2189422300c98cbe5d2c045eaa6f29351e873f8c92bb2ba4d" +content-hash = "afe0c9ed9e5cb15d216e56fcde897a8e133afb07c69b0a769c68476654684961" diff --git a/pyproject.toml b/pyproject.toml index acba697..53270a9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,6 @@ readme = "README.md" [tool.poetry.dependencies] python = "^3.10" -ffmpeg-python = "^0.2.0" python-telegram = "^0.19.0" [tool.poetry.group.dev.dependencies] diff --git a/video2story/__main__.py b/video2story/__main__.py index 1b65f2a..8e08cac 100644 --- a/video2story/__main__.py +++ b/video2story/__main__.py @@ -1,4 +1,7 @@ from argparse import ArgumentParser, RawTextHelpFormatter +from os.path import normpath + +from video2story import cut, upload parser = ArgumentParser( prog="video2story", @@ -20,9 +23,15 @@ video_parser = subparsers.add_parser( video_parser.add_argument( "filename", type=str, - metavar="FILENAME", + metavar="FILE", help="Video file name", ) +video_parser.add_argument( + "output", + type=str, + metavar="PATH", + help="Output folder for processed videos", +) video_parser.add_argument( "-d", "--duration", @@ -41,6 +50,23 @@ video_parser.add_argument( action="store_true", help="Remove sound from video.", ) +video_parser.add_argument( + "-s", + "--start", + type=int, + metavar="SECONDS", + default=None, + help="Specifies the second of the video from which processing will begin.", +) +video_parser.add_argument( + "-e", + "--end", + type=int, + metavar="SECONDS", + default=None, + help="Specifies the second of the video from which processing will end.", +) + story_parser = subparsers.add_parser( "story", @@ -124,4 +150,14 @@ story_parser.add_argument( args = parser.parse_args() -print(args) +if args.module == "video": + cut( + normpath(args.filename), + normpath(args.output), + args.duration, + args.no_sound, + args.start, + args.end, + ) +elif args.module == "story": + pass diff --git a/video2story/cutter.py b/video2story/cutter.py index 880a672..23f035e 100644 --- a/video2story/cutter.py +++ b/video2story/cutter.py @@ -1,5 +1,49 @@ -import ffmpeg +from os import makedirs +from os.path import exists, isdir, join +from subprocess import Popen -def cut(filename: str) -> None: - ffmpeg.input(filename).output("test.mp4") +def cut( + filename: str, + output: str, + duration: int, + no_sound: bool, + start: int | None, + end: int | None, +) -> None: + if not exists(output): + makedirs(output) + elif not isdir(output): + print("Output is not a directory") + exit(1) + process = Popen( + [ + "ffmpeg", + "-y", + # Input file + *("-i", filename), + # Start point + *(("-ss", str(start)) if start is not None else ()), + # End point + *(("-to", str(end)) if end is not None else ()), + # Codec + *("-c:v", "libx264"), + *(("-an",) if no_sound else ("-c:a", "mp3")), + # Video centring + *( + "-vf", + "scale=720:1280:force_original_aspect_ratio=decrease,pad=720:1280:-1:-1,setsar=1", + ), + # Segment splitter + *("-f", "segment"), + *("-segment_time", str(duration)), + *("-reset_timestamps", "1"), + *("-force_key_frames", f"expr:gte(t,n_forced*{duration})"), + # Output + join(output, "%d.mp4"), + ] + ) + + exit_code = process.wait() + if exit_code != 0: + exit(exit_code) -- cgit v1.2.3