aboutsummaryrefslogtreecommitdiffhomepage
path: root/libs/guessit/rules/properties/bit_rate.py
blob: d279c9f1cde3901405aa57a07e7e3c788919f73a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
video_bit_rate and audio_bit_rate properties
"""
import re

from rebulk import Rebulk
from rebulk.rules import Rule, RemoveMatch, RenameMatch

from ..common import dash, seps
from ..common.pattern import is_disabled
from ..common.quantity import BitRate
from ..common.validators import seps_surround


def bit_rate(config):  # pylint:disable=unused-argument
    """
    Builder for rebulk object.

    :param config: rule configuration
    :type config: dict
    :return: Created Rebulk object
    :rtype: Rebulk
    """
    rebulk = Rebulk(disabled=lambda context: (is_disabled(context, 'audio_bit_rate')
                                              and is_disabled(context, 'video_bit_rate')))
    rebulk = rebulk.regex_defaults(flags=re.IGNORECASE, abbreviations=[dash])
    rebulk.defaults(name='audio_bit_rate', validator=seps_surround)
    rebulk.regex(r'\d+-?[kmg]b(ps|its?)', r'\d+\.\d+-?[kmg]b(ps|its?)',
                 conflict_solver=(
                     lambda match, other: match
                     if other.name == 'audio_channels' and 'weak-audio_channels' not in other.tags
                     else other
                 ),
                 formatter=BitRate.fromstring, tags=['release-group-prefix'])

    rebulk.rules(BitRateTypeRule)

    return rebulk


class BitRateTypeRule(Rule):
    """
    Convert audio bit rate guess into video bit rate.
    """
    consequence = [RenameMatch('video_bit_rate'), RemoveMatch]

    def when(self, matches, context):
        to_rename = []
        to_remove = []

        if is_disabled(context, 'audio_bit_rate'):
            to_remove.extend(matches.named('audio_bit_rate'))
        else:
            video_bit_rate_disabled = is_disabled(context, 'video_bit_rate')
            for match in matches.named('audio_bit_rate'):
                previous = matches.previous(match, index=0,
                                            predicate=lambda m: m.name in ('source', 'screen_size', 'video_codec'))
                if previous and not matches.holes(previous.end, match.start, predicate=lambda m: m.value.strip(seps)):
                    after = matches.next(match, index=0, predicate=lambda m: m.name == 'audio_codec')
                    if after and not matches.holes(match.end, after.start, predicate=lambda m: m.value.strip(seps)):
                        bitrate = match.value
                        if bitrate.units == 'Kbps' or (bitrate.units == 'Mbps' and bitrate.magnitude < 10):
                            continue

                    if video_bit_rate_disabled:
                        to_remove.append(match)
                    else:
                        to_rename.append(match)

        if to_rename or to_remove:
            return to_rename, to_remove
        return False