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

ffmpeg_streaming._command_builder   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 104
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 68
dl 0
loc 104
rs 10
c 0
b 0
f 0
wmc 11

8 Functions

Rating   Name   Duplication   Size   Complexity  
A _get_hls_stream() 0 22 1
A _hls() 0 7 2
A _hls_seg_ext() 0 2 2
A _stream2file() 0 5 1
A command_builder() 0 3 1
A stream_args() 0 2 1
A _dash() 0 23 2
A _get_dash_stream() 0 8 1
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
    args = {'c': 'copy'}
20
    args.update(stream2file.options)
21
22
    return cnv_options_to_args(args) + [stream2file.output_]
23
24
25
def _get_dash_stream(key, rep):
26
    args = {
27
        'map':              '0',
28
        'b:v:' + str(key):   rep.bitrate.normalize_video(),
29
        'b:a:' + str(key):   rep.bitrate.audio,
30
        's:v:' + str(key):   rep.size.normalize
31
    }
32
    return cnv_options_to_args(args)
33
34
35
def _dash(dash):
36
    dirname, name = get_path_info(dash.output_)
37
    init_args = {
38
        'c:v':              dash.format.video,
39
        'c:a':              dash.format.audio,
40
        'bf':              '1',
41
        'keyint_min':      '120',
42
        'g':               '120',
43
        'sc_threshold':    '0',
44
        'b_strategy':      '0',
45
        'use_timeline':    '1',
46
        'use_template':    '1',
47
        'init_seg_name':   name + '_init_$RepresentationID$.$ext$',
48
        "media_seg_name":  name + '_chunk_$RepresentationID$_$Number%05d$.$ext$',
49
        'f':               'dash'
50
    }
51
    init_args.update(dash.options)
52
    args = cnv_options_to_args(init_args)
53
54
    for key, rep in enumerate(dash.reps):
55
        args += _get_dash_stream(key, rep)
56
57
    return args + ['-strict', '-2', dirname + '/' + name + '.mpd']
58
59
60
def _hls_seg_ext(hls):
61
    return 'm4s' if hls.options.get('hls_segment_type', '') == 'fmp4' else 'ts'
62
63
64
def _get_hls_stream(hls, rep, dirname, name):
65
    args = {
66
        'c:v':                      hls.format.video,
67
        'c:a':                      hls.format.audio,
68
        's:v':                      rep.size.normalize,
69
        'crf':                      '20',
70
        'sc_threshold':             '0',
71
        'g':                        '48',
72
        'keyint_min':               '48',
73
        'hls_list_size':            '0',
74
        'hls_time':                 '10',
75
        'hls_allow_cache':          '1',
76
        'b:v':                      rep.bitrate.normalize_video(),
77
        'b:a':                      rep.bitrate.audio,
78
        'maxrate':                  rep.bitrate.max_rate,
79
        'hls_segment_filename':     dirname + "/" + name + "_" + str(rep.size.height) + "p_%04d." + _hls_seg_ext(hls),
80
        'hls_fmp4_init_filename':   name + "_init.mp4",
81
        'strict':                   '-2'
82
    }
83
    args.update(hls.options)
84
85
    return cnv_options_to_args(args) + [dirname + "/" + name + "_" + str(rep.size.height) + "p.m3u8"]
86
87
88
def _hls(hls):
89
    dirname, name = get_path_info(hls.output_)
90
    streams = []
91
    for rep in hls.reps:
92
        streams += _get_hls_stream(hls, rep, dirname, name)
93
94
    return streams
95
96
97
def stream_args(media):
98
    return getattr(sys.modules[__name__], "_%s" % type(media).__name__.lower())(media)
99
100
101
def command_builder(ffmpeg_bin: str, media):
102
    args = [ffmpeg_bin] + cnv_options_to_args(dict(media.media.input_opts)) + stream_args(media)
103
    return " ".join(clean_args(args))
104
105