You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
bazarr/libs/knowit/rules/audio.py

105 lines
3.2 KiB

import typing
from decimal import Decimal
from logging import NullHandler, getLogger
from knowit.core import Rule
logger = getLogger(__name__)
logger.addHandler(NullHandler())
class AtmosRule(Rule):
"""Atmos rule."""
def __init__(self, config: typing.Mapping[str, typing.Mapping], name: str,
**kwargs):
"""Initialize an Atmos rule."""
super().__init__(name, **kwargs)
self.audio_codecs = getattr(config, 'AudioCodec')
def execute(self, props, pv_props, context):
"""Execute the rule against properties."""
profile = context.get('profile') or 'default'
format_commercial = pv_props.get('format_commercial')
if 'codec' in props and format_commercial and 'atmos' in format_commercial.lower():
props['codec'] = [props['codec'],
getattr(self.audio_codecs['ATMOS'], profile)]
class AudioChannelsRule(Rule):
"""Audio Channel rule."""
mapping = {
1: '1.0',
2: '2.0',
6: '5.1',
8: '7.1',
}
def execute(self, props, pv_props, context):
"""Execute the rule against properties."""
count = props.get('channels_count')
if count is None:
return
channels = self.mapping.get(count) if isinstance(count, int) else None
positions = pv_props.get('channel_positions') or []
positions = positions if isinstance(positions, list) else [positions]
candidate = 0
for position in positions:
if not position:
continue
c = Decimal('0.0')
for i in position.split('/'):
try:
c += Decimal(i)
except ValueError:
logger.debug('Invalid %s: %s', self.description, i)
pass
c_count = int(c) + int(round((c - int(c)) * 10))
if c_count == count:
return str(c)
candidate = max(candidate, c)
if channels:
return channels
if candidate:
return candidate
self.report(positions, context)
class DtsHdRule(Rule):
"""DTS-HD rule."""
def __init__(self, config: typing.Mapping[str, typing.Mapping], name: str,
**kwargs):
"""Initialize a DTS-HD Rule."""
super().__init__(name, **kwargs)
self.audio_codecs = getattr(config, 'AudioCodec')
self.audio_profiles = getattr(config, 'AudioProfile')
@classmethod
def _redefine(cls, props, name, index):
actual = props.get(name)
if isinstance(actual, list):
value = actual[index]
if value is None:
del props[name]
else:
props[name] = value
def execute(self, props, pv_props, context):
"""Execute the rule against properties."""
profile = context.get('profile') or 'default'
if props.get('codec') == getattr(self.audio_codecs['DTS'],
profile) and props.get('profile') in (
getattr(self.audio_profiles['MA'], profile),
getattr(self.audio_profiles['HRA'], profile)):
props['codec'] = getattr(self.audio_codecs['DTS-HD'], profile)