Make Option a namedtuple and refactor OptionStore
This commit is contained in:
parent
f343010211
commit
4d905c1c27
|
|
@ -40,8 +40,7 @@ class VideoCodec(Codec):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def aspect(self, x, y):
|
def aspect(self, x, y):
|
||||||
filter = self._format_parameter(x, y)
|
self.add_parameter('-aspect', x, y)
|
||||||
self.add_option('-aspect', filter)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def bitrate_tolerance(self, tolerance):
|
def bitrate_tolerance(self, tolerance):
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ class FFmpeg(OptionStore):
|
||||||
OptionStore.__init__(self, *args)
|
OptionStore.__init__(self, *args)
|
||||||
|
|
||||||
def add_option(self, key, value):
|
def add_option(self, key, value):
|
||||||
self._list.insert(0, Option({key: value}))
|
self.container_list.insert(0, Option(key, value))
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Executes the command of this object. Return a
|
"""Executes the command of this object. Return a
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,7 @@ class VideoFilter(FilterStore):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def blackframe(self, amount, threshold):
|
def blackframe(self, amount, threshold):
|
||||||
filter = self._format_parameter(amount, threshold)
|
self.add_parameter('blackframe', amount, threshold)
|
||||||
self.add_option('blackframe', filter)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def copy(self):
|
def copy(self):
|
||||||
|
|
@ -40,35 +39,30 @@ class VideoFilter(FilterStore):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def crop(self, out_w, out_h=None, x=None, y=None):
|
def crop(self, out_w, out_h=None, x=None, y=None):
|
||||||
filter = self._format_parameter(out_w, out_h, x, y)
|
self.add_parameter('crop', out_w, out_h, x, y)
|
||||||
self.add_option('crop', filter)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def cropdetect(self, limit=None, round=None, reset=None):
|
def cropdetect(self, limit=None, round=None, reset=None):
|
||||||
filter = self._format_parameter(limit, round, reset)
|
self.add_parameter('cropdetect', limit, round, reset)
|
||||||
self.add_option('cropdetect', filter)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def drawbox(self, x, y, width, height, color):
|
def drawbox(self, x, y, width, height, color):
|
||||||
filter = self._format_parameter(x, y, width, height, color)
|
self.add_parameter('drawbox', x, y, width, height, color)
|
||||||
self.add_option('drawbox', filter)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def drawtext(self, **kwargs):
|
def drawtext(self, **kwargs):
|
||||||
filter = self._format_keyword_parameter(**kwargs)
|
self.add_parameter('drawtext', **kwargs)
|
||||||
self.add_option('drawtext', filter)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def fade(self, type, start, number):
|
def fade(self, type, start, number):
|
||||||
filter = self._format_parameter(type, start, number)
|
self.add_parameter('fade', type, start, number)
|
||||||
self.add_option('fade', filter)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def fieldorder(self, type):
|
def fieldorder(self, type):
|
||||||
if str(type) not in ['0', '1', 'bff', 'tff']:
|
if str(type) not in ['0', '1', 'bff', 'tff']:
|
||||||
raise ValueError('Invalid Option for fieldorder. '
|
raise ValueError('Invalid Option for fieldorder. '
|
||||||
'Read FFmpeg manual!')
|
'Read FFmpeg manual!')
|
||||||
self.add_option('fieldorder', type)
|
self.add_parameter('fieldorder', type)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def fifo(self):
|
def fifo(self):
|
||||||
|
|
@ -76,18 +70,15 @@ class VideoFilter(FilterStore):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def format(self, *args):
|
def format(self, *args):
|
||||||
filter = self._format_parameter(*args)
|
self.add_parameter('format', *args)
|
||||||
self.add_option('format', filter)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def freior(self, name, *args):
|
def freior(self, name, *args):
|
||||||
filter = self._format_parameter(name, *args)
|
self.add_parameter('frei0r', name, *args)
|
||||||
self.add_option('frei0r', filter)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def gradfun(self, strength='', radius=''):
|
def gradfun(self, strength='', radius=''):
|
||||||
filter = self._format_parameter(strength, radius)
|
self.add_parameter('gradfun', strength, radius)
|
||||||
self.add_option('gradfun', filter)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def hflip(self):
|
def hflip(self):
|
||||||
|
|
@ -96,14 +87,12 @@ class VideoFilter(FilterStore):
|
||||||
|
|
||||||
def hqdn3d(self, luma_sp=None, chroma_sp=None,
|
def hqdn3d(self, luma_sp=None, chroma_sp=None,
|
||||||
luma_tmp=None, chroma_tmp=None):
|
luma_tmp=None, chroma_tmp=None):
|
||||||
filter = self._format_parameter(
|
self.add_parameter('hqdn3d',
|
||||||
luma_sp, chroma_sp, luma_tmp, chroma_tmp)
|
luma_sp, chroma_sp, luma_tmp, chroma_tmp)
|
||||||
self.add_option('hqdn3d', filter)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def mp(self, **kwargs):
|
def mp(self, **kwargs):
|
||||||
filter = self._format_keyword_parameter(**kwargs)
|
self.add_parameter('mp', **kwargs)
|
||||||
self.add_option('mp', filter)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def negate(self):
|
def negate(self):
|
||||||
|
|
@ -111,8 +100,7 @@ class VideoFilter(FilterStore):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def noformat(self, *args):
|
def noformat(self, *args):
|
||||||
filter = self._format_parameter(*args)
|
self.add_parameter('noformat', *args)
|
||||||
self.add_option('noformat', filter)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def null(self):
|
def null(self):
|
||||||
|
|
@ -120,55 +108,49 @@ class VideoFilter(FilterStore):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def overlay(self, x, y):
|
def overlay(self, x, y):
|
||||||
filter = self._format_parameter(x, y)
|
self.add_parameter('overlay', x, y)
|
||||||
self.add_option('overlay', filter)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def pad(self, width, height, x, y, color):
|
def pad(self, width, height, x, y, color):
|
||||||
filter = self._format_parameter(width, height, x, y, color)
|
self.add_parameter('pad', width, height, x, y, color)
|
||||||
self.add_option('pad', filter)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def scale(self, width=-1, height=-1):
|
def scale(self, width=-1, height=-1):
|
||||||
filter = self._format_parameter(width, height)
|
self.add_parameter('scale', width, height)
|
||||||
self.add_option('scale', filter)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def select(self, expression):
|
def select(self, expression):
|
||||||
self.add_option('select', expression)
|
self.add_parameter('select', expression)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def setdar(self, x, y):
|
def setdar(self, x, y):
|
||||||
filter = self._format_parameter(x, y)
|
self.add_parameter('setdar', x, y)
|
||||||
self.add_option('setdar', filter)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def setpts(self, expression):
|
def setpts(self, expression):
|
||||||
self.add_option('setpts', expression)
|
self.add_parameter('setpts', expression)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def setsar(self, x, y):
|
def setsar(self, x, y):
|
||||||
filter = self._format_parameter(x, y)
|
self.add_parameter('setsar', x, y)
|
||||||
self.add_option('setsar', filter)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def slicify(self, height=16):
|
def slicify(self, height=16):
|
||||||
self.add_option("slicify", height)
|
self.add_parameter('slicify', height)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def transpose(self, type):
|
def transpose(self, type):
|
||||||
if str(type) not in ['0', '1','2', '3']:
|
if str(type) not in ['0', '1','2', '3']:
|
||||||
raise ValueError('Invalid Option for transpose. '
|
raise ValueError('Invalid Option for transpose. '
|
||||||
'Read FFmpeg manual')
|
'Read FFmpeg manual')
|
||||||
self.add_option('transpose', type)
|
self.add_parameter('transpose', type)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def unsharp(self, *args):
|
def unsharp(self, *args):
|
||||||
if len(args) > 6:
|
if len(args) > 6:
|
||||||
message = 'unsharp() takes exactly 6 positional arguments'
|
message = 'unsharp() takes exactly 6 positional arguments'
|
||||||
raise TypeError(message)
|
raise TypeError(message)
|
||||||
filter = self._format_parameter(*args)
|
self.add_parameter('unsharp', *args)
|
||||||
self.add_option('unsharp', filter)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def vflip(self):
|
def vflip(self):
|
||||||
|
|
@ -176,8 +158,7 @@ class VideoFilter(FilterStore):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def yadif(self, mode=0, parity=-1):
|
def yadif(self, mode=0, parity=-1):
|
||||||
filter = self._format_parameter(mode, parity)
|
self.add_parameter('yadif', mode, parity)
|
||||||
self.add_option('yadif', filter)
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
|
|
|
||||||
|
|
@ -1,80 +1,16 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from itertools import chain
|
||||||
|
from collections import MutableSequence, namedtuple
|
||||||
|
|
||||||
class Option(dict):
|
try:
|
||||||
|
from itertools import ifilter
|
||||||
def __init__(self, *args, **kwargs):
|
except ImportError:
|
||||||
dict.__init__(self, *args, **kwargs)
|
ifilter = filter
|
||||||
|
|
||||||
def __getitem__(self, key):
|
|
||||||
if key in self:
|
|
||||||
return dict.__getitem__(self, key)
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
for option, value in self.items():
|
|
||||||
yield option
|
|
||||||
if value:
|
|
||||||
yield value
|
|
||||||
|
|
||||||
def iteritems(self):
|
|
||||||
for option, value in self.items():
|
|
||||||
yield (option, value)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "<{cls} {opts}>".format(opts=list(self),
|
|
||||||
cls=self.__class__.__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class OptionStore(object):
|
def format_parameter(*args, **kwargs):
|
||||||
|
|
||||||
def __init__(self, *args):
|
|
||||||
self._list = list(args)
|
|
||||||
|
|
||||||
def __add__(self, other):
|
|
||||||
self.append(other)
|
|
||||||
|
|
||||||
def append(self, item):
|
|
||||||
self._list.append(item)
|
|
||||||
|
|
||||||
def insert(self, item):
|
|
||||||
self._list.insert(item)
|
|
||||||
|
|
||||||
def pop(self):
|
|
||||||
return self._list.pop()
|
|
||||||
|
|
||||||
def remove(self, item):
|
|
||||||
self._list.remove()
|
|
||||||
|
|
||||||
def count(self, items):
|
|
||||||
return self._list.count()
|
|
||||||
|
|
||||||
def index(self, item):
|
|
||||||
return self._list.index(item)
|
|
||||||
|
|
||||||
def add_option(self, key, value):
|
|
||||||
self._list.append(Option({key: value}))
|
|
||||||
|
|
||||||
@property
|
|
||||||
def option_containers(self):
|
|
||||||
return self._list
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
for option in self._list:
|
|
||||||
for item in option:
|
|
||||||
yield item
|
|
||||||
|
|
||||||
def iteritems(self):
|
|
||||||
for option in self._list:
|
|
||||||
for item in option.iteritems():
|
|
||||||
yield item
|
|
||||||
|
|
||||||
def _format_parameter(self, *args):
|
|
||||||
parameter = filter(lambda x: x is not None, args)
|
|
||||||
return ':'.join(map(str, parameter))
|
|
||||||
|
|
||||||
def _format_keyword_parameter(self, **kwargs):
|
|
||||||
parameter_list = []
|
parameter_list = []
|
||||||
print(kwargs)
|
|
||||||
for key, value in kwargs.items():
|
for key, value in kwargs.items():
|
||||||
try:
|
try:
|
||||||
if not value:
|
if not value:
|
||||||
|
|
@ -84,8 +20,54 @@ class OptionStore(object):
|
||||||
except TypeError:
|
except TypeError:
|
||||||
values = ':'.join(kwargs[key])
|
values = ':'.join(kwargs[key])
|
||||||
parameter_list.append("=".join([key, values]))
|
parameter_list.append("=".join([key, values]))
|
||||||
return '"' + ':'.join(parameter_list) + '"'
|
for value in args:
|
||||||
|
if value is not None:
|
||||||
|
parameter_list.append(str(value))
|
||||||
|
result = ':'.join(parameter_list)
|
||||||
|
if kwargs:
|
||||||
|
return '"%s"' % result
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
Option = namedtuple('Option', ['name', 'value'])
|
||||||
|
|
||||||
|
|
||||||
|
class OptionStore(MutableSequence):
|
||||||
|
|
||||||
|
def __init__(self, *containers):
|
||||||
|
self.container_list = list(containers)
|
||||||
|
|
||||||
|
def add_option(self, key, value):
|
||||||
|
self.container_list.append(Option(key, value))
|
||||||
|
|
||||||
|
def add_parameter(self, name, *args, **kwargs):
|
||||||
|
parameter = format_parameter(*args, **kwargs)
|
||||||
|
self.add_option(name, parameter)
|
||||||
|
|
||||||
|
def insert(self, index, value):
|
||||||
|
self.container_list.insert(index, value)
|
||||||
|
|
||||||
|
def iteritems(self):
|
||||||
|
return iter(self.container_list)
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return ifilter(None, chain.from_iterable(self.container_list))
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return self.container_list.__len__()
|
||||||
|
|
||||||
|
def __setitem__(self, index, value):
|
||||||
|
self.container_list.__setitem__(index, value)
|
||||||
|
|
||||||
|
def __getitem__(self, index):
|
||||||
|
return self.container_list.__getitem__(index)
|
||||||
|
|
||||||
|
def __delitem__(self, index):
|
||||||
|
self.container_list.__delitem__(index)
|
||||||
|
|
||||||
|
def __contains__(self, other):
|
||||||
|
return self.container_list.__contains__(other)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<{cls} {opts}>".format(opts=list(self),
|
return "<{cls} {opts}>".format(
|
||||||
cls=self.__class__.__name__)
|
opts=list(self), cls=self.__class__.__name__)
|
||||||
|
|
|
||||||
8
test.py
8
test.py
|
|
@ -14,26 +14,26 @@ class FFmpegTestCase(unittest.TestCase):
|
||||||
self.assertEqual(list(input), ['-i', '/old'])
|
self.assertEqual(list(input), ['-i', '/old'])
|
||||||
self.assertEqual(input.file, '/old')
|
self.assertEqual(input.file, '/old')
|
||||||
|
|
||||||
option = Option({'-vf': 'x11grab'})
|
option = Option('-vf', 'x11grab')
|
||||||
input.append(option)
|
input.append(option)
|
||||||
self.assertEqual(list(input), ['-vf', 'x11grab', '-i', '/old'])
|
self.assertEqual(list(input), ['-vf', 'x11grab', '-i', '/old'])
|
||||||
self.assertEqual(input.pop(), option)
|
self.assertEqual(input.pop(), option)
|
||||||
|
|
||||||
input.add_option('-vf', 'x11grab')
|
input.add_option('-vf', 'x11grab')
|
||||||
self.assertEqual(input.option_containers, [option])
|
self.assertEqual(input.container_list, [option])
|
||||||
|
|
||||||
def test_output_interface(self):
|
def test_output_interface(self):
|
||||||
output = Output('/new')
|
output = Output('/new')
|
||||||
self.assertEqual(list(output), ['/new'])
|
self.assertEqual(list(output), ['/new'])
|
||||||
self.assertEqual(output.file, '/new')
|
self.assertEqual(output.file, '/new')
|
||||||
|
|
||||||
option = Option({'-vcodec': 'libx264'})
|
option = Option('-vcodec', 'libx264')
|
||||||
output.append(option)
|
output.append(option)
|
||||||
self.assertEqual(list(output), ['-vcodec', 'libx264', '/new'])
|
self.assertEqual(list(output), ['-vcodec', 'libx264', '/new'])
|
||||||
self.assertEqual(output.pop(), option)
|
self.assertEqual(output.pop(), option)
|
||||||
|
|
||||||
output.add_option('-vcodec', 'libx264')
|
output.add_option('-vcodec', 'libx264')
|
||||||
self.assertEqual(output.option_containers, [option])
|
self.assertEqual(output.container_list, [option])
|
||||||
|
|
||||||
def test_codec_interface(self):
|
def test_codec_interface(self):
|
||||||
codec = VideoCodec('libx264')
|
codec = VideoCodec('libx264')
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue