Esempio n. 1
0
def output():
    """
    this output is for playing on desktop with ffplay
    """
    overlay = []

    ff_pre_settings = [
        '-pix_fmt', 'yuv420p', '-r',
        str(_pre.fps), '-c:v', 'mpeg2video', '-intra', '-b:v',
        f'{_pre.v_bitrate}k', '-minrate', f'{_pre.v_bitrate}k', '-maxrate',
        f'{_pre.v_bitrate}k', '-bufsize', f'{_pre.v_bufsize}k'
    ] + pre_audio_codec() + ['-f', 'mpegts', '-']

    if _text.add_text and not _text.over_pre:
        messenger.info(
            f'Using drawtext node, listening on address: {_text.address}')
        overlay = [
            '-vf',
            "null,zmq=b=tcp\\\\://'{}',drawtext=text='':fontfile='{}'".format(
                _text.address.replace(':', '\\:'), _text.fontfile)
        ]

    try:
        enc_cmd = ['ffplay', '-hide_banner', '-nostats', '-i', 'pipe:0'
                   ] + overlay

        messenger.debug(f'Encoder CMD: "{" ".join(enc_cmd)}"')

        _ff.encoder = Popen(enc_cmd, stderr=PIPE, stdin=PIPE, stdout=None)

        enc_err_thread = Thread(target=ffmpeg_stderr_reader,
                                args=(_ff.encoder.stderr, False))
        enc_err_thread.daemon = True
        enc_err_thread.start()

        if _playlist.mode and not stdin_args.folder:
            watcher = None
            get_source = GetSourceFromPlaylist()
        else:
            messenger.info('Start folder mode')
            media = MediaStore()
            watcher = MediaWatcher(media)
            get_source = GetSourceFromFolder(media)

        try:
            for node in get_source.next():
                if watcher is not None:
                    watcher.current_clip = node.get('source')

                messenger.info(f'Play for {node["out"] - node["seek"]:.2f} '
                               f'seconds: {node.get("source")}')

                dec_cmd = [
                    'ffmpeg', '-v',
                    _log.ff_level.lower(), '-hide_banner', '-nostats'
                ] + node['src_cmd'] + node['filter'] + ff_pre_settings

                messenger.debug(f'Decoder CMD: "{" ".join(dec_cmd)}"')

                with Popen(dec_cmd, stdout=PIPE, stderr=PIPE) as _ff.decoder:
                    dec_err_thread = Thread(target=ffmpeg_stderr_reader,
                                            args=(_ff.decoder.stderr, True))
                    dec_err_thread.daemon = True
                    dec_err_thread.start()

                    while True:
                        buf = _ff.decoder.stdout.read(COPY_BUFSIZE)
                        if not buf:
                            break
                        _ff.encoder.stdin.write(buf)

        except BrokenPipeError:
            messenger.error('Broken Pipe!')
            terminate_processes(watcher)

        except SystemExit:
            messenger.info('Got close command')
            terminate_processes(watcher)

        except KeyboardInterrupt:
            messenger.warning('Program terminated')
            terminate_processes(watcher)

        # close encoder when nothing is to do anymore
        if _ff.encoder.poll() is None:
            _ff.encoder.terminate()

    finally:
        if _ff.encoder.poll() is None:
            _ff.encoder.terminate()
        _ff.encoder.wait()
Esempio n. 2
0
def output():
    """
    this output is for streaming to a target address,
    like rtmp, rtp, svt, etc.
    """
    year = get_date(False).split('-')[0]
    overlay = []

    ff_pre_settings = [
        '-pix_fmt', 'yuv420p', '-r',
        str(_pre.fps), '-c:v', 'mpeg2video', '-intra', '-b:v', '{}k'.format(
            _pre.v_bitrate), '-minrate', '{}k'.format(_pre.v_bitrate),
        '-maxrate', '{}k'.format(_pre.v_bitrate), '-bufsize', '{}k'.format(
            _pre.v_bufsize)
    ] + pre_audio_codec() + ['-f', 'mpegts', '-']

    if _text.add_text and not _text.over_pre:
        messenger.info('Using drawtext node, listening on address: {}'.format(
            _text.address))
        overlay = [
            '-vf',
            "null,zmq=b=tcp\\\\://'{}',drawtext=text='':fontfile='{}'".format(
                _text.address.replace(':', '\\:'), _text.fontfile)
        ]

    try:
        _ff.encoder = Popen([
            'ffmpeg', '-v',
            _log.ff_level.lower(), '-hide_banner', '-nostats', '-re',
            '-thread_queue_size', '256', '-i', 'pipe:0'
        ] + overlay + [
            '-metadata', 'service_name=' + _playout.name, '-metadata',
            'service_provider=' + _playout.provider, '-metadata',
            'year={}'.format(year)
        ] + _playout.ffmpeg_param + _playout.stream_output,
                            stdin=PIPE,
                            stderr=PIPE)

        enc_err_thread = Thread(target=ffmpeg_stderr_reader,
                                args=(_ff.encoder.stderr, False))
        enc_err_thread.daemon = True
        enc_err_thread.start()

        if _playlist.mode and not stdin_args.folder:
            watcher = None
            get_source = GetSourceFromPlaylist()
        else:
            messenger.info('Start folder mode')
            media = MediaStore()
            watcher = MediaWatcher(media)
            get_source = GetSourceFromFolder(media)

        try:
            for src_cmd in get_source.next():
                messenger.debug('src_cmd: "{}"'.format(src_cmd))
                if src_cmd[0] == '-i':
                    current_file = src_cmd[1]
                else:
                    current_file = src_cmd[3]

                _current.clip = current_file
                messenger.info('Play: "{}"'.format(current_file))

                with Popen([
                        'ffmpeg', '-v',
                        _log.ff_level.lower(), '-hide_banner', '-nostats'
                ] + src_cmd + ff_pre_settings,
                           stdout=PIPE,
                           stderr=PIPE) as _ff.decoder:

                    dec_err_thread = Thread(target=ffmpeg_stderr_reader,
                                            args=(_ff.decoder.stderr, True))
                    dec_err_thread.daemon = True
                    dec_err_thread.start()

                    while True:
                        buf = _ff.decoder.stdout.read(COPY_BUFSIZE)
                        if not buf:
                            break
                        _ff.encoder.stdin.write(buf)

        except BrokenPipeError:
            messenger.error('Broken Pipe!')
            terminate_processes(watcher)

        except SystemExit:
            messenger.info('Got close command')
            terminate_processes(watcher)

        except KeyboardInterrupt:
            messenger.warning('Program terminated')
            terminate_processes(watcher)

        # close encoder when nothing is to do anymore
        if _ff.encoder.poll() is None:
            _ff.encoder.terminate()

    finally:
        if _ff.encoder.poll() is None:
            _ff.encoder.terminate()
        _ff.encoder.wait()
Esempio n. 3
0
def output():
    """
    this output is for streaming to a target address,
    like rtmp, rtp, svt, etc.
    """
    year = get_date(False).split('-')[0]
    overlay = []

    ff_pre_settings = [
        '-pix_fmt', 'yuv420p', '-r',
        str(pre.fps), '-c:v', 'mpeg2video', '-intra', '-b:v',
        f'{pre.v_bitrate}k', '-minrate', f'{pre.v_bitrate}k', '-maxrate',
        f'{pre.v_bitrate}k', '-bufsize', f'{pre.v_bufsize}k'
    ] + pre_audio_codec() + ['-f', 'mpegts', '-']

    if lower_third.add_text and not lower_third.over_pre:
        messenger.info(
            f'Using drawtext node, listening on address: {lower_third.address}'
        )
        overlay = [
            '-vf',
            "null,zmq=b=tcp\\\\://'{}',drawtext=text='':fontfile='{}'".format(
                lower_third.address.replace(':', '\\:'), lower_third.fontfile)
        ]

    try:
        enc_cmd = [
            'ffmpeg', '-v',
            log.ff_level.lower(), '-hide_banner', '-nostats', '-re',
            '-thread_queue_size', '160', '-i', 'pipe:0'
        ] + overlay + [
            '-metadata', 'service_name=' + playout.name, '-metadata',
            'service_provider=' + playout.provider, '-metadata', f'year={year}'
        ] + playout.ffmpeg_param + playout.stream_output

        messenger.debug(f'Encoder CMD: "{" ".join(enc_cmd)}"')

        ff_proc.encoder = Popen(enc_cmd, stdin=PIPE, stderr=PIPE)

        enc_err_thread = Thread(target=ffmpeg_stderr_reader,
                                args=(ff_proc.encoder.stderr, False))
        enc_err_thread.daemon = True
        enc_err_thread.start()

        if playlist.mode and not stdin_args.folder:
            watcher = None
            get_source = GetSourceFromPlaylist()
        else:
            messenger.info('Start folder mode')
            media = MediaStore()
            watcher = MediaWatcher(media)
            get_source = GetSourceFromFolder(media)

        try:
            for node in get_source.next():
                if watcher is not None:
                    watcher.current_clip = node.get('source')

                messenger.info(f'Play: {node.get("source")}')

                dec_cmd = [
                    'ffmpeg', '-v',
                    log.ff_level.lower(), '-hide_banner', '-nostats'
                ] + node['src_cmd'] + node['filter'] + ff_pre_settings

                messenger.debug(f'Decoder CMD: "{" ".join(dec_cmd)}"')

                with Popen(dec_cmd, stdout=PIPE,
                           stderr=PIPE) as ff_proc.decoder:
                    dec_err_thread = Thread(target=ffmpeg_stderr_reader,
                                            args=(ff_proc.decoder.stderr,
                                                  True))
                    dec_err_thread.daemon = True
                    dec_err_thread.start()

                    while True:
                        buf = ff_proc.decoder.stdout.read(COPY_BUFSIZE)
                        if not buf:
                            break
                        ff_proc.encoder.stdin.write(buf)

        except BrokenPipeError:
            messenger.error('Broken Pipe!')
            terminate_processes(watcher)

        except SystemExit:
            messenger.info('Got close command')
            terminate_processes(watcher)

        except KeyboardInterrupt:
            messenger.warning('Program terminated')
            terminate_processes(watcher)

        # close encoder when nothing is to do anymore
        if ff_proc.encoder.poll() is None:
            ff_proc.encoder.terminate()

    finally:
        if ff_proc.encoder.poll() is None:
            ff_proc.encoder.terminate()
        ff_proc.encoder.wait()