Last active
July 12, 2020 02:58
-
-
Save OrangeChannel/b9666b3650a3448589069d25dd6a394c to your computer and use it in GitHub Desktop.
VSEdit Bookmark generator. Useful for scenefiltering https://guide.encode.moe/encoding/scenefiltering.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""VSEdit bookmark generator.""" | |
__all__ = ['generate', 'convert'] | |
__author__ = 'Dave <orangechannel@pm.me>' | |
__date__ = '30 November 2019' | |
import vapoursynth as vs | |
import re | |
core = vs.core | |
def generate(clip: vs.VideoNode, script_name: str): | |
"""Generates keyframe VSEdit bookmark file. | |
some of this stolen from kageru's generate_keyframes | |
(https://github.com/Irrational-Encoding-Wizardry/kagefunc) | |
:param clip: input clip | |
:bit depth: ANY | |
:color family: ANY | |
:float precision: ANY | |
:sample type: ANY | |
:subsampling: ANY | |
:param script_name: name of VSEdit script with no extension | |
i.e. editing 'script.vpy' --> 'script' | |
""" | |
script_name += '.vpy.bookmarks' | |
# speed up the analysis by resizing first | |
clip = core.resize.Bilinear(clip, 640, 360) | |
clip = core.wwxd.WWXD(clip) | |
kf = '0' | |
for i in range(1, clip.num_frames): | |
if clip.get_frame(i).props.Scenechange == 1: | |
kf += ", %d" % i | |
text_file = open(script_name, "w") | |
text_file.write(kf) | |
text_file.close() | |
def convert(file_path: str, script_name: str): | |
"""Converts standard keyframe file to VSEdit bookmark format. | |
Accepts WWXD qp-files and (SC)XviD keyframe files | |
:param file_path: OS absolute '/path/to/keyframes.txt' | |
:param script_name: name of VSEdit script with no extension. | |
""" | |
script_name += '.vpy.bookmarks' | |
lines = [line.rstrip('\n') for line in open(file_path, 'r')] | |
lines = list(filter(None, lines)) | |
if 'WWXD' in lines[0]: | |
kf = '0' | |
for i in range(2, len(lines)): | |
match = re.search(r'\d+', lines[i]) | |
match = match[0] if match else None | |
if match: | |
kf += (', ' + match) | |
elif 'XviD' in lines[0]: | |
count = 0 | |
kf = '' | |
for i in range(len(lines)): | |
if lines[i][0] == 'i': | |
kf += (str(count) + ', ') | |
count += 1 | |
elif lines[i][0] == 'p' or lines[i][0] == 'b': | |
count += 1 | |
kf = kf[:-2] | |
else: | |
raise IOError('convert: keyframe file format could not be determined') | |
text_file = open(script_name, 'w') | |
text_file.write(kf) | |
text_file.close() | |
# WIP functions --------------------------------------------------------------- | |
def min_max(clip: vs.VideoNode): | |
clip = core.resize.Bilinear(clip, 640, 360) | |
clip = core.wwxd.WWXD(clip) | |
keys = [] | |
for i in range(1, clip.num_frames): | |
if clip.get_frame(i).props.Scenechange == 1: | |
keys.append(int(i)) | |
diffs = [] | |
for i in range(len(keys) - 1): | |
diffs.append(keys[i + 1] - keys[i]) | |
raise ValueError('minimum is {} fr, maximum is {} fr' | |
.format(min(diffs), max(diffs))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment