Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FFMPEG] (WIP) Adding FFMPEG command JSON schema #137

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ flake8>=3.7.9
pycodestyle>=2.5.0
pytest>=5.4.1
teamcity-messages==1.25
fastjsonschema>=2.14.5
91 changes: 91 additions & 0 deletions tests/unit/test_unffmpeg_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,94 @@
OR OTHER DEALINGS IN THE SOFTWARE.

"""

import os
import sys
import pytest

try:
import unmanic.libs.unffmpeg as unffmpeg
except ImportError:
project_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.path.append(project_dir)
import unmanic.libs.unffmpeg as unffmpeg



class TestClass(object):
"""
TestClass

"""

def setup_class(self):
"""
Setup any state specific to the execution of the given class
(which usually contains tests).

:return:
"""
pass

def teardown_class(self):
"""
Teardown any state that was previously setup with a call to
setup_class.

:return:
"""
pass

def setup_method(self):
"""
Setup any state tied to the execution of the given method in a
class.
setup_method is invoked for every test method of a class.

:return:
"""
pass

def teardown_method(self):
"""
Teardown any state that was previously setup with a setup_method
call.

:return:
"""
pass

def invalid_command(self):
return {
"TODO:": "Write valid command"
}

def valid_command(self):
# command = ['ffmpeg', '-y', '-i', infile] + args + ['-y', outfile]
valid_command = {
"ffmpeg": "",
"-y": "",
" -hide_banner": "",
"-i": "/path/to/video.mkv",
"-loglevel": "info",
"-strict": "-2",
"-max_muxing_queue_size": "512",
}
return valid_command

@pytest.mark.unittest
def test_can_generate_valid_ffmpeg_command(self):
ffmpeg_cli = unffmpeg.cli
command = ffmpeg_cli.ffmpeg_generate_valid_comand(self.valid_command())
print(command)

@pytest.mark.unittest
def test_can_validate_command_schema(self):
# Loop over settings object attributes
command = self.valid_command()
valid = unffmpeg.cli.validate_command(command)
assert valid == command


if __name__ == '__main__':
pytest.main(['-s', '--log-cli-level=DEBUG', __file__])
2 changes: 2 additions & 0 deletions unmanic/libs/unffmpeg/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,12 @@
from .audio_codec_handle import AudioCodecHandle
from .subtitle_handle import SubtitleHandle
from .video_codec_handle import VideoCodecHandle
from .lib import cli

__author__ = 'Josh.5 (jsunnex@gmail.com)'

__all__ = (
'cli',
'containers',
'exceptions',
'audio_codecs',
Expand Down
28 changes: 27 additions & 1 deletion unmanic/libs/unffmpeg/lib/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,28 @@
"""
import json
import subprocess
#import fastjsonschema

from ..exceptions.ffmpeg import FFMpegError
from ..exceptions.ffprobe import FFProbeError

from ..lib import validation

def ffprobe_file(vid_file_path):
"""
Give a json from ffprobe command line

Eg:
ffprobe -loglevel quiet \
-print_format json \
-show_format \
-show_streams \
-show_error \
/path/to/video.mkv

:param vid_file_path: The absolute (full) path of the video file, string.
:return:
"""

if type(vid_file_path) != str:
raise Exception('Give ffprobe a full file path of the video')

Expand Down Expand Up @@ -105,3 +115,19 @@ def ffmpeg_available_encoders():
raise FFMpegError(command, 'No command output returned')

return raw_output

#
# def validate_command(command):
# """
# Validates a command array against the command JSON schema
# :param command:
# :return:
# """
#
# json_validate = fastjsonschema.compile(validation.command_schema)
# return json_validate(command)
#
# def ffmpeg_generate_valid_comand(command):
# validated_command = validate_command(command)
# print(validated_command)
#
57 changes: 57 additions & 0 deletions unmanic/libs/unffmpeg/lib/validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,60 @@
OR OTHER DEALINGS IN THE SOFTWARE.

"""

command_schema = {
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "http://example.com/example.json",
"type": "object",
"title": "The root schema",
"description": "The root schema comprises the entire JSON document.",
"default": {},
"required": [
"ffmpeg",
"-i",
],
"properties": {
"ffmpeg": {
"type": "string",
"title": "The main command.",
"description": "The main command."
},
"-i": {
"type": "string",
"title": "The main command.",
"description": "The main command.",
"minLength": 1
},
"-hide_banner": {
"type": "string",
"title": "The -hide_banner schema",
"description": "An explanation about the purpose of this instance.",
"default": "",
"examples": [
""
]
},
"-loglevel": {
"type": "string",
"title": "The -loglevel schema",
"description": "An explanation about the purpose of this instance.",
"default": "info",
"examples": [
"info",
"warning",
"debug",
"verbose"
]
},
"-max_muxing_queue_size": {
"type": "string",
"title": "The -max_muxing_queue_size schema",
"description": "An explanation about the purpose of this instance.",
"default": "512",
"examples": [
"512"
]
}
},
"additionalProperties": True
}