Passed
Push — master ( 7bc1c2...5b857f )
by Amin
03:31
created

ffmpeg_streaming._reperesentation.cal_bitrate()   A

Complexity

Conditions 2

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nop 3
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
"""
2
ffmpeg_streaming.media
3
~~~~~~~~~~~~
4
5
Auto Generate Representation and Representation Object
6
7
8
:copyright: (c) 2020 by Amin Yazdanpanah.
9
:website: https://www.aminyazdanpanah.com
10
:email: [email protected]
11
:license: MIT, see LICENSE for more details.
12
"""
13
from ._format import Format
14
from ._media_property import Size, Bitrate
15
16
MINIMUM_BITRATE = 65536
17
18
19
class Representation:
20
    def __init__(self, size: Size, bitrate: Bitrate):
21
        self.size = size
22
        self.bitrate = bitrate
23
24
25
def min_bitrate(bitrate: int) -> int:
26
    if bitrate < MINIMUM_BITRATE:
27
        return MINIMUM_BITRATE
28
29
    return bitrate
30
31
32
def reduce_bitrate(bitrate: Bitrate, divide: int) -> Bitrate:
33
    if divide == 1:
34
        return bitrate
35
36
    divide = 1 + divide / 2
37
38
    overall = min_bitrate(int(bitrate.overall_ / divide))
39
    video = min_bitrate(int(bitrate.video_ / divide)) if bitrate.video_ is not None and bitrate.video_ != 0 else None
40
    audio = min_bitrate(int(bitrate.audio_ / divide)) if bitrate.audio_ is not None and bitrate.audio_ != 0 else None
41
42
    return Bitrate(video, audio, overall)
43
44
45
def cal_bitrate(bitrate, org_bitrate: Bitrate, index: int) -> Bitrate:
46
    return bitrate[index - 1] if bitrate is not None else reduce_bitrate(org_bitrate, index)
47
48
49
class AutoRep(object):
50
    def __init__(self, original_size: Size, original_bitrate: Bitrate, _format: Format, heights: list = None, bitrate: list = None):
51
        self.original_bitrate = original_bitrate
52
        self.original_size = original_size
53
        self._format = _format
54
        self.heights = heights if heights is not None else [2160, 1440, 1080, 720, 480, 360, 240, 144]
55
        self.bitrate = bitrate
56
        self.is_default = True if heights is not None and bitrate is not None else False
57
58
        if heights is not None and bitrate is not None and len(heights) != len(bitrate):
59
            raise ValueError("The length of heights list must the same as length of bitrate")
60
61
    def __iter__(self):
62
        if not self.is_default:
63
            height = self.original_size.ratio.calculate_height(self.original_size.width, self._format.multiply())
64
            self.heights = [height] + list(filter(lambda x: x < height, self.heights))
0 ignored issues
show
introduced by
The variable height does not seem to be defined in case BooleanNotNode on line 62 is False. Are you sure this can never be the case?
Loading history...
65
66
        self.index = 0
67
68
        return self
69
70
    def __next__(self):
71
        if self.index < len(self.heights):
72
            height = self.heights[self.index]
73
            width = self.original_size.ratio.calculate_width(height, self._format.multiply())
74
            self.index += 1
75
76
            return Representation(Size(width, height), cal_bitrate(self.bitrate, self.original_bitrate, self.index))
77
        else:
78
            raise StopIteration
79
80
81
__all__ = [
82
    'Representation'
83
]
84