Skip to content

Instantly share code, notes, and snippets.

@OrangeChannel
Last active July 12, 2020 02:58
Show Gist options
  • Save OrangeChannel/b9666b3650a3448589069d25dd6a394c to your computer and use it in GitHub Desktop.
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
"""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