Passed
Push — master ( 6ab7ae...6f6dda )
by Amin
03:33
created

ffmpeg_streaming._command_builder._hls_seg_ext()   A

Complexity

Conditions 2

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
"""
2
ffmpeg_streaming.build_args
3
~~~~~~~~~~~~
4
5
Build a command for the FFmpeg
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
import sys
14
15
from ._utiles import cnv_options_to_args, get_path_info, clean_args
16
17
18
def _stream2file(stream2file):
19
    """
20
    @TODO: add documentation
21
    """
22
    args = stream2file.format.all
23
    args.update({'c': 'copy'})
24
    args.update(stream2file.options)
25
26
    return cnv_options_to_args(args) + [stream2file.output_]
27
28
29
def _get_audio_bitrate(rep, index: int = None):
30
    """
31
    @TODO: add documentation
32
    """
33
    if rep.bitrate.audio_ is not None and rep.bitrate.audio_ != 0:
34
        opt = 'b:a' if index is None else 'b:a:' + str(index)
35
        return {opt: rep.bitrate.audio}
36
37
    return {}
38
39
40
def _get_dash_stream(key, rep):
41
    """
42
    @TODO: add documentation
43
    """
44
    args = {
45
        'map':               0,
46
        's:v:' + str(key):   rep.size.normalize,
47
        'b:v:' + str(key):   rep.bitrate.normalize_video()
48
    }
49
    args.update(_get_audio_bitrate(rep, key))
50
    return cnv_options_to_args(args)
51
52
53
def _dash(dash):
54
    """
55
    @TODO: add documentation
56
    """
57
    dirname, name = get_path_info(dash.output_)
58
    _args = dash.format.all
59
    _args.update({
60
        'use_timeline':    1,
61
        'use_template':    1,
62
        'init_seg_name':   '{}_init_$RepresentationID$.$ext$'.format(name),
63
        "media_seg_name":  '{}_chunk_$RepresentationID$_$Number%05d$.$ext$'.format(name),
64
        'f':               'dash'
65
    })
66
    _args.update(dash.options)
67
    args = cnv_options_to_args(_args)
68
69
    for key, rep in enumerate(dash.reps):
70
        args += _get_dash_stream(key, rep)
71
72
    return args + ['-strict', '-2', '{}/{}.mpd'.format(dirname, name)]
73
74
75
def _hls_seg_ext(hls):
76
    """
77
    @TODO: add documentation
78
    """
79
    return 'm4s' if hls.options.get('hls_segment_type', '') == 'fmp4' else 'ts'
80
81
82
def _get_hls_stream(hls, rep, dirname, name):
83
    """
84
    @TODO: add documentation
85
    """
86
    args = hls.format.all
87
    args.update({
88
        'hls_list_size':            0,
89
        'hls_time':                 10,
90
        'hls_allow_cache':          1,
91
        'hls_segment_filename':     "{}/{}_{}p_%04d.{}".format(dirname, name, str(rep.size.height), _hls_seg_ext(hls)),
92
        'hls_fmp4_init_filename':   "{}_{}p_init.mp4".format(name, str(rep.size.height)),
93
        's:v':                      rep.size.normalize,
94
        'b:v':                      rep.bitrate.normalize_video()
95
    })
96
    args.update(_get_audio_bitrate(rep))
97
    args.update({'strict': '-2'})
98
    args.update(hls.options)
99
100
    return cnv_options_to_args(args) + ["{}/{}_{}p.m3u8".format(dirname, name, str(rep.size.height))]
101
102
103
def _hls(hls):
104
    """
105
    @TODO: add documentation
106
    """
107
    dirname, name = get_path_info(hls.output_)
108
    streams = []
109
    for key, rep in enumerate(hls.reps):
110
        if key > 0:
111
            streams += input_args(hls)
112
        streams += _get_hls_stream(hls, rep, dirname, name)
113
114
    return streams
115
116
117
def stream_args(media):
118
    """
119
    @TODO: add documentation
120
    """
121
    return getattr(sys.modules[__name__], "_%s" % type(media).__name__.lower())(media)
122
123
124
def input_args(media):
125
    inputs = []
126
    for key, _input in enumerate(media.media.inputs.inputs):
127
        _input = dict(_input)
128
        _input.pop('is_tmp', None)
129
        if key > 0:
130
            _input.pop('y', None)
131
        inputs += cnv_options_to_args(_input)
132
133
    return inputs
134
135
136
def command_builder(ffmpeg_bin: str, media):
137
    """
138
    @TODO: add documentation
139
    """
140
    return " ".join(clean_args([ffmpeg_bin] + input_args(media) + stream_args(media)))
141
142