vapoursynth: Add "ask" mode for get_keyframe

This commit is contained in:
arch1t3cht 2023-06-11 01:22:06 +02:00
parent d06a31968d
commit 1f6684823c
3 changed files with 25 additions and 12 deletions

View File

@ -28,6 +28,8 @@ other data.
import os import os
import os.path import os.path
import re import re
from enum import Enum
from tkinter.messagebox import askyesno
from collections import deque from collections import deque
from typing import Any, Dict, List, Tuple from typing import Any, Dict, List, Tuple
@ -216,25 +218,36 @@ def save_keyframes(filename: str, keyframes: List[int]):
f.write("".join(f"{n}\n" for n in keyframes)) f.write("".join(f"{n}\n" for n in keyframes))
def try_get_keyframes(filename: str, default: str | List[int]) -> str | List[int]: class GenKeyframesMode(Enum):
""" NEVER = 0
Checks if a keyframes file for the given filename is present and, if so, ALWAYS = 1
returns it. Otherwise, returns the given list of keyframes. ASK = 2
"""
kffilename = make_keyframes_filename(filename)
return kffilename if os.path.exists(kffilename) else default
def get_keyframes(filename: str, clip: vs.VideoNode, **kwargs: Any) -> str: def get_keyframes(filename: str, clip: vs.VideoNode, fallback: str | List[int],
generate: GenKeyframesMode = GenKeyframesMode.ASK, **kwargs: Any) -> str | List[int]:
""" """
When not already present, creates a keyframe file for the given clip next Looks for a keyframes file for the given filename.
If no file was found, this function can generate a keyframe file for the given clip next
to the given filename using WWXD or Scxvid (see the make_keyframes docstring). to the given filename using WWXD or Scxvid (see the make_keyframes docstring).
Whether or not keyframes are generated depends on the `generate` argument.
Depending on the `generate` argument, the function will
- always generate keyframes when no file was found
- never generate keyframes when no file was found
(and return the fallback keyframes instead)
- show a dialog to ask the user whether keyframes should be
generated or not
Additional keyword arguments are passed on to make_keyframes. Additional keyword arguments are passed on to make_keyframes.
""" """
kffilename = make_keyframes_filename(filename) kffilename = make_keyframes_filename(filename)
if not os.path.exists(kffilename): if not os.path.exists(kffilename):
if generate == GenKeyframesMode.NEVER:
return fallback
if generate == GenKeyframesMode.ASK and not askyesno("Generate Keyframes", \
"No keyframes file was found for this video file.\nShould Aegisub detect keyframes from the video?\nThis will take a while.", default="no"):
return fallback
vs.core.log_message(vs.MESSAGE_TYPE_INFORMATION, "No keyframes file found, detecting keyframes...\n") vs.core.log_message(vs.MESSAGE_TYPE_INFORMATION, "No keyframes file found, detecting keyframes...\n")
keyframes = make_keyframes(clip, **kwargs) keyframes = make_keyframes(clip, **kwargs)
save_keyframes(kffilename, keyframes) save_keyframes(kffilename, keyframes)

View File

@ -374,7 +374,7 @@
}, },
"VapourSynth" : { "VapourSynth" : {
"Log Level": "Information", "Log Level": "Information",
"Default Script" : "# This default script will load a video file using LWLibavSource.\n# It requires the `lsmas` plugin.\n# See ?data/automation/vapoursynth/aegisub_vs.py for more information.\n\nimport vapoursynth as vs\nimport time\nimport aegisub_vs as a\na.set_paths(locals())\n\nclip, videoinfo = a.wrap_lwlibavsource(filename)\nclip.set_output()\n__aegi_timecodes = videoinfo[\"timecodes\"]\n__aegi_keyframes = videoinfo[\"keyframes\"]\n\n# Uncomment the first following line to read keyframes from a file when present.\n#__aegi_keyframes = a.try_get_keyframes(filename, __aegi_keyframes)\n\n# Uncomment the following line to automatically generate keyframes at scene changes. This will take some time when first loading a video.\n#__aegi_keyframes = a.get_keyframes(filename, clip)\n\n# Check if the file has an audio track. This requires the `bas` plugin.\n__aegi_hasaudio = 1 if a.check_audio(filename) else 0" "Default Script" : "# This default script will load a video file using LWLibavSource.\n# It requires the `lsmas` plugin.\n# See ?data/automation/vapoursynth/aegisub_vs.py for more information.\n\nimport vapoursynth as vs\nimport time\nimport aegisub_vs as a\na.set_paths(locals())\n\nclip, videoinfo = a.wrap_lwlibavsource(filename)\nclip.set_output()\n__aegi_timecodes = videoinfo[\"timecodes\"]\n__aegi_keyframes = videoinfo[\"keyframes\"]\n\n# Uncomment this line to make Aegisub look for a keyframes file for the video, or ask to detect keyframes on scene changes if no file was found.\n# You can also change the GenKeyframesMode. Valid values are NEVER, ALWAYS, and ASK.\n#__aegi_keyframes = a.get_keyframes(filename, clip, __aegi_keyframes, generate=a.GenKeyframesMode.ASK)\n\n# Check if the file has an audio track. This requires the `bas` plugin.\n__aegi_hasaudio = 1 if a.check_audio(filename) else 0"
} }
} }
}, },

View File

@ -374,7 +374,7 @@
}, },
"VapourSynth" : { "VapourSynth" : {
"Log Level": "Information", "Log Level": "Information",
"Default Script" : "# This default script will load a video file using LWLibavSource.\n# It requires the `lsmas` plugin.\n# See ?data/automation/vapoursynth/aegisub_vs.py for more information.\n\nimport vapoursynth as vs\nimport time\nimport aegisub_vs as a\na.set_paths(locals())\n\nclip, videoinfo = a.wrap_lwlibavsource(filename)\nclip.set_output()\n__aegi_timecodes = videoinfo[\"timecodes\"]\n__aegi_keyframes = videoinfo[\"keyframes\"]\n\n# Uncomment the first following line to read keyframes from a file when present.\n#__aegi_keyframes = a.try_get_keyframes(filename, __aegi_keyframes)\n\n# Uncomment the following line to automatically generate keyframes at scene changes. This will take some time when first loading a video.\n#__aegi_keyframes = a.get_keyframes(filename, clip)\n\n# Check if the file has an audio track. This requires the `bas` plugin.\n__aegi_hasaudio = 1 if a.check_audio(filename) else 0" "Default Script" : "# This default script will load a video file using LWLibavSource.\n# It requires the `lsmas` plugin.\n# See ?data/automation/vapoursynth/aegisub_vs.py for more information.\n\nimport vapoursynth as vs\nimport time\nimport aegisub_vs as a\na.set_paths(locals())\n\nclip, videoinfo = a.wrap_lwlibavsource(filename)\nclip.set_output()\n__aegi_timecodes = videoinfo[\"timecodes\"]\n__aegi_keyframes = videoinfo[\"keyframes\"]\n\n# Uncomment this line to make Aegisub look for a keyframes file for the video, or ask to detect keyframes on scene changes if no file was found.\n# You can also change the GenKeyframesMode. Valid values are NEVER, ALWAYS, and ASK.\n#__aegi_keyframes = a.get_keyframes(filename, clip, __aegi_keyframes, generate=a.GenKeyframesMode.ASK)\n\n# Check if the file has an audio track. This requires the `bas` plugin.\n__aegi_hasaudio = 1 if a.check_audio(filename) else 0"
} }
} }
}, },