Passed
Push — master ( 79d402...4ebce0 )
by Amin
01:15
created

ffmpeg_streaming/_reperesentation.py (1 issue)

Severity
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
        """
22
        @TODO: add documentation
23
        """
24
        self.size = size
25
        self.bitrate = bitrate
26
27
28
def min_bitrate(bitrate: int) -> int:
29
    """
30
    @TODO: add documentation
31
    """
32
    if bitrate < MINIMUM_BITRATE:
33
        return MINIMUM_BITRATE
34
35
    return bitrate
36
37
38
def reduce_bitrate(bitrate: Bitrate, divide: int) -> Bitrate:
39
    """
40
    @TODO: add documentation
41
    """
42
    if divide == 1:
43
        return bitrate
44
45
    divide = 1 + divide / 2
46
47
    overall = min_bitrate(int(bitrate.overall_ / divide))
48
    video = min_bitrate(int(bitrate.video_ / divide)) if bitrate.video_ is not None and bitrate.video_ != 0 else None
49
    audio = min_bitrate(int(bitrate.audio_ / divide)) if bitrate.audio_ is not None and bitrate.audio_ != 0 else None
50
51
    return Bitrate(video, audio, overall)
52
53
54
def cal_bitrate(bitrate, org_bitrate: Bitrate, index: int) -> Bitrate:
55
    return bitrate[index - 1] if bitrate is not None else reduce_bitrate(org_bitrate, index)
56
57
58
class AutoRep(object):
59
    def __init__(self, original_size: Size, original_bitrate: Bitrate, _format: Format, heights: list = None, bitrate: list = None):
60
        """
61
        @TODO: add documentation
62
        """
63
        self.original_bitrate = original_bitrate
64
        self.original_size = original_size
65
        self._format = _format
66
        self.heights = heights if heights is not None else [2160, 1440, 1080, 720, 480, 360, 240, 144]
67
        self.bitrate = bitrate
68
        self.is_default = True if heights is not None and bitrate is not None else False
69
70
        if heights is not None and bitrate is not None and len(heights) != len(bitrate):
71
            raise ValueError("The length of heights list must the same as length of bitrate")
72
73
    def __iter__(self):
74
        """
75
        @TODO: add documentation
76
        """
77
        if not self.is_default:
78
            height = self.original_size.ratio.calculate_height(self.original_size.width, self._format.multiply())
79
            self.heights = [height] + list(filter(lambda x: x < height, self.heights))
0 ignored issues
show
The variable height does not seem to be defined in case BooleanNotNode on line 77 is False. Are you sure this can never be the case?
Loading history...
80
81
        self.index = 0
82
83
        return self
84
85
    def __next__(self):
86
        """
87
        @TODO: add documentation
88
        """
89
        if self.index < len(self.heights):
90
            height = self.heights[self.index]
91
            width = self.original_size.ratio.calculate_width(height, self._format.multiply())
92
            self.index += 1
93
94
            return Representation(Size(width, height), cal_bitrate(self.bitrate, self.original_bitrate, self.index))
95
        else:
96
            raise StopIteration
97
98
99
__all__ = [
100
    'Representation'
101
]
102