Beispiel #1
0
def return_with_progress(stream_spec):
    args = ffmpeg.compile(stream_spec)
    return subprocess.Popen(args,
                            stdin=None,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.STDOUT,
                            universal_newlines=True)
Beispiel #2
0
 def run_async(self):
     if not self.ff_segment_out:
         raise Exception('Command is not ready')
     if logger.isEnabledFor(logging.DEBUG):
         logger.debug("FFmpeg CLI command: '%s'",
                      " ".join(ffmpeg.compile(self.ff_segment_out)))
     return self.ff_segment_out.run_async()
Beispiel #3
0
def test__run_async(mocker, pipe_stdin, pipe_stdout, pipe_stderr, cwd):
    process__mock = mock.Mock()
    popen__mock = mocker.patch.object(subprocess,
                                      'Popen',
                                      return_value=process__mock)
    stream = _get_simple_example()
    process = ffmpeg.run_async(
        stream,
        pipe_stdin=pipe_stdin,
        pipe_stdout=pipe_stdout,
        pipe_stderr=pipe_stderr,
        cwd=cwd,
    )
    assert process is process__mock

    expected_stdin = subprocess.PIPE if pipe_stdin else None
    expected_stdout = subprocess.PIPE if pipe_stdout else None
    expected_stderr = subprocess.PIPE if pipe_stderr else None
    (args, ), kwargs = popen__mock.call_args
    assert args == ffmpeg.compile(stream)
    assert kwargs == dict(
        stdin=expected_stdin,
        stdout=expected_stdout,
        stderr=expected_stderr,
        cwd=cwd,
    )
Beispiel #4
0
 def _estublish_cmd(self, scenes: List[Scene]):
     inputfile = self.input_media_path.as_posix()
     outputfile = self.output_media_path.as_posix()
     stream = ffmpeg.input(inputfile)
     video_streams = list()
     audio_streams = list()
     for scene in scenes:
         start = scene.get_startat()
         duration = scene.get_interval()
         v_clip_stream = ffmpeg.trim(
             stream, start=start, duration=duration)
         v_clip_stream = ffmpeg.setpts(v_clip_stream, 'PTS-STARTPTS')
         a_clip_stream = ffmpeg.filter_(
             stream, 'atrim', start=start, duration=duration)
         a_clip_stream = ffmpeg.filter_(
             a_clip_stream, 'asetpts', 'PTS-STARTPTS')
         video_streams.append(v_clip_stream)
         audio_streams.append(a_clip_stream)
     v_stream = ffmpeg.concat(
         *video_streams, n=len(video_streams), v=1, a=0)
     a_stream = ffmpeg.concat(
         *audio_streams, n=len(audio_streams), v=0, a=1)
     stream = ffmpeg.output(
         v_stream, a_stream, outputfile, **self.CONFIG_720P)
     # ffmpeg.view(stream)  # Debug
     self.stream = stream
     return ' '.join(ffmpeg.compile(stream))
Beispiel #5
0
 def receive(self, text_data):
     text_data_json = json.loads(text_data)
     params = text_data_json
     params['username'] = '******'
     input_vid = ffmpeg.input(params['url'])
     vid = input_vid.trim(start=params['start_time'], end=params['end_time']).setpts('PTS-STARTPTS')
     aud = input_vid.filter_('atrim', start=params['start_time'], end=params['end_time']).filter_('asetpts', 'PTS-STARTPTS')
     joined = ffmpeg.concat(vid, aud, v=1, a=1).node
     stream = ffmpeg.output(joined[0], joined[1], f"out_t_{params['username']}.mp4")
     stream = stream.overwrite_output()
     log = LogController.add_log(params['username'], params['start_time'], params['end_time'], params['url'])
     cmd = ffmpeg.compile(stream)
     process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, encoding="utf-8")
     for line in process.stdout:
         duration_res = re.search(r'\sDuration: (?P<duration>\S+)', line)
         if duration_res is not None:
             duration = duration_res.groupdict()['duration']
             duration = re.sub(r',', '', duration)
             
         result = re.search(r'\stime=(?P<time>\S+)', line)
         if result is not None:
             elapsed_time = result.groupdict()['time']
             progress = (get_seconds(elapsed_time) / get_seconds(duration)) * 100
             print("进度:%3.2f" % progress + "%")
             # time.sleep(1)
             self.send(text_data=json.dumps({'progress': progress}))
     process.wait()
     if process.poll() == 0:
         self.send(text_data=json.dumps({'progress': 100.00}))
         self.send(text_data=json.dumps({'msg': 'success'}))
Beispiel #6
0
def test(orgasmos):
    import ffmpeg
    from datetime import datetime
    stream = ffmpeg.input(
        "data\\upload\\orgasmos\\1-x-ti\\pqaY1OJ9eWOzWgVZDn-L1TAnkcdnJrUR.mp3")
    stream = ffmpeg.filter(stream, 'loudnorm')
    concatList = []
    selected = {1: stream}
    for _ in range(5):
        id = 1
        stream = selected.get(id)
        streams = ffmpeg.filter_multi_output(stream, 'asplit')
        selected[id] = streams.stream(0)
        stream = streams.stream(1)
        concatList.append(stream)

    fullStream = ffmpeg.concat(*concatList, v=0, a=1)
    outputFilename = "mix-test-{:d}.m4a".format(int(
        datetime.now().timestamp()))
    outputPath = basePath.joinpath("mixed").joinpath(outputFilename)
    fullStream = fullStream.output(str(outputPath))
    cmd = ffmpeg.compile(fullStream)
    print(cmd)
    ffmpeg.view(fullStream, filename=str(outputPath) + ".png")
    # ffmpeg.run(fullStream)
    pass
def extract_audio_into_file(video,
                            save_dir='',
                            ext_format='mp3',
                            force_overwrite=False,
                            verbose=False):
    """
    Extract_audio_into_file:

    @params:
        video: str
            Paths to input video
        save_dir: str or None
            Path to save output stacked video files, if None, save under working dir.
        ext_format: str
            Extesion format for output audio file, i.e. `mp3`, `.mp3`, `wav`, `acc`.
        force_overwrite: bool
            If False, try to firstly load available audio file and trim info json files.
            If True, just extract audio and calc trim_info_dict. 
        verbose: bool
            Print verbose information, mainly for debug.

    @return:
        audio_file: str,
            path of saved audio file.
    """
    if verbose:
        print('===> Video: ', video)

    if not ext_format.startswith('.'):
        ext_format = '.' + ext_format

    audio_file = osp.splitext(video)[0] + ext_format

    if save_dir:
        basename = osp.basename(audio_file)
        if not osp.isdir(save_dir):
            os.makedirs(save_dir)
        audio_file = osp.join(save_dir, basename)

    if verbose:
        print('===> audio_file saved into: ', audio_file)

    if not osp.isfile(audio_file) or force_overwrite:
        in_stream = ffmpeg.input(video)

        out_stream = ffmpeg.output(in_stream.audio, audio_file)
        if verbose:
            cmdline = ffmpeg.compile(out_stream)
            print('===> ffmpeg cmdline:', cmdline)

        out_stream.run()
    else:
        print('===> audio file already exists at {}, skip'.format(audio_file))

    return audio_file
Beispiel #8
0
    def __init__(self, filename, out_filename):
        os.makedirs(os.path.dirname(out_filename), exist_ok=True)
        self.out_filename = out_filename
        self.log_filename = os.path.splitext(self.out_filename)[0] + ".log"
        self.stderr = open(self.log_filename, "w", encoding="utf8")
        self.pipe_read, self.pipe_write = os.pipe()
        self.pipe_read_file = os.fdopen(self.pipe_read)

        probe = ffmpeg.probe(filename)
        duration = float(probe["format"]["duration"])
        seconds = int(duration)
        milliseconds = int((duration - seconds) * 1000)
        self.duration = datetime.timedelta(seconds=seconds,
                                           milliseconds=milliseconds)

        info = [s for s in probe["streams"] if s["codec_type"] == "video"][0]
        self.width = info["width"]
        self.height = info["height"]
        source_bitrate = get_video_bitrate(probe)
        # Pick bitrate based on resolution, 1080p (8Mbps), 720p (5Mbps), smaller (3Mbps)
        bitrate = 3000
        if self.height > 720:
            bitrate = 8000
        elif self.height > 480:
            bitrate = 5000
        # Don't exceed the source bitrate as our target
        if bitrate > source_bitrate:
            bitrate = source_bitrate

        encoding_args = {
            # HWAccel for RPi4, may need to pick a different encoder
            # for HW accel on other systems
            "c:v": "h264_v4l2m2m",
            "num_output_buffers": 32,
            "num_capture_buffers": 16,
            "b:v": f"{bitrate}k",
            "c:a": "copy",
            "progress": f"pipe:{self.pipe_write}"
        }
        self.start = datetime.datetime.now()
        in_stream = ffmpeg.input(filename)
        video = in_stream.video.filter("format", **{"pix_fmts": "yuv420p"})
        enc = ffmpeg.output(video, in_stream.audio, self.out_filename,
                            **encoding_args)
        args = ffmpeg.compile(enc, overwrite_output=True)
        self.proc = subprocess.Popen(args,
                                     stdout=subprocess.DEVNULL,
                                     stderr=self.stderr,
                                     pass_fds=[self.pipe_write])
        self.encode_stats = {}
        self.encode_error = False
Beispiel #9
0
 def run(self):
     global compiling
     compiling = True
     print("compiling started!")
     print(self.attr, self.amb)
     self.start_button.emit(False)
     util.clean_up()
     download.playlist_download(self, self.attr['playlist'], self.attr['config'].options_dict['audio_bitrate'])
     if self.attr['config'].options_dict['ambience']:
         download.ambience_download(self, self.amb, self.attr['config'].options_dict['audio_bitrate'])
     tracklist_length = util.generate_tracklist(self.attr['config'])
     if self.attr['config'].options_dict['stretch_image']:
         self.attr['thumbnail'] = util.stretch_image(self.attr['thumbnail'])
     title = self.attr['title']
     if title == "":
         title = self.attr['playlist'][self.attr['playlist'].index("=")+1:]
     ffmpeg.compile(self, title, self.attr['thumbnail'], int(self.attr['config'].options_dict['audio_bitrate'])*1000, int(self.attr['config'].options_dict['video_bitrate'])*1000, self.attr['config'].options_dict['normalize_audio'], self.attr['config'].options_dict['ambience'], tracklist_length)
     self.progress_update.emit(['format', ""])
     self.progress_update.emit(['increment', 0])
     util.clean_up()
     compiling = False
     self.start_button.emit(True)
     print("compiling finished!")
Beispiel #10
0
def createVideoClip(clip, outputfile, fps, size=[256, 256]):

    vf = clip.shape[0]

    args = [  #'ffmpeg',
        '-y',  # overwrite output file if it exists
        '-f',
        'rawvideo',
        '-s',
        '%dx%d' % (size[1], size[0]),  # '256x256', # size of one frame
        '-pix_fmt',
        'rgb24',
        '-r',
        str(fps),  # frames per second
        '-an',  # Tells FFMPEG not to expect any audio
        '-i',
        '-',  # The input comes from a pipe
        '-vcodec',
        'libx264',
        '-b:v',
        '1500k',
        '-vframes',
        str(vf),  # 5*25
        '-s',
        '%dx%d' % (size[1], size[0]),  # '256x256', # size of one frame
        outputfile
    ]

    process = (ffmpeg.input('pipe:',
                            format='rawvideo',
                            pix_fmt='rgb24',
                            s='{}x{}'.format(size[1], size[0])).output(
                                outputfile,
                                pix_fmt='yuv420p',
                                format='mp4',
                                video_bitrate='1500k',
                                r=str(fps),
                                s='{}x{}'.format(size[1],
                                                 size[0])).overwrite_output())

    command = ffmpeg.compile(process, overwrite_output=True)

    #command = ffmpeg.get_args(args, overwrite_output=True)
    # sfolder+'/'+name
    pipe = sp.Popen(command, stdin=sp.PIPE, stderr=sp.PIPE)
    out, err = pipe.communicate(clip.tostring())
    pipe.wait()
    pipe.terminate()
    print(err)
Beispiel #11
0
    def __init__(
        self,
        input_path: pathlib.Path,
        input_width: int,
        input_height: int,
        frame_rate: float,
        processing_queue: multiprocessing.Queue,
        processing_settings: tuple,
        pause: Synchronized,
        ignore_max_image_pixels=True,
    ) -> None:
        threading.Thread.__init__(self)
        self.running = False
        self.input_path = input_path
        self.input_width = input_width
        self.input_height = input_height
        self.processing_queue = processing_queue
        self.processing_settings = processing_settings
        self.pause = pause

        # this disables the "possible DDoS" warning
        if ignore_max_image_pixels:
            Image.MAX_IMAGE_PIXELS = None

        self.exception = None
        self.decoder = subprocess.Popen(
            ffmpeg.compile(
                ffmpeg.input(input_path, r=frame_rate)["v"].output(
                    "pipe:1", format="rawvideo", pix_fmt="rgb24",
                    vsync="cfr").global_args("-hide_banner").global_args(
                        "-nostats").global_args("-nostdin").global_args(
                            "-loglevel",
                            LOGURU_FFMPEG_LOGLEVELS.get(
                                os.environ.get("LOGURU_LEVEL",
                                               "INFO").lower()),
                        ),
                overwrite_output=True,
            ),
            env={"AV_LOG_FORCE_COLOR": "TRUE"},
            stdin=subprocess.DEVNULL,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
        )

        # start the PIPE printer to start printing FFmpeg logs
        self.pipe_printer = PipePrinter(self.decoder.stderr)
        self.pipe_printer.start()
Beispiel #12
0
def vid2gif(src, dst, output_width="-1", output_height="-1", start_time=-1.0, stop_time=-1.0, fps=-1):

    # ffmpeg -y -i in.mp4 -t 30 -filter_complex "fps=10,scale=-1:-1:flags=lanczos,split[x][y];[x]palettegen[z];[y][z]paletteuse" out.gif
    in_stream = ffmpeg.input(src, ss=start_time, t=(stop_time-start_time))
    scale_input = in_stream
    if fps >= 1:
        stream = ffmpeg.filter(in_stream['v'], 'fps', fps)
        scale_input = stream

    stream = ffmpeg.filter(scale_input, 'scale', output_width, output_height, 'lanczos')
    
    palette = ffmpeg.filter(in_stream['v'], 'palettegen')
    stream = ffmpeg.filter(stream, palette, 'paletteuse')
    stream = stream.overwrite_output(dst, format='gif')
    print(ffmpeg.compile(stream))
    ffmpeg.run(stream,overwrite_output=True)
    ffmpeg.run(palette)
Beispiel #13
0
def convert_video_progress_bar(source: str, dest: str, manager=None):
    if manager is None:
        manager = enlighten.get_manager()
    stream = ffmpeg.input(source)
    stream = ffmpeg.output(stream, dest, vcodec='libx265', crf='28')
    args = ffmpeg.compile(stream, 'ffmpeg')
    args.insert(1, '-progress pipe:1')
    args = map(lambda x: '"' + x + '"' if '\\' in x or '/' in x else x, args)
    args = list(args)
    name = source.rsplit(os.path.sep, 1)[-1]
    proc = expect.spawn(' '.join(args), encoding='utf-8')
    pbar = None
    try:
        proc.expect(pattern_duration)
        total = sum(
            map(lambda x: float(x[1]) * 60**x[0],
                enumerate(reversed(
                    proc.match.groups()[0].strip().split(':')))))
        cont = 0
        pbar = manager.counter(total=100,
                               desc=name,
                               unit='%',
                               bar_format=BAR_FMT,
                               counter_format=COUNTER_FMT)
        while True:
            proc.expect(pattern_progress)
            progress = sum(
                map(
                    lambda x: float(x[1]) * 60**x[0],
                    enumerate(
                        reversed(proc.match.groups()[0].strip().split(':')))))
            percent = progress / total * 100
            pbar.update(percent - cont)
            cont = percent
    except expect.EOF:
        pass
    finally:
        if pbar is not None:
            pbar.close()
    proc.expect(expect.EOF)
    res = proc.before
    res += proc.read()
    exitstatus = proc.wait()
    if exitstatus:
        raise ffmpeg.Error('ffmpeg', '', res)
    def generate_cmd(self,
                     output: FileDesc,
                     quiet: bool = True,
                     y: bool = True,
                     accurate_seek: bool = False,
                     other_args: List[str] = []) -> List[str]:
        """
        生成变换用的命令

        :param output: 输出文件
        :param quiet: 静默模式,对应 ffmpeg 的 -v quiet
        :param y: 不进行确认,对应 ffmpeg 的 -y
        :param accurate_seek: 精准时间切割,对应 ffmpeg 的 -accurate_seek -avoid_negative_ts 1
        :param other_args: 其它 ffmpeg 的参数
        :returns: 变换用的命令
        :raises AssertionError
        """

        global_args = []
        if self.now_duration is not None:
            self.input.update({
                'ss': str(self.now_duration[0]),
                't': str(self.now_duration[1]),
            })
            if accurate_seek:
                self.input.update({
                    'accurate_seek': None,
                    'avoid_negative_ts': '1',
                })
        if quiet:
            global_args += ['-v', 'quiet']
        global_args += other_args
        stream = ffmpeg.output(
            self.stream,
            **self.__get_file_parameters(output),
        )
        if global_args:
            stream = ffmpeg.nodes.GlobalNode(stream, 'my_args',
                                             global_args).stream()

        return ffmpeg.compile(stream, overwrite_output=y)
Beispiel #15
0
def custom_ffmpeg_run(output, cmd):
    full_cmd = ffmpeg.compile(output, cmd=cmd)
    # print(' '.join([f'"{x}"' for x in full_cmd]))

    filter_str = None
    for i in range(0, len(full_cmd)):
        x = full_cmd[i]
        if x == '-filter_complex':
            full_cmd[i] = '-filter_complex_script'
            filter_str = full_cmd[i + 1]
            full_cmd[i + 1] = 'filter.txt'

    with open('filter.txt', 'w', encoding='utf8') as f:
        f.write(filter_str)

    # print(' '.join([f'"{x}"' for x in full_cmd]))
    import subprocess
    args = full_cmd
    process = subprocess.Popen(args)
    out, err = process.communicate(input)
    retcode = process.poll()
    if retcode:
        raise Error('ffmpeg', out, err)
Beispiel #16
0
    "b:v": "800k",
    "ac": 1,  # Mono
    # "b:a": "128k",
    "acodec": "aac",  # copy
}

preFileStream = ffmpeg.input(PRE_FILE, **preFile_input_args)
inputStream = ffmpeg.input(INPUT_FILE_PATH, **input_args)
a1 = preFileStream.audio
a2 = inputStream.audio

inputStream = ffmpeg.filter(inputStream, 'scale', size='1920x1080', force_original_aspect_ratio='decrease')
inputStream = ffmpeg.filter(inputStream, 'pad', '1920', '1080', '(ow-iw)/2', '(oh-ih)/2')
inputStream = ffmpeg.overlay(inputStream, OVERLAY_FILE)
inputStream = ffmpeg.filter(inputStream, "fade", type='in', start_time=0, duration=1)
# inputStream = ffmpeg.filter(inputStream, "fade", type='out', duration=1)

stream = ffmpeg.concat(preFileStream, a1, inputStream, a2, v=1, a=1)

OUTPUT_PATH = "../output/" + "[" + Utils.sToTimeFormat(TRIM_START, "%H:%M:%S.%f") + "-" + Utils.sToTimeFormat(TRIM_END,
                                                                                                              "%H:%M:%S.%f") + "]" + INPUT_FILE_NAME
if not os.path.exists("../output/"):
    os.makedirs("../output/")
# if os.path.exists(OUTPUT_PATH):
#  os.remove(OUTPUT_PATH)

stream = ffmpeg.output(stream, OUTPUT_PATH, **output_args)
stream = ffmpeg.overwrite_output(stream)
ffmpeg.run(stream)
print(ffmpeg.compile(stream))
def add_audio(in_file=None,
              out_file=None,
              combined_file=None,
              VERBOSE=False,
              DEBUG=False):
    """
    Combines audio data from source video file and annotated video
    into one file.

    :param in_file: str path to original video source file
    :param out_file: str path to annotated video output file.
    :param combined_file: str path file to new write
    :param VERBOSE: verbose flag

    TODO: an async progress meter would be nice.

    """
    if VERBOSE:
        print("\nProcessing audio...")

    analysis_start_time = time.time()

    # log_level = 'quiet'
    log_level = 'error'
    # log_level = 'info'
    # log_level = 'verbose'
    # log_level = 'debug'

    video_source_file = ffmpeg.input(out_file)
    audio_source_file = ffmpeg.input(in_file)
    video_component = video_source_file.video
    audio_component = audio_source_file.audio

    # Using a constant rate factor of 18 gives results almost indistinguishable
    # from the original opencv video. It also halves the file size.
    output = (
        ffmpeg.concat(video_component, audio_component, v=1, a=1).output(
            combined_file,
            pix_fmt='yuv420p',
            movflags='faststart',
            hls_time=10,
            hls_list_size=0,
            crf=18,
            format='mov',
            shortest=None,
        ).global_args('-loglevel', log_level).overwrite_output(
        )  # I'm confusing it, and it asks to overwrite otherwise??
    )

    if DEBUG:
        command_line = ' '.join(ffmpeg.compile(
            output))  # Just for debugging to see what it's sending.

        print("ffmpeg audio merge command line: {}".format(command_line))

    output.run()

    analysis_end_time = time.time()

    if VERBOSE:
        print("Processed audio in {:2.1f} seconds.\n".format(
            analysis_end_time - analysis_start_time))

    if os.path.exists(combined_file):
        try:
            os.remove(out_file)
        except Exception as error:
            sys.exit(
                "\n\nOops. Cannot remove intermediate video file!\n{}\n{}\n".
                format(out_file, error))
Beispiel #18
0
import ffmpeg
from pathlib import Path
import json

file = Path(r"C:\Users\Jimmy\PycharmProjects\ffmpeg\videos\big_buck_bunny_720p_1mb.mp4")
input_file = str(file)

probe = ffmpeg.probe(filename=input_file)
#print(json.dumps(probe, indent=2))

# Convert input file to stream object
input_stream = ffmpeg.input(filename=input_file)

# Produces the output stream object, but does not run it yet.
# out_put = ffmpeg.output(input_stream, "out_put_test.mp4", format="mp4", vcodec="libx264", acodec=[""])
out_put = ffmpeg.output(input_stream["0"], input_stream["1"], input_stream["1"], "out_put_test.mkv",
                        **{"c:v": "libx264"}, **{"c:a:0": "copy"}, **{"c:a:1": "aac"},
                        **{"b:a:1": "128k"}, ac=2)

# Adds -y
out_put = ffmpeg.overwrite_output(out_put)

# Set some global args, note args go to the whole command line on a stream.
# We could use the progress parameter here and get them web sockets going
out_put = out_put.global_args('-loglevel', 'info', "-strict", "-2")

print(json.dumps(ffmpeg.compile(out_put), indent=2))
ffmpeg.run(out_put)
Beispiel #19
0
    def ffmpeg_out(self,
                   current_layer: int,
                   *args,
                   override_nb_frames=False,
                   **kwargs):  # NOQA
        """output with ffmpeg
        This takes in all normal ffmpeg output args.

        This is complex because we have to deal with default args and multiple output styles

        :param current_layer: the current index of the operation
        :param total_layers: the number of total layers to offset progress
        """
        total_layers = kwargs.pop('total_layers', self.total_layers)
        self.logger.debug("ffmpeg_out - {}/{}".format(current_layer,
                                                      total_layers))
        if self.ffmpeg_path != 'ffmpeg':
            self.logger.debug("direct ffmpeg")
            assert (os.path.isfile(self.ffmpeg_path)), 'invalid ffmpeg path'

        kwargs['vcodec'] = kwargs.get('vcodec', self.vcodec)
        kwargs['threads'] = kwargs.get('threads', self.thread_alloc)
        if self.current_codec != kwargs['vcodec']:
            self.logger.debug("vcodec")
            if self.bit_rate is not None:
                kwargs['b'] = self.bit_rate
                kwargs['maxrate'] = self.bit_rate
                kwargs['bufsize'] = 2 * self.bit_rate
            kwargs['profile'] = 'high'
            kwargs['preset'] = 'slow'

        self.logger.debug("ffmpeg args - \n" + json.dumps(kwargs, indent=2))

        ffout = ffmpeg.output(*args, **kwargs).global_args(
            '-loglevel', self.verbosity, '-hide_banner').overwrite_output()
        if self.pipe_ffmpeg:
            ffmpeg.run(ffout, cmd=self.ffmpeg_path, overwrite_output=True)
        else:
            try:
                args = ffmpeg.compile(ffout,
                                      cmd=self.ffmpeg_path,
                                      overwrite_output=True)
                process = subprocess.Popen(args,
                                           stdout=subprocess.PIPE,
                                           stderr=subprocess.STDOUT,
                                           universal_newlines=True)

                for line in process.stdout:
                    if 'frame' in line and 'speed' in line:
                        groups = re.search(
                            r'frame=\s*([0-9]*).*speed=\s*([0-9.]*)',
                            line)  # noqa W605
                        frame_percent = int(groups.group(1)) / (
                            self.total_time * self.frame_rate)
                        if not override_nb_frames and self.nb_frames is not None and self.nb_frames > 0:
                            frame_percent = int(
                                groups.group(1)) / self.nb_frames
                        float_speed = 0.0
                        try:
                            float_speed = float(groups.group(2))
                        except ValueError:
                            pass

                        real_percent = frame_percent / total_layers + current_layer / total_layers
                        if self.readable:
                            sys.stdout.write("\033[K")  # clear previous line
                            self.logger.info(
                                '\r({}/{}) action progress is {:.3%} at a speed of {:}x'
                                .format(current_layer, total_layers,
                                        frame_percent, float_speed))
                        else:
                            self.logger.info('{:.3%}|{:.3f}x'.format(
                                real_percent, float_speed))
                        self.logger.handlers[1].flush()
            except Exception as e:
                self.logger.exception(e)
                raise
Beispiel #20
0
    def __init__(
        self,
        input_path: pathlib.Path,
        frame_rate: float,
        output_path: pathlib.Path,
        output_width: int,
        output_height: int,
        total_frames: int,
        processed_frames: ListProxy,
        processed: Synchronized,
        pause: Synchronized,
        copy_audio: bool = True,
        copy_subtitle: bool = True,
        copy_data: bool = False,
        copy_attachments: bool = False,
    ) -> None:
        threading.Thread.__init__(self)
        self.running = False
        self.input_path = input_path
        self.output_path = output_path
        self.total_frames = total_frames
        self.processed_frames = processed_frames
        self.processed = processed
        self.pause = pause

        # stores exceptions if the thread exits with errors
        self.exception = None

        # create FFmpeg input for the original input video
        self.original = ffmpeg.input(input_path)

        # define frames as input
        frames = ffmpeg.input(
            "pipe:0",
            format="rawvideo",
            pix_fmt="rgb24",
            vsync="cfr",
            s=f"{output_width}x{output_height}",
            r=frame_rate,
        )

        # copy additional streams from original file
        # https://ffmpeg.org/ffmpeg.html#Stream-specifiers-1
        additional_streams = [
            # self.original["1:v?"],
            self.original["a?"] if copy_audio is True else None,
            self.original["s?"] if copy_subtitle is True else None,
            self.original["d?"] if copy_data is True else None,
            self.original["t?"] if copy_attachments is True else None,
        ]

        # run FFmpeg and produce final output
        self.encoder = subprocess.Popen(
            ffmpeg.compile(
                ffmpeg.output(
                    frames,
                    *[s for s in additional_streams if s is not None],
                    str(self.output_path),
                    vcodec="libx264",
                    vsync="cfr",
                    pix_fmt="yuv420p",
                    crf=17,
                    preset="veryslow",
                    # acodec="libfdk_aac",
                    # cutoff=20000,
                    r=frame_rate,
                    map_metadata=1,
                    metadata="comment=Processed with Video2X",
                )
                .global_args("-hide_banner")
                .global_args("-nostats")
                .global_args(
                    "-loglevel",
                    LOGURU_FFMPEG_LOGLEVELS.get(
                        os.environ.get("LOGURU_LEVEL", "INFO").lower()
                    ),
                ),
                overwrite_output=True,
            ),
            env={"AV_LOG_FORCE_COLOR": "TRUE"},
            stdin=subprocess.PIPE,
            stderr=subprocess.PIPE,
        )

        # start the PIPE printer to start printing FFmpeg logs
        self.pipe_printer = PipePrinter(self.encoder.stderr)
        self.pipe_printer.start()
Beispiel #21
0
def ffmpeg_process(file_, ffmpegPath, ffprobePath, basePath):
    log.info("starting processing: {}".format(file_))
    filename, ext = os.path.splitext(file_)
    outputFile = filename + "_post" + ext
    log.info("output path: {}".format(outputFile))

    # ffprobe to get media info
    jProbe = ffmpeg.probe(file_, cmd=ffprobePath)["streams"]  # json load
    vProbe = [
        jProbe[indx] for indx, stream in enumerate(jProbe)
        if stream["codec_type"] == "video"
    ][0]
    streamInfo = {
        "width": int(vProbe["width"]),
        "height": int(vProbe["height"]),
        "start": float(vProbe["start_time"]),
        "duration": float(vProbe["duration"]),
        "frames": int(vProbe["nb_frames"]),
        "fps": int(vProbe["nb_frames"]) / float(vProbe["duration"])
    }
    log.debug("streamInfo: {}".format(streamInfo))

    # random choices
    CODE_DUR = 30
    rCode = str(random.randint(0, 9999)).zfill(4)  # zero pad to 4 places
    colors = [
        "red", "orange", "yellow", "green", "blue", "purple", "black", "white"
    ]
    rColor = random.choice(colors)
    rPer = random.randrange(
        5, 75) / 100  # percentage through the video to start code
    rStFrame = math.floor(streamInfo["frames"] * rPer)
    rStTime = math.floor(rStFrame * 1 / streamInfo["fps"])
    log.info("Random choices: color: {}, code: {}, stTime {}".format(
        rColor, rCode, rStTime))

    input = ffmpeg.input(file_)

    audioOrig = input.audio
    soundBite = ffmpeg.input(
        os.path.join(basePath, "resources", "audio", "beep.mp3"))
    soundBite = soundBite.filter("adelay",
                                 rStTime * 1000).filter("apad")  # ms to s
    audio = ffmpeg.filter([audioOrig, soundBite], "amerge")

    video = input.video
    video = ffmpeg.drawtext(video,
                            text=rCode,
                            x=40,
                            y=40,
                            fontfile=os.path.join(basePath, "resources",
                                                  "fonts",
                                                  "OpenSans-Regular.ttf"),
                            fontsize=80,
                            fontcolor=rColor,
                            box=True,
                            boxcolor="gray",
                            boxborderw=10,
                            enable="".join([
                                "between", "(t,",
                                str(rStTime), ",",
                                str(rStTime + CODE_DUR), ")"
                            ]))
    video = ffmpeg.drawtext(video,
                            text="LegalTechnicality.com",
                            x=40,
                            y="h-th-40",
                            fontfile=os.path.join(basePath, "resources",
                                                  "fonts",
                                                  "OpenSans-Regular.ttf"),
                            fontsize=60,
                            alpha=0.75,
                            fontcolor="white")

    output = ffmpeg.output(video, audio, outputFile)  # **{"ac": 1}
    fullCmd = ffmpeg.compile(output, cmd=ffmpegPath, overwrite_output=True)
    log.debug("ffmpeg command to be called: {}".format(fullCmd))

    try:
        stdout, stderr = ffmpeg.run(output,
                                    cmd=ffmpegPath,
                                    quiet=False,
                                    capture_stdout=False,
                                    capture_stderr=False,
                                    overwrite_output=True)
        # strings are falsy; False if empty
        if stdout:
            log.debug("ffmpeg output: {}".format(stdout.decode("utf-8")))
        if stderr:  # actually a false error -- just the ffmpeg output
            log.debug("ffmpeg output: {}".format(stderr.decode("utf-8")))
        log.info("sucessfully processed file")
    except ffmpeg.Error as e:
        log.exception("failed to process file")
        log.exception(e.stderr)
Beispiel #22
0
def ffmpegConcat(orgs):
    import ffmpeg
    import random
    import json
    from datetime import datetime
    max_nb_layers = 20
    hard_limit = 30000
    dur_limit = 600
    tags_not = {
        "Couple", "Electric", 'Threesome', 'Public transport', 'Male stranger'
    }
    tags_must = {"Alone"}
    tags_may = {"Powerful", "Finger"}

    contactList = []
    amixList = []
    length = 0

    selected = dict()
    selectedOrgs = []
    for _ in range(hard_limit):
        id = random.randint(0, len(orgs) - 1)
        # id = random.randint(0, 5)
        org = orgs[id]
        tags = set(org.get("tags"))
        if tags_not & tags:
            # print(tags_not & tags)
            continue
        if tags_must - tags:
            # print(tags_must - tags)
            continue
        if not tags_may & tags:
            # print(tags_may & tags)
            continue

        stream = selected.get(id, None)
        if not stream:
            stream = ffmpeg.input(str(getAudioFilePath(org)))
            stream = ffmpeg.filter(stream, 'loudnorm')

        streams = ffmpeg.filter_multi_output(stream, 'asplit')
        selected[id] = streams.stream(0)
        stream = streams.stream(1)
        contactList.append(stream)

        audioLength = float(org.get("duration", "30"))
        length += audioLength
        if length >= dur_limit:
            contactStream = ffmpeg.concat(*contactList, v=0, a=1)
            amixList.append(contactStream)
            contactList = []
            length = 0

        selectedOrgs.append(org)
        if len(amixList) >= max_nb_layers:
            break
    else:
        if contactList:
            contactStream = ffmpeg.concat(*contactList, v=0, a=1)
            amixList.append(contactStream)

    fullStream = ffmpeg.filter(amixList,
                               'amix',
                               inputs=len(amixList),
                               duration='longest')
    fullStream = ffmpeg.filter(fullStream, 'atrim', duration=dur_limit)

    outputPath = basePath.joinpath("mixed").joinpath("mix-{:d}.m4a".format(
        int(datetime.now().timestamp())))
    metadata = {
        'length': dur_limit,
        'nb': len(selectedOrgs),
        'nb_dist': len(selected),
        'mix_layers': len(amixList),
        'tags_not': list(tags_not),
        'tags_must': list(tags_must),
        'tags_may': list(tags_may),
        'tags': list(getTags(selectedOrgs))
    }
    metadataJson = json.dumps(metadata, ensure_ascii=False, sort_keys=False)
    outputParam = {
        'metadata': 'comment="{}"'.format(metadataJson),
        'acodec': 'aac'
    }

    fullStream = fullStream.output(str(outputPath), **outputParam)
    cmd = ffmpeg.compile(fullStream)
    print(cmd)
    ffmpeg.view(fullStream, filename=str(outputPath) + ".png")
    ffmpeg.run(fullStream, overwrite_output=True)
    printTags(selectedOrgs)
    pass
Beispiel #23
0
def get_r128_loudness(audio_filepaths,
                      *,
                      calc_peak=True,
                      enable_ffmpeg_threading=True,
                      ffmpeg_path=None,
                      start_evt=None):
    """ Get R128 loudness loudness level and sample peak. """
    if start_evt is not None:
        start_evt.wait()

    logger().info("Analyzing loudness of file%s %s..." %
                  ("s" if (len(audio_filepaths) > 1) else "", ", ".join(
                      repr(audio_filepath)
                      for audio_filepath in audio_filepaths)))

    # build command line
    ffmpeg_inputs = []
    if not enable_ffmpeg_threading:
        additional_ffmpeg_args = {"threads": 1}  # single decoding thread
    else:
        additional_ffmpeg_args = dict()
    for audio_filepath in audio_filepaths:
        ffmpeg_input = ffmpeg.input(audio_filepath,
                                    **additional_ffmpeg_args).audio
        ffmpeg_inputs.append(ffmpeg_input)

    output_streams = []
    ffmpeg_r128_streams = []
    for ffmpeg_input in ffmpeg_inputs:
        if calc_peak:
            split_streams = ffmpeg_input.filter_multi_output("asplit",
                                                             outputs=2)
            ffmpeg_rg_stream, ffmpeg_r128_stream = split_streams[
                0], split_streams[1]
            ffmpeg_rg_stream = ffmpeg_rg_stream.filter(
                "aformat", sample_fmts="s16", channel_layouts="stereo")
            ffmpeg_rg_stream = ffmpeg_rg_stream.filter("replaygain")
            output_streams.append(ffmpeg_rg_stream)
        else:
            ffmpeg_r128_stream = ffmpeg_input
        ffmpeg_r128_stream = ffmpeg_r128_stream.filter(
            "aformat",
            sample_fmts="s16",
            sample_rates="48000",
            channel_layouts="stereo")
        ffmpeg_r128_stream = ffmpeg_r128_stream.filter(
            "afifo")  # needed for FFmpeg < 4.1
        ffmpeg_r128_streams.append(ffmpeg_r128_stream)

    if len(audio_filepaths) > 1:
        ffmpeg_r128_merged = ffmpeg.concat(*ffmpeg_r128_streams,
                                           n=len(ffmpeg_r128_streams),
                                           v=0,
                                           a=1)
    else:
        ffmpeg_r128_merged = ffmpeg_r128_streams[0]
    ffmpeg_r128_merged = ffmpeg_r128_merged.filter("ebur128",
                                                   framelog="verbose")
    output_streams.append(ffmpeg_r128_merged)

    if (get_ffmpeg_lib_versions()["libavfilter"] >=
            0x06526400) and (not enable_ffmpeg_threading):
        additional_ffmpeg_args = {
            "filter_complex_threads": 1
        }  # single filter thread
    else:
        additional_ffmpeg_args = dict()
    cmd = ffmpeg.compile(ffmpeg.output(*output_streams,
                                       os.devnull,
                                       **additional_ffmpeg_args,
                                       f="null").global_args(
                                           "-hide_banner", "-nostats"),
                         cmd=ffmpeg_path or "ffmpeg")

    # run
    logger().debug(cmd_to_string(cmd))
    output = subprocess.run(cmd,
                            check=True,
                            stdin=subprocess.DEVNULL,
                            stderr=subprocess.PIPE).stderr
    output = output.decode("utf-8", errors="replace").splitlines()

    if calc_peak:
        # parse replaygain filter output
        sample_peaks = []
        for line in reversed(output):
            if line.startswith("[Parsed_replaygain_") and ("] track_peak = "
                                                           in line):
                sample_peaks.append(float(line.rsplit("=", 1)[1]))
                if len(sample_peaks) == len(audio_filepaths):
                    break
        sample_peak = max(sample_peaks)
    else:
        sample_peak = None

    # parse r128 filter output
    for i in reversed(range(len(output))):
        line = output[i]
        if line.startswith("[Parsed_ebur128_") and line.endswith("Summary:"):
            break
    output = filter(lambda x: x and not x.startswith("[Parsed_replaygain_"),
                    map(str.strip, output[i:]))
    r128_stats = dict(
        tuple(map(str.strip, line.split(":", 1))) for line in output
        if not line.endswith(":"))
    r128_stats = {k: float(v.split(" ", 1)[0]) for k, v in r128_stats.items()}

    return r128_stats["I"], sample_peak
def trim(request):
    if request.path == '/favicon.ico':
        abort(404)  # Ignore browser requests for favicon

    request.path = request.path.strip('/').split('/')
    _source_params = request.path[1]
    _source_file = request.path[2]
    _time = int(time.time())
    _params = dict()
    _params['operation'] = request.path[0]
    _params['source_file'] = request.path[2]

    # Extract parameters from URL field
    for param in _source_params.split(','):
        try:
            _split = param.split(':')
            _key = _split[0]
            _value = _split[1] if len(_split) > 1 else None

            if _key in _allowed_params:
                _params[_key] = _value
            else:
                abort(400)
        except:
            abort(400)

    ## Generate hash
    _hash = generate_hash("{}:{}".format(dumps(_params, sort_keys=True),
                                         _source_file))

    ## Check for existing entry in datastore
    #_entity = read_in_datastore(_hash)
    #if _entity:
    #	# todo: 301/302/307 redirect
    #	print('Already found.')

    ## Generate signed URL
    _params['signed_url'] = request_signed_url(SOURCE_BUCKET_NAME,
                                               _source_file)

    if not _params['signed_url']:
        return abort(404)

    ## Create args for ffmpeg.input
    _input_kwargs = ffmpeg_input_args(**_params)
    _output_kwargs = ffmpeg_output_args(**_params)

    job = ffmpeg.input(_params['signed_url'], **_input_kwargs)
    job = ffmpeg.output(
        job, '{}/{}_{}.{}'.format(
            LOCAL_DESTINATION_PATH, _time, _hash,
            'mp4' if _params['operation'] == 'trim' else 'jpg'),
        **_output_kwargs)

    try:
        out, err = ffmpeg.run(job,
                              cmd=FFMPEG_BINARY_PATH,
                              capture_stderr=True,
                              capture_stdout=True)

        #logging.info(out.decode('utf-8').replace('\n', ' '))
        #logging.error(err.decode('utf-8').replace('\n', ' '))

    except ffmpeg.Error as e:
        abort(500)
        logging.error(e.stderr.decode().replace('\n', ' '))
        logging.error(e.stderr)
        logging.error(e)

    _info = {
        'params': _source_params,
        'js_params': _params,
        'ffmpeg_input_args': _input_kwargs,
        'ffmpeg_output_args': _output_kwargs,
        'ffmpeg_command': " ".join(ffmpeg.compile(job)),
        'source_file': _source_file,
        'hash': _hash
    }

    logging.info(_info)

    # todo: wrap in try except
    response = make_response(
        send_file('{}/{}_{}.{}'.format(
            LOCAL_DESTINATION_PATH, _time, _hash,
            'mp4' if _params['operation'] == 'trim' else 'jpg')))
    response.headers['X-Query-Hash'] = _hash

    insert_to_datastore(
        _hash, '{}/{}_{}.{}'.format(
            LOCAL_DESTINATION_PATH, _time, _hash,
            'mp4' if _params['operation'] == 'trim' else 'jpg'))

    return response
Beispiel #25
0
def get_r128_loudness(
    audio_filepaths: Sequence[str],
    *,
    calc_peak: bool = True,
    enable_ffmpeg_threading: bool = True,
    ffmpeg_path: Optional[str] = None,
    start_evt: Optional[threading.Event] = None,
) -> Tuple[float, Optional[float]]:
    """Get R128 loudness loudness level and sample peak."""
    if start_evt is not None:
        start_evt.wait()

    logger().info("Analyzing loudness of file%s %s..." % (
        "s" if (len(audio_filepaths) > 1) else "",
        ", ".join(repr(audio_filepath) for audio_filepath in audio_filepaths),
    ))

    # build command line
    ffmpeg_inputs = []
    if not enable_ffmpeg_threading:
        additional_ffmpeg_args = {"threads": 1}  # single decoding thread
    else:
        additional_ffmpeg_args = dict()
    for audio_filepath in audio_filepaths:
        ffmpeg_input = ffmpeg.input(audio_filepath,
                                    **additional_ffmpeg_args).audio
        ffmpeg_inputs.append(ffmpeg_input)

    output_streams = []
    ffmpeg_r128_streams = []
    for ffmpeg_input in ffmpeg_inputs:
        if calc_peak:
            split_streams = ffmpeg_input.filter_multi_output("asplit",
                                                             outputs=2)
            ffmpeg_rg_stream, ffmpeg_r128_stream = split_streams[
                0], split_streams[1]
            ffmpeg_rg_stream = ffmpeg_rg_stream.filter(
                "aformat", sample_fmts="s16", channel_layouts="stereo")
            ffmpeg_rg_stream = ffmpeg_rg_stream.filter("replaygain")
            output_streams.append(ffmpeg_rg_stream)
        else:
            ffmpeg_r128_stream = ffmpeg_input
        ffmpeg_r128_stream = ffmpeg_r128_stream.filter(
            "aformat",
            sample_fmts="s16",
            sample_rates="48000",
            channel_layouts="stereo")
        ffmpeg_r128_stream = ffmpeg_r128_stream.filter(
            "afifo")  # needed for FFmpeg < 4.1
        ffmpeg_r128_streams.append(ffmpeg_r128_stream)

    if len(audio_filepaths) > 1:
        ffmpeg_r128_merged = ffmpeg.concat(*ffmpeg_r128_streams,
                                           n=len(ffmpeg_r128_streams),
                                           v=0,
                                           a=1)
    else:
        ffmpeg_r128_merged = ffmpeg_r128_streams[0]
    ffmpeg_r128_merged = ffmpeg_r128_merged.filter("ebur128",
                                                   framelog="verbose")
    output_streams.append(ffmpeg_r128_merged)

    if (get_ffmpeg_lib_versions()["libavfilter"] >=
            0x06526400) and (not enable_ffmpeg_threading):
        additional_ffmpeg_args = {
            "filter_complex_threads": 1
        }  # single filter thread
    else:
        additional_ffmpeg_args = dict()
    cmd = ffmpeg.compile(
        ffmpeg.output(*output_streams,
                      os.devnull,
                      **additional_ffmpeg_args,
                      f="null").global_args("-hide_banner", "-nostats"),
        cmd=ffmpeg_path or "ffmpeg",
    )

    # workaround https://github.com/kkroening/ffmpeg-python/issues/161
    opt_index = cmd.index("-filter_complex")
    with tempfile.TemporaryDirectory(prefix="r128gain_") as tmp_dir:
        tmp_script_filepath = os.path.join(tmp_dir, "ffmpeg_filters")
        with open(tmp_script_filepath, "wt") as f:
            f.write(cmd[opt_index + 1])
        cmd[opt_index] = "-filter_complex_script"
        cmd[opt_index + 1] = tmp_script_filepath

        # run
        logger().debug(cmd_to_string(cmd))
        output = subprocess.run(cmd,
                                check=True,
                                stdin=subprocess.DEVNULL,
                                stderr=subprocess.PIPE).stderr
        output_lines = output.decode("utf-8", errors="replace").splitlines()

    if calc_peak:
        # parse replaygain filter output
        sample_peaks = []
        for line in reversed(output_lines):
            if line.startswith("[Parsed_replaygain_") and ("] track_peak = "
                                                           in line):
                sample_peaks.append(float(line.rsplit("=", 1)[1]))
                if len(sample_peaks) == len(audio_filepaths):
                    break
        sample_peak: Optional[float] = max(sample_peaks)
    else:
        sample_peak = None

    # parse r128 filter output
    for i in reversed(range(len(output_lines))):
        line = output_lines[i]
        if line.startswith("[Parsed_ebur128_") and line.endswith("Summary:"):
            break
    output_lines_r128 = filter(
        lambda x: x and not x.startswith("[Parsed_replaygain_"),
        map(str.strip, output_lines[i:]))
    r128_stats_raw: Dict[str, str] = dict(
        tuple(map(str.strip, line.split(":", 1)))  # type: ignore
        for line in output_lines_r128 if not line.endswith(":"))
    r128_stats: Dict[str, float] = {
        k: float(v.split(" ", 1)[0])
        for k, v in r128_stats_raw.items()
    }

    return r128_stats["I"], sample_peak
Beispiel #26
0
    def start_recording(self):
        """
        Start recording the stream defined on self.stream_uri
        :return: boolean if the recording started sucessfully
        """

        # if we are dealing with a USB camera or RTSP stream we
        # treat them differently, for example remove the socket TCP I/O timeout (stimeout)
        parsed_uri = urlparse(self.stream_uri)
        if parsed_uri.scheme == "rtsp":
            stream_input = ffmpeg.input(
                self.stream_uri,
                nostdin=None,
                use_wallclock_as_timestamps=1,
                stimeout=self._def_stimeout,
                fflags="+genpts",
                rtsp_transport='tcp')  # stimeout in microsecondss
        else:
            stream_input = ffmpeg.input(self.stream_uri)

        # store the files in segments to prevent corruption
        segment_fpath = self.prepare_filepath_for_segment(
            self.output_filepath, self._def_segment_fname_size)

        # ffmpeg -use_wallclock_as_timestamps 1 -fflags +genpts -rtsp_transport tcp -stimeout 3000000
        # -i rtsp://admin:[email protected]:554/stream0 -f segment -b:v 900k -an -flags +global_header -map 0
        # -map_metadata -1 -movflags +frag_keyframe+separate_moof+omit_tfhd_offset+empty_moov -reset_timestamps 1
        # -segment_format matroska
        # -segment_list /tmp/stored_streams/2.stream_192_168_3_22_554.2019-08-18.14.02.53_video_list.txt
        # -segment_list_type ffconcat -segment_time 20 -strict 2 -vcodec copy -use_wallclock_as_timestamps 1
        # -fflags +genpts /tmp/stored_streams/2.stream_192_168_3_22_554.2019-08-18.14.02.53-%03d.mkv -y

        output_arguments = [
            ("strict", 2),
            ("f", "segment"),
            ("map", 0),
            ("segment_time", self._def_segment_time),
            ("segment_format", self._def_segment_format),
            ("segment_list", self.segment_filelist),
            ("segment_list_type", "ffconcat"),
            ("vcodec", self._def_vcodec),
            ("video_bitrate", self._def_bitrate),
            ("flags", "+global_header"),
            ("reset_timestamps", 1),
            ("map_metadata", -1),
            ("use_wallclock_as_timestamps", 1),
            ("fflags", "+genpts"),
            ("movflags",
             "+frag_keyframe+separate_moof+omit_tfhd_offset+empty_moov"),
        ]

        # if there is no audio codec then use the an
        # flag to remove audio from the recorded stream
        if self._def_acodec != "":
            output_arguments.append(("acodec", self._def_acodec))
        else:
            output_arguments.append(("an", None))

        ffmpeg_output_streams = [
            ffmpeg.output(stream_input, segment_fpath,
                          **OrderedDict(output_arguments))
        ]

        output_streams = ffmpeg.merge_outputs(*ffmpeg_output_streams)
        output_streams = ffmpeg.overwrite_output(output_streams)

        debug_command = ffmpeg.compile(output_streams)
        print("ffmpeg command: {}".format(' '.join(debug_command)))

        self.start_time = time.time()
        self.proc = (
            # ALERT: https://stackoverflow.com/questions/16523746/ffmpeg-hangs-when-run-in-background
            # clean the stderr / stdout regularly to prevent this process for freezing
            ffmpeg.run_async(output_streams,
                             pipe_stdout=True,
                             pipe_stderr=True,
                             overwrite_output=True))

        start_timeout = time.time()
        is_reached_size = False
        while self.proc.poll() is None and time.time(
        ) - start_timeout < self._def_timeout_secs and not is_reached_size:
            try:
                if os.path.getsize(self.get_last_segment_output_filepath()
                                   ) > self._def_min_video_size_bytes:
                    is_reached_size = True
            except OSError as e:
                pass
            time.sleep(0.1)

        if self.proc.poll() is None:
            return True
        else:
            self.start_time = 0
            self.out, self.err = self.proc.communicate()
            return False
Beispiel #27
0
            base_rgb = np.array(command["color-change"]["from-color"])
            to_bgr = np.flip(np.array(command["color-change"]["to-color"]))
            for y in range(lu[1], rd[1] + 1):
                for x in range(lu[0], rd[0] + 1):
                    if (frame[y, x] == base_rgb).all():  # 指定の色と一致してたら色を差し替える
                        frame[y, x] = to_bgr  # rgbじゃなくてbgrで格納されてるので
        if "alpha-blend" in command:
            alpha = command["alpha-blend"]["alpha"]
            to_bgr = np.flip(np.array(command["alpha-blend"]["to-color"]))
            frame = frame * alpha + to_bgr * (1 - alpha)
            frame = frame.astype("uint8")
        """

        frame = cv2.cvtColor(frame, cv2.COLOR_RGBA2RGB)
        out.write(frame)

    out.release()

    output_movie_file = str(tmp_dir_path / setting.output_file)
    movie_input = ffmpeg.input(temp_file)
    audio_input = ffmpeg.input(setting.audio_file)
    output = ffmpeg.output(movie_input, audio_input, output_movie_file)
    print(ffmpeg.compile(output))
    ffmpeg.run(output)

    yyyymmddhhmmss = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
    result_dir = title_dir / f"archive/{yyyymmddhhmmss}/"
    shutil.copytree(tmp_dir_path, result_dir)

shutil.copytree(materials_dir, result_dir / "materials")
Beispiel #28
0
probe = ffmpeg.probe(input_file)
# print(json.dumps(probe, indent=2))

# for stream in probe['streams']:
#     print(stream)

# convert the input file to a stream object
input_stream = ffmpeg.input(filename=input_file)

# Produces the output stream object, but doesn't run it yet.
out_put = ffmpeg.output(input_stream["0"],
                        input_stream["1"],
                        input_stream["1"],
                        "done/out_put_test.mkv",
                        **{"c:v": "libx264"},
                        **{"c:a:0": "copy"},
                        **{"c:a:1": "aac"},
                        **{"b:a:1": "128k"},
                        ac=2)

# Adds -y to the ffmpeg command
out_put = ffmpeg.overwrite_output(out_put)

# Set some global args, note args go to the whole command line on a stream.
# We could use the progress parameter here and get them web sockets going
out_put = out_put.global_args('-loglevel', 'info', "-strict", "-2")

print(json.dumps(ffmpeg.compile(out_put), indent=2))
print(" ".join(ffmpeg.compile(out_put)))
# ffmpeg.run(out_put)