vse_toolbox/auto_splitter.py

105 lines
2.7 KiB
Python
Raw Normal View History

import os
2024-05-24 09:44:19 +02:00
import re
import subprocess
import bpy
2024-05-24 09:44:19 +02:00
from vse_toolbox import bl_utils
2024-05-24 09:44:19 +02:00
def launch_split(movie_strip, threshold, frame_start=None, frame_end=None):
"""Launch ffmpeg command to detect changing frames from a movie strip.
2024-05-24 09:44:19 +02:00
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.
2024-05-24 09:44:19 +02:00
Returns:
str: ffmpeg command log.
"""
2024-05-24 09:44:19 +02:00
path = bl_utils.abspath(movie_strip.filepath)
fps = bpy.context.scene.render.fps
2024-05-24 09:44:19 +02:00
if frame_start is None:
2024-05-28 14:49:28 +02:00
frame_start = 0
if frame_end is None:
2024-05-28 14:49:28 +02:00
frame_end = movie_strip.frame_duration
2024-05-24 09:44:19 +02:00
2024-05-28 14:49:28 +02:00
frame_start = frame_start - movie_strip.frame_start
#frame_start += movie_strip.frame_offset_start
#frame_end -= movie_strip.frame_offset_end
2024-05-24 09:44:19 +02:00
# Launch ffmpeg command to split
ffmpeg_cmd = get_command(str(path), threshold, frame_start, frame_end, fps)
2024-05-24 09:44:19 +02:00
print(ffmpeg_cmd)
process = subprocess.Popen(
ffmpeg_cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True)
2024-05-24 09:44:19 +02:00
return process
2024-05-24 09:44:19 +02:00
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