import os import re import subprocess import bpy from vse_toolbox import bl_utils def launch_split(movie_strip, threshold, frame_start=None, frame_end=None): """Launch ffmpeg command to detect changing frames from a movie strip. Args: movie_strip (bpy.types.Sequence): blender sequence strip to detect changes. threshold (float): value of the detection factor (from 0 to 1). frame_start (int, optional): first frame to detect. Defaults to None. frame_end (int, optional): last frame to detect. Defaults to None. Returns: str: ffmpeg command log. """ path = bl_utils.abspath(movie_strip.filepath) fps = bpy.context.scene.render.fps if frame_start is None: frame_start = 0 if frame_end is None: frame_end = movie_strip.frame_duration frame_start = frame_start - movie_strip.frame_start #frame_start += movie_strip.frame_offset_start #frame_end -= movie_strip.frame_offset_end # Launch ffmpeg command to split ffmpeg_cmd = get_command(str(path), threshold, frame_start, frame_end, fps) print(ffmpeg_cmd) process = subprocess.Popen( ffmpeg_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) return process def get_command(path, threshold, frame_start, frame_end, fps): """Generate the ffmpeg command which detect change from a movie. Args: path (_type_): path to detect changes. threshold (_type_): value of the detection factor (from 0 to 1). frame_start (_type_): first frame to detect. frame_end (_type_): last frame to detect. fps (_type_): framerate of the movie. Returns: list: ffmpeg command as list for subprocess module. """ start_time = frame_start/fps end_time = frame_end/fps return [ 'ffmpeg', '-i', str(path), '-vf', f"trim=start={start_time}:end={end_time}, select='gt(scene, {threshold})',showinfo", '-f', 'null', '-' ] def get_split_time(log, as_frame=True, fps=None): """Parse ffmpeg command lines to detect the timecode Args: log (str): log to parse. as_frame (bool, optional): if wanted the timecode as frame number. Defaults to True. fps (_type_, optional): framerate of the movie (mandatory if as_frame used). Defaults to None. Returns: _type_: _description_ """ timecodes = re.findall(r'pts_time:([\d.]+)', log) if not timecodes: return timecode = timecodes[0] if as_frame: # convert timecode to frame number return round(float(timecode) * fps) return timecode