예제 #1
0
def get_hls_mux_args(enc_params, hls_ingest_url):
    output_config = enc_params['output']
    segment_size = wc_utils.to_int(output_config['segment_size'])
    ffmpeg_out_url = hls_ingest_url
    now = datetime.datetime.now()
    ccgroup_name = 'cc'

    hls_args = ''
    hls_args += '%s=%s' %('f', 'hls')

    var_stream_map = ''
    if enc_params['output']['create_muxed_av'] == 'on' :
        for n in range(0, len(enc_params['video']['variants'])):
            var_stream_map += " a\:%d,v\:%d" %(n, n)
            if enc_params['video']['enable_cc'] == 'on':
                var_stream_map += ",ccgroup\:%s" %ccgroup_name
    else:
        for aud_tag in enc_params['audio']:
            aud_id = wc_utils.to_int(enc_params['audio'].keys().index(aud_tag))
            var_stream_map += " a\:%d,agroup\:%s" %(aud_id, aud_tag)
        for n in range(0, len(enc_params['video']['variants'])):
            var_stream_map += " v\:%d,agroup\:%s" \
                   %(n, enc_params['video']['variants'][n]['audio_tag'])
            if enc_params['video']['enable_cc'] == 'on':
                var_stream_map += ",ccgroup\:%s" %ccgroup_name

    if enc_params['output']['seg_in_subfolder'] == 'on' :
        hls_segment_filename = '%s/variant_%%v/stream_%02d%02d%02d_%%d.ts' %\
                               (ffmpeg_out_url.replace(':', '\:'),
                                now.hour, now.minute, now.second)
    else:
        hls_segment_filename = '%s/stream_%02d%02d%02d_%%v_%%d.ts' %\
                               (ffmpeg_out_url.replace(':', '\:'),
                                now.hour, now.minute, now.second)

    hls_flags = 'program_date_time+round_durations'

    hls_ts_options = 'mpegts_pmt_start_pid=480:mpegts_start_pid=481'

    hls_args += ':%s=\'%s\'' %('var_stream_map', var_stream_map)
    hls_args += ':%s=\'%s\'' %('hls_segment_filename', hls_segment_filename)
    hls_args += ':%s=%s' %('hls_time', segment_size)
    hls_args += ':%s=%s' %('hls_flags', hls_flags)
    hls_args += ':%s=\'%s\'' %('hls_ts_options', str(hls_ts_options).replace(':', '\:'))
    hls_args += ':%s=%s' %('http_persistent', 1)
    hls_args += ':%s=%s' %('http_user_agent', enc_params['output']['user_agent'])
    hls_args += ':%s=%s' %('hls_list_size', 6)
    hls_args += ':%s=\'%s\'' %('cc_stream_map', "ccgroup\:%s,instreamid\:CC1" %ccgroup_name)
    hls_args += ':%s=%s' %('master_pl_name', enc_params['output']['hls_master_manifest'])
    hls_args += ':%s=%s' %('master_pl_publish_rate', 100)
    hls_args += ':%s=%s' %('timeout', 0.5)
    hls_args += ':%s=%s' %('method', 'PUT')
    hls_args += ':%s=%s' %('ignore_io_errors', '1')

    if output_config['enable_abs_seg_path'] == 'on' :
        hls_args += ':%s=\'%s\'' %('hls_base_url',
                                 str(output_config['abs_seg_path_base_url']).replace(':', '\:'))

    return hls_args
예제 #2
0
def get_vcodec_args(enc_params, osi):
    vid_config = enc_params['video']['variants']
    video_codec = vid_config[osi]['codec']
    video_bitrate = wc_utils.to_int(vid_config[osi]['bitrate'])
    video_width = str(vid_config[osi]['video_width'])
    video_height = str(vid_config[osi]['video_height'])

    args = ''
    '''
    osi stands for output stream index. Each codec parameter is indexed with
    output stream index. This is needed for multi-bitrate usecase to
    map the encoded streamss to appropriate output streams.
    '''
    postfix = ':' + str(osi)

    if enc_params['video']['rate_control'] == 'cbr':
        vbv_bufsize = wc_utils.to_int(video_bitrate * 0.1)
    else:
        vbv_bufsize = video_bitrate

    args += ' -c:v%s %s' % (postfix, video_codec)
    args += ' -pix_fmt%s yuv420p' % (postfix)

    cc_flag = 0
    if enc_params['video']['enable_cc'] == 'on':
        cc_flag = 1

    if (video_codec == 'libx264'):
        args += ' -preset%s %s' % (postfix,
                                   enc_params['video']['speed_preset'])
        args += ' -a53cc%s %d -nal-hrd%s %s -x264opts%s scenecut=-1:rc_lookahead=0' % \
                (postfix, cc_flag, postfix, enc_params['video']['rate_control'], postfix)
        if psutil.cpu_count() > 8:
            args += ':threads=12'
    elif (video_codec == 'libvpx-vp9'):
        cpu_used = x264_preset_to_vp9_cpu_used(
            enc_params['video']['speed_preset'])
        args += ' -deadline%s realtime -cpu-used%s %d -tile-columns%s 4'\
                ' -frame-parallel%s 1 -threads%s 8 -static-thresh%s 0 -lag-in-frames%s 0 ' % \
                (postfix, postfix, cpu_used, postfix, postfix, postfix, postfix, postfix)

    args += ' -b:v%s %sk -bufsize%s %sk' % \
            (postfix, video_bitrate, postfix, vbv_bufsize)

    if (video_width != '-1' and video_height != '-1'):
        args += ' -s%s ' % postfix + video_width + 'x' + video_height + ' '

    args += ' -force_key_frames%s "expr:gte(t,n_forced*%s)" -bf%s %d' % \
            (postfix, enc_params['output']['segment_size'],\
             postfix, int(enc_params['video']['num_b_frame']))

    args += ' '
    return args
예제 #3
0
def get_dash_mux_args(enc_params):
    segment_size = wc_utils.to_int(enc_params['output']['segment_size'])

    now = datetime.datetime.now()
    curr_time = str(now.hour) + str(now.minute) + str(now.second)

    if enc_params['output']['seg_in_subfolder'] == 'on':
        chunk_name = '%s/chunk-stream_\$RepresentationID\$-\$Number%%05d\$.\$ext\$' % (
            curr_time)
        init_seg_name = '%s/init-stream\$RepresentationID\$.\$ext\$' % (
            curr_time)
    else:
        chunk_name = 'chunk-stream_%s_\$RepresentationID\$-\$Number%%05d\$.\$ext\$' % (
            curr_time)
        init_seg_name = 'init-stream_%s_\$RepresentationID\$.\$ext\$' % (
            curr_time)
    chunk_name = chunk_name.replace(':', '\:')
    streaming = 0
    if enc_params['output']['dash_chunked'] == 'on':
        streaming = 1

    dash_cmd = ''
    dash_cmd += '%s=%s' % ('f', 'dash')
    dash_cmd += ':%s=\'%s\'' % ('media_seg_name', chunk_name)
    dash_cmd += ':%s=\'%s\'' % ('init_seg_name', init_seg_name)
    dash_cmd += ':%s=%s' % ('min_seg_duration', int(segment_size) * 1000000)
    dash_cmd += ':%s=%s' % ('window_size', 3)
    if enc_params['output']['dash_segtimeline'] == 'on':
        dash_cmd += ':%s=%s' % ('use_timeline', 1)
    else:
        dash_cmd += ':%s=%s' % ('use_timeline', 0)
    dash_cmd += ':%s=%s' % ('http_user_agent',
                            enc_params['output']['user_agent'])
    dash_cmd += ':%s=%s' % ('streaming', streaming)
    dash_cmd += ':%s=%s' % ('index_correction', 1)
    dash_cmd += ':%s=%s' % ('timeout', 0.5)
    dash_cmd += ':%s=%s' % ('dash_segment_type', 'mp4')
    dash_cmd += ':%s=%s' % ('method', 'PUT')
    dash_cmd += ':%s=%s' % ('ignore_io_errors', '1')

    if enc_params['output']['lhls'] == 'on':
        dash_cmd += ':%s=%s' % ('lhls', '1')

    if (segment_size < 8):
        dash_cmd += ':%s=%s' % ('http_persistent', 1)
    if (enc_params['output']['out_type'] == 'CMAF'):
        dash_cmd += ":%s=%s" % ('hls_playlist', 1)

    dash_cmd += ' '
    return dash_cmd
예제 #4
0
def get_args(enc_params):

    out_type = enc_params['output']['out_type']

    if not 'tee_port' in enc_params['output']:
        enc_params['output']['tee_port'] = 0

    ffmpeg_output_args = ' '
    ffmpeg_input_args = ' '

    if enc_params['input']['input_interface'] != wc_capture.INPUT_INTERFACE_URL:
        ffmpeg_input_args += ' -copyts '
        ffmpeg_input_args += ' -probesize 10M -f %s ' % (
            enc_params['input']['input_interface'])
    else:
        if (urlparse.urlparse(
                enc_params['input']['inputurl']).scheme == 'file'):
            ffmpeg_input_args += ' -re '
        elif (urlparse.urlparse(
                enc_params['input']['inputurl']).scheme == 'rtmp'):
            ffmpeg_input_args += ' -listen 1 '

    if enc_params['input'][
            'input_interface'] == wc_capture.INPUT_INTERFACE_DECKLINK:
        '''
        video capture format is yuv 422
        audio sampling frequency is always 48kHz
        number of bits per audio sample is 16
        number audio channels are 2
        '''
        ffmpeg_input_args += ' -bm_v210 0 -audio_depth 16 -channels 2 '
        qbufsize = int(enc_params['input']['vid_width']) * \
                   int(enc_params['input']['vid_height']) * 2 * \
                   math.ceil(float(enc_params['input']['vid_framerate']))
        qbufsize += 48000 * 2 * 2
        ffmpeg_input_args += ' -queue_size %d ' % qbufsize
        ffmpeg_input_args += '-decklink_copyts 1 -audio_pts abs_wallclock -video_pts abs_wallclock '

    ffmpeg_input_args += '-i %s ' % (enc_params['input']['inputurl'])
    ffmpeg_input_args += '-flags +global_header '
    if enc_params['input']['input_interface'] != wc_capture.INPUT_INTERFACE_URL and\
       enc_params['input']['input_interface'] != wc_capture.INPUT_INTERFACE_AVFOUNDATION:
        fps_num, fps_den = wc_utils.map_fps_num_den(
            enc_params['input']['vid_framerate'])
        ffmpeg_input_args += '-r %s/%s ' % (fps_num, fps_den)

    if (enc_params['output']['burn_tc'] == 'on'):
        ffmpeg_output_args += '-vf drawbox="x=0:y=0:width=%s:height=%s:color=white:t=fill",drawtext="x=15:y=20:fontfile=/usr/share/fonts/truetype/freefont/%s.ttf:fontsize=%s:fontcolor=black:'\
                              %(enc_params['output']['drawbox_width'], enc_params['output']['drawbox_height'], enc_params['output']['fonttype'], enc_params['output']['fontsize'])
        if enc_params['input'][
                'input_interface'] == wc_capture.INPUT_INTERFACE_URL and (
                    urlparse.urlparse(
                        enc_params['input']['inputurl']).scheme == 'file'):
            ffmpeg_output_args += 'expansion=strftime:text=\'%H\\:%M\\:%S\'"'
        else:
            ffmpeg_output_args += 'text=\'%%{pts\\:hms\\:%d\\:24HH}\'"' % (
                (time.timezone * -1))

    ffmpeg_output_args += ' -af aresample=async=1 '
    num_vid_sub_streams = len(enc_params['video']['variants'])
    num_aud_sub_streams = len(enc_params['audio'])

    vid_config = enc_params['video']['variants']
    for n in range(0, num_vid_sub_streams):
        ffmpeg_output_args += get_vcodec_args(enc_params, n)

    if enc_params['output']['create_muxed_av'] == 'on':
        num_aud_sub_streams = num_vid_sub_streams
        for n in range(0, num_vid_sub_streams):
            audio_ref_tag = vid_config[n]['audio_tag']
            audio_bitrate = wc_utils.to_int(
                enc_params['audio'][audio_ref_tag]['bitrate'])
            audio_codec = enc_params['audio'][audio_ref_tag]['codec']
            ffmpeg_output_args += get_acodec_args(n, audio_codec,
                                                  audio_bitrate)
    else:
        for aud_tag in enc_params['audio']:
            aud_id = wc_utils.to_int(enc_params['audio'].keys().index(aud_tag))
            audio_bitrate = wc_utils.to_int(
                enc_params['audio'][aud_tag]['bitrate'])
            audio_codec = enc_params['audio'][aud_tag]['codec']
            ffmpeg_output_args += get_acodec_args(aud_id, audio_codec,
                                                  audio_bitrate)

    if enc_params['output']['lhls'] == 'on':
        ffmpeg_output_args += ' -strict experimental'

    ffmpeg_output_args += ' -f tee '

    for n in range(0, num_vid_sub_streams):
        ffmpeg_output_args += '-map 0:v '
    for n in range(0, num_aud_sub_streams):
        if enc_params['input'][
                'input_interface'] == wc_capture.INPUT_INTERFACE_V4L2:
            ffmpeg_output_args += '-map 1:a? '
        else:
            ffmpeg_output_args += '-map 0:a? '

    if (out_type == 'HLS'):
        hls_ingest_url = enc_params['output']['ingest_url'].rstrip('/')

        ffmpeg_mux_args = get_hls_mux_args(enc_params, hls_ingest_url)

        if enc_params['output']['seg_in_subfolder'] == 'on':
            ffmpeg_out_url = '%s/variant_%%v/media.m3u8 ' % hls_ingest_url
        else:
            ffmpeg_out_url = '%s/media_%%v.m3u8 ' % hls_ingest_url

        ffmpeg_output_args += '"[%s]%s' % (ffmpeg_mux_args, ffmpeg_out_url)
        if enc_params['output']['b_ingest_url'] != '':
            hls_ingest_url = enc_params['output']['b_ingest_url'].rstrip('/')

            ffmpeg_mux_args = get_hls_mux_args(enc_params, hls_ingest_url)
            if enc_params['output']['seg_in_subfolder'] == 'on':
                ffmpeg_out_url = '%s/variant_%%v/media.m3u8 ' % hls_ingest_url
            else:
                ffmpeg_out_url = '%s/media_%%v.m3u8 ' % hls_ingest_url
            ffmpeg_output_args += '|[%s]%s' % (ffmpeg_mux_args, ffmpeg_out_url)

        ffmpeg_output_args += '"'

    elif (out_type == 'DASH' or out_type == 'CMAF'):
        dash_ingest_url = enc_params['output']['ingest_url'].rstrip('/')

        ffmpeg_mux_args = get_dash_mux_args(enc_params)
        ffmpeg_out_url = '%s/%s ' %(dash_ingest_url,\
                                    enc_params['output']['dash_master_manifest'])
        ffmpeg_output_args += '"[%s]%s' % (ffmpeg_mux_args, ffmpeg_out_url)

        if enc_params['output']['b_ingest_url'] != '':
            dash_ingest_url = enc_params['output']['b_ingest_url'].rstrip('/')

            ffmpeg_mux_args = get_dash_mux_args(enc_params)
            ffmpeg_out_url = '%s/%s ' %(dash_ingest_url,\
                                        enc_params['output']['dash_master_manifest'])
            ffmpeg_output_args += '|[%s]%s' % (ffmpeg_mux_args, ffmpeg_out_url)

        ffmpeg_output_args += '"'

    args = ffmpeg_input_args + ffmpeg_output_args
    return args
예제 #5
0
def validate_encoder_params(encoder_params):
    min_video_bitrate = 200
    max_video_bitrate = 20000

    min_audio_bitrate = 32
    max_audio_bitrate = 320

    min_segment_size = 1
    max_segment_size = 60

    min_video_width = 160
    min_video_height = 120
    max_video_width = 4096
    max_video_height = 2160

    num_devices = capture.get_devices(False)
    input_id = encoder_params['input_id']
    out_type = encoder_params['output']['out_type']

    # TODO(Karthick) : Security RISK. More input validation needs to done here
    if int(input_id) < 0 or \
       int(input_id) > int(num_devices):
        msg = 'Invalid input_id:' + str(input_id)
        return False, msg

    if len(encoder_params['video']['variants']) <= 0:
        msg = 'No video bitrates specified'
        return False, msg

    num_vid_sub_streams = len(encoder_params['video']['variants'])
    num_aud_sub_streams = len(encoder_params['audio'])

    for n in range(0, num_vid_sub_streams):
        vid_config = encoder_params['video']['variants']

        video_codec = vid_config[n]['codec']
        if video_codec not in codecs.get_codecs():
            msg = 'Selected codec ' + video_codec + ' not supported'
            return False, msg

        video_bitrate = wc_utils.to_int(vid_config[n]['bitrate'])

        try:
            video_width = int(vid_config[n]['video_width'])
            video_height = int(vid_config[n]['video_height'])
        except:
            msg = 'Invalid video_width or video_height:' + \
                   str(vid_config[n]['video_width']) + ' or ' + \
                   str(vid_config[n]['video_height'])
            return False, msg

        if (video_bitrate > max_video_bitrate) or (video_bitrate <
                                                   min_video_bitrate):
            msg = 'Invalid video_bitrate:' + str(video_bitrate)
            return False, msg

        if (video_width != -1 and
            (video_width < min_video_width or video_width > max_video_width or
             (video_width % 2) != 0)):
            msg = 'Invalid video_width: ' + str(video_width)
            msg += ' min:' + str(min_video_width) + ' max:' + str(
                max_video_width)
            msg += ' and video_width is expected to be multiple of 2'
            return False, msg
        if (video_height != -1 and
            (video_height < min_video_height or video_height > max_video_height
             or (video_height % 2) != 0)):
            msg = 'Invalid video_height: ' + str(video_height)
            msg += ' min:' + str(min_video_height) + ' max:' + str(
                max_video_height)
            msg += ' and video_height is expected to be multiple of 2'
            return False, msg

    speed_preset = encoder_params['video']['speed_preset']
    if speed_preset != 'slower' and speed_preset != 'slow' and speed_preset != 'medium' and \
        speed_preset != 'fast' and speed_preset != 'faster' and speed_preset != 'veryfast' and \
        speed_preset != 'superfast' and speed_preset != 'ultrafast':
        msg = 'Invalid speed_preset: ' + str(speed_preset)
        return False, msg

    if encoder_params['video']['rate_control'] != 'cbr' and \
       encoder_params['video']['rate_control'] != 'vbr':
        msg = 'Invalid rate_control: ' + str(
            encoder_params['video']['rate_control'])
        return False, msg

    if (encoder_params['video']['enable_cc'] != 'on') and \
       (encoder_params['video']['enable_cc'] != 'off'):
        msg = ' Invalid  enable_cc flag ' + str(
            encoder_params['video']['enable_cc'])
        return False, msg

    if (encoder_params['video']['num_b_frame'] > 8):
        msg = ' Invalid number of B frames, max supported is 8 '
        return False, msg

    for aud_tag in encoder_params['audio']:
        audio_bitrate = wc_utils.to_int(
            encoder_params['audio'][aud_tag]['bitrate'])
        audio_codec = encoder_params['audio'][aud_tag]['codec']

        if audio_codec != 'aac':
            msg = ' Invalid audio_codec:' + str(audio_codec)
            return False, msg

        if (audio_bitrate > max_audio_bitrate) or (audio_bitrate <
                                                   min_audio_bitrate):
            msg = ' Invalid audio_bitrate:' + str(audio_bitrate)
            return False, msg

    if (encoder_params['output']['burn_tc'] != 'on') and \
       (encoder_params['output']['burn_tc'] != 'off'):
        msg = ' Invalid  burn_tc flag ' + str(
            encoder_params['output']['burn_tc'])
        return False, msg

    if (encoder_params['output']['create_muxed_av'] != 'on') and \
       (encoder_params['output']['create_muxed_av'] != 'off'):
        msg = ' Invalid  create_muxed_av flag ' + str(
            encoder_params['output']['create_muxed_av'])
        return False, msg
    if (out_type != 'HLS') and (encoder_params['output']['create_muxed_av']
                                == 'on'):
        msg = ' Muxed AV flag is not expected to be set for non HLS format ' + out_type
        return False, msg

    if (encoder_params['output']['enable_abs_seg_path'] != 'on') and \
       (encoder_params['output']['enable_abs_seg_path'] != 'off'):
        msg = ' Invalid  enable_abs_seg_path flag ' + str(
            encoder_params['output']['enable_abs_seg_path'])
        return False, msg
    if (out_type != 'HLS') and (encoder_params['output']['enable_abs_seg_path']
                                == 'on'):
        msg = ' Enable absolute segment path flag is not expected to be set for non HLS format ' + out_type
        return False, msg
    if encoder_params['output']['enable_abs_seg_path'] == 'on':
        parsed_url = urlparse.urlparse(
            encoder_params['output']['abs_seg_path_base_url'])
        if False == (bool(parsed_url.scheme) and bool(parsed_url.netloc)):
            msg = ' Invalid  absolute segment path base URL ' + str(
                encoder_params['output']['abs_seg_path_base_url'])
            return False, msg
        if not encoder_params['output']['abs_seg_path_base_url'].endswith('/'):
            encoder_params['output']['abs_seg_path_base_url'] += '/'
    if (encoder_params['output']['seg_in_subfolder'] != 'on') and \
       (encoder_params['output']['seg_in_subfolder'] != 'off'):
        msg = ' Invalid  seg_in_subfolder flag ' + str(
            encoder_params['output']['seg_in_subfolder'])
        return False, msg

    if (out_type != 'HLS') and (out_type != 'DASH') and \
       (out_type != 'CMAF'):
        msg = ' Invalid  out_type ' + str(out_type)
        return False, msg

    if (out_type == 'HLS' or out_type == 'DASH' or out_type == 'CMAF'):
        segment_size = wc_utils.to_int(
            encoder_params['output']['segment_size'])
        if segment_size > max_segment_size or \
           segment_size < min_segment_size:
            msg = ' Invalid segment size: ' + str(segment_size)
            return False, msg

    if out_type == 'HLS' or out_type == 'DASH' or out_type == 'CMAF':
        parsed_url = urlparse.urlparse(encoder_params['output']['ingest_url'])
        if False == (bool(parsed_url.scheme) and bool(parsed_url.netloc)):
            msg = ' Invalid  ingest_url ' + str(
                encoder_params['output']['ingest_url'])
            return False, msg

    if out_type == 'DASH' or out_type == 'CMAF':
        if (encoder_params['output']['dash_chunked'] != 'on') and \
           (encoder_params['output']['dash_chunked'] != 'off'):
            msg = ' Invalid  dash_chunked flag ' + str(
                encoder_params['output']['dash_chunked'])
            return False, msg

    if out_type == 'CMAF':
        if (encoder_params['output']['lhls'] != 'on') and \
           (encoder_params['output']['lhls'] != 'off'):
            msg = ' Invalid  LHLS flag ' + str(
                encoder_params['output']['lhls'])
            return False, msg
    else:
        if (encoder_params['output']['lhls'] != 'off'):
            msg = ' Invalid  LHLS flag ' + str(
                encoder_params['output']['lhls'])
            return False, msg
    return True, ''
예제 #6
0
def start_encoder(enc_params):
    print 'Starting encoder'
    """
    WSGI Application that gets called with the set environment and the
    response generation function.
    """
    default_config = {
        "input_id": "-1",
        "video": {
            "speed_preset":
            "fast",
            "rate_control":
            "cbr",
            "enable_cc":
            "on",
            "num_b_frame":
            8,
            "variants": [{
                "codec": "libx264",
                "bitrate": "-1",
                "video_width": "-1",
                "video_height": "-1",
                "audio_tag": "0"
            }]
        },
        "audio": {
            "0": {
                "bitrate": "-1",
                "codec": "aac"
            }
        },
        "output": {
            "out_type": "HLS",
            "segment_size": "5",
            "burn_tc": "off",
            "create_muxed_av": "off",
            "enable_abs_seg_path": "off",
            "abs_seg_path_base_url": "",
            "seg_in_subfolder": "off",
            "ingest_url": "",
            "b_ingest_url": "",
            "dash_chunked": "off",
            "lhls": "off",
            "hls_master_manifest": "master.m3u8",
            "dash_master_manifest": "out.mpd"
        },
    }
    ffmpeg_proc_name = 'ffmpeg '

    store_default_config(default_config, enc_params)
    status, msg = validate_encoder_params(enc_params)
    if False == status:
        reason = 'Bad Request: ' + msg
        return 400, reason

    input_id = str(enc_params['input_id'])
    segment_size = wc_utils.to_int(enc_params['output']['segment_size'])
    out_type = enc_params['output']['out_type']

    print 'Inside start_encoder.py input_id:' + str(enc_params['input_id'])

    #Kill any existing process
    stopencoder.stop_encoder(input_id)

    #Store the json input in a file
    store_load_input_cfg.store_json_cfg(enc_params)

    enc_params['input'] = {}
    enc_params['input']['input_interface'] = capture.get_input_interface(
        int(input_id))
    enc_params['input']['inputurl'] = capture.get_inputurl(int(input_id))

    ffmpeg_format_args = ''

    if enc_params['input']['input_interface'] == capture.INPUT_INTERFACE_URL:
        ffmpeg_format_args += ' -timeout 1000000 -analyzeduration 5000000 '
    else:
        ffmpeg_format_args += ' -probesize 10M -f ' + enc_params['input'][
            'input_interface']

    ffmpeg_format_args += ' -i %s' % (enc_params['input']['inputurl'])

    vid_w, vid_h, vid_fr, scantype, device_status = capture.find_input_format(
        ffmpeg_proc_name + ffmpeg_format_args)
    if device_status != 'Active':
        print 'Input signal detection failed: ' + str(device_status)

    enc_params['input']['vid_width'] = vid_w
    enc_params['input']['vid_height'] = vid_h
    enc_params['input']['vid_framerate'] = vid_fr
    enc_params['input']['vid_scantype'] = scantype

    enc_params['output']['user_agent'] = USER_AGENT
    enc_params['output']['drawbox_width'] = 500
    enc_params['output']['drawbox_height'] = 88
    enc_params['output']['fonttype'] = "FreeSerif"
    enc_params['output']['fontsize'] = 80

    args = wc_ffmpeg_args.get_args(enc_params)
    print ffmpeg_proc_name + args
    proc = subprocess.Popen(shlex.split(ffmpeg_proc_name + args))
    pid = proc.pid

    current_time = time.time() * 1000000

    for n in range(0, len(enc_params['video']['variants'])):

        cfg = {
            'TIME': int(current_time),  #current time
            'InputID': int(input_id),  #Input ID
            'SubStreamID': int(n),  #Substream ID
            'ProcessID': pid,  #ProcessID
            'VidInWidth': int(vid_w),  #Input video width
            'VidInHt': int(vid_h),  #Input video height
            'InScanType': str(scantype),  #Input scantype
            'VidInFrameRate': str(vid_fr),  #Input framerate
            'FrameRate': str(vid_fr),  #Output framerate
        }

        configdb.insert_stream_config(cfg)

    print 'All Ok, encoder started successfully'
    return 200, 'OK'