bazarr/libs/knowit/properties/video.py

122 lines
3.1 KiB
Python

import re
import typing
from decimal import Decimal
from knowit.core import Configurable
from knowit.core import Property
from knowit.utils import round_decimal
class VideoCodec(Configurable[str]):
"""Video Codec handler."""
@classmethod
def _extract_key(cls, value) -> str:
key = value.upper().split('/')[-1]
if key.startswith('V_'):
key = key[2:]
return key.split(' ')[-1]
class VideoDimensions(Property[int]):
"""Dimensions property."""
def __init__(self, *args: str, dimension='width' or 'height', **kwargs):
"""Initialize the object."""
super().__init__(*args, **kwargs)
self.dimension = dimension
dimensions_re = re.compile(r'(?P<width>\d+)x(?P<height>\d+)')
def handle(self, value, context) -> typing.Optional[int]:
"""Handle ratio."""
match = self.dimensions_re.match(value)
if match:
match_dict = match.groupdict()
try:
value = match_dict[self.dimension]
except KeyError:
pass
else:
return int(value)
self.report(value, context)
return None
class VideoEncoder(Configurable):
"""Video Encoder property."""
class VideoHdrFormat(Configurable):
"""Video HDR Format property."""
class VideoProfile(Configurable[str]):
"""Video Profile property."""
@classmethod
def _extract_key(cls, value) -> str:
return value.upper().split('@')[0]
class VideoProfileLevel(Configurable[str]):
"""Video Profile Level property."""
@classmethod
def _extract_key(cls, value) -> typing.Union[str, bool]:
values = str(value).upper().split('@')
if len(values) > 1:
value = values[1]
return value
# There's no level, so don't warn or report it
return False
class VideoProfileTier(Configurable[str]):
"""Video Profile Tier property."""
@classmethod
def _extract_key(cls, value) -> typing.Union[str, bool]:
values = str(value).upper().split('@')
if len(values) > 2:
return values[2]
# There's no tier, so don't warn or report it
return False
class Ratio(Property[Decimal]):
"""Ratio property."""
def __init__(self, *args: str, unit=None, **kwargs):
"""Initialize the object."""
super().__init__(*args, **kwargs)
self.unit = unit
ratio_re = re.compile(r'(?P<width>\d+)[:/](?P<height>\d+)')
def handle(self, value, context) -> typing.Optional[Decimal]:
"""Handle ratio."""
match = self.ratio_re.match(value)
if match:
width, height = match.groups()
if (width, height) == ('0', '1'): # identity
return Decimal('1.0')
if height:
result = round_decimal(Decimal(width) / Decimal(height), min_digits=1, max_digits=3)
if self.unit:
result *= self.unit
return result
self.report(value, context)
return None
class ScanType(Configurable[str]):
"""Scan Type property."""