5
0

Compare commits

..

2 Commits

Author SHA1 Message Date
e144906b11
vivy: tv: common: upstream dehardsubbing utility to lvsfunc 2021-04-17 20:52:22 -04:00
69c3ddaa61
vivy: tv: friendship ended with funi & subsplease
Erai-Raws has good funi audio still if amazon isn't out in time
2021-04-17 18:19:28 -04:00
10 changed files with 81 additions and 167 deletions

4
.gitignore vendored
View File

@ -6,8 +6,12 @@
*.png
*.aac
*.m4a
*.h264
*.h265
*.eac3
*.ass
*.mka
*.xml
cudnn_data/
*.webm
ffmpeg2pass*.log

View File

@ -1,12 +1,15 @@
import vapoursynth as vs
from lvsfunc.types import Range
from lvsfunc.dehardsub import HardsubSign, bounded_dehardsub
from typing import List
import os
import sys
sys.path.append("..")
from vivy_common import (HardsubSign, Range, bounded_dehardsub, antialias, deband, denoise, # noqa: E402
from vivy_common import (SelfRunner, antialias, deband, denoise, # noqa: E402
finalize, fsrcnnx_rescale, letterbox_edgefix, source)
core = vs.core
@ -37,10 +40,16 @@ LETTERBOX: List[Range] = [
(659, 14071)
]
def filter_basic() -> vs.VideoNode:
waka, ref = source(EPNUM)
waka = waka[:37301] + core.std.BlankClip(waka, length=6) + waka[37301:]
src = bounded_dehardsub(waka, ref, SIGNS_RU)
return src
def filter() -> vs.VideoNode:
src = filter_basic()
rescale = fsrcnnx_rescale(src, NOSCALE)
den = denoise(rescale)
deb = deband(den)
@ -48,3 +57,10 @@ aa = antialias(deb, NOAA)
edgefix = letterbox_edgefix(aa, LETTERBOX)
final = finalize(edgefix)
final.set_output()
return final
if __name__ == "__main__":
SelfRunner(EPNUM, filter, filter_basic)
else:
filter()

View File

@ -1,13 +1,16 @@
import vapoursynth as vs
from lvsfunc.types import Range
from lvsfunc.dehardsub import HardsubSign, bounded_dehardsub
from typing import List
import os
import sys
sys.path.append("..")
from vivy_common import (HardsubSign, Range, bounded_dehardsub, antialias, deband, denoise, # noqa: E402
finalize, fsrcnnx_rescale, source)
from vivy_common import (SelfRunner, antialias, deband, denoise, finalize, # noqa: E402
fsrcnnx_rescale, source)
core = vs.core
@ -45,13 +48,26 @@ PIXELSHIT: List[Range] = [
NOSCALE: List[Range] = CREDITS + PIXELSHIT
NOAA: List[Range] = PIXELSHIT
def filter_basic() -> vs.VideoNode:
waka, ref = source(EPNUM)
waka = waka[:32344] + waka[32349:]
src = bounded_dehardsub(waka, ref, SIGNS_RU)
return src
def filter() -> vs.VideoNode:
src = filter_basic()
rescale = fsrcnnx_rescale(src, NOSCALE)
den = denoise(rescale)
deb = deband(den)
aa = antialias(deb, NOAA)
final = finalize(aa)
final.set_output()
return final
if __name__ == "__main__":
SelfRunner(EPNUM, filter, filter_basic)
else:
filter()

View File

@ -1,12 +1,15 @@
import vapoursynth as vs
from lvsfunc.types import Range
from lvsfunc.dehardsub import HardsubSign, bounded_dehardsub
from typing import List
import os
import sys
sys.path.append("..")
from vivy_common import (HardsubSign, Range, SelfRunner, bounded_dehardsub, antialias, deband, denoise, # noqa: E402
from vivy_common import (SelfRunner, antialias, deband, denoise, # noqa: E402
finalize, fsrcnnx_rescale, letterbox_edgefix, source)
core = vs.core

View File

@ -1,32 +0,0 @@
#!/usr/bin/env python3
import vapoursynth as vs
import acsuite
import os
import sys
from subprocess import DEVNULL, call
from vivy_common.util import FUNI_FILENAME, FUNI_INTRO, glob_crc
EPNUM: int = int(sys.argv[1])
ac = acsuite.AC()
core = vs.core
funi: str = glob_crc(os.path.join(f"{EPNUM:02d}", FUNI_FILENAME.format(epnum=EPNUM)))
src = core.ffms2.Source(funi)
if __name__ == "__main__":
funi_audio: str = f"{EPNUM:02d}/funi.aac"
if not os.path.isfile(funi_audio):
call(["ffmpeg",
"-i", funi,
"-vn",
"-sn",
"-map_metadata", "-1",
"-c:a", "copy",
funi_audio],
stdout=DEVNULL, stderr=DEVNULL
)
ac.eztrim(src, (FUNI_INTRO, 0), funi_audio, f"{EPNUM:02d}/{EPNUM:02d}_cut.mka")

View File

@ -24,7 +24,7 @@ ignore_errors = False
allow_untyped_globals = False
allow_redefinition = False
implicit_reexport = False
implicit_reexport = True
strict_equality = True
show_error_context = False
@ -34,6 +34,8 @@ color_output = True
error_summary = True
pretty = True
mypy_path = .
[mypy-cytoolz.*]
ignore_errors = True

View File

@ -1,3 +1,2 @@
from .dehardsub import HardsubSign, bounded_dehardsub, get_all_masks # noqa: F401
from .filter import antialias, deband, denoise, finalize, fsrcnnx_rescale, letterbox_edgefix # noqa: F401
from .util import Range, SelfRunner, glob_crc, source # noqa: F401
from .util import SelfRunner, glob_crc, source # noqa: F401

View File

@ -1,97 +0,0 @@
import vapoursynth as vs
import kagefunc as kgf
import lvsfunc as lvf
from typing import List, NamedTuple, Optional, Tuple, Union
from .util import Range
core = vs.core
class Position(NamedTuple):
x: int
y: int
class Size(NamedTuple):
x: int
y: int
class BoundingBox():
pos: Position
size: Size
def __init__(self, pos: Position, size: Size):
self.pos = pos
self.size = size
class HardsubSign():
range: Range
bound: Optional[BoundingBox]
refframe: Optional[int]
highpass: int
expand: int
def __init__(self,
range: Range,
bound: Union[BoundingBox, Tuple[Tuple[int, int], Tuple[int, int]], None],
refframe: Optional[int] = None, highpass: int = 5000, expand: int = 8):
self.range = range
self.refframe = refframe
self.highpass = highpass
self.expand = expand
if bound is None:
self.bound = None
elif isinstance(bound, BoundingBox):
self.bound = bound
else:
self.bound = BoundingBox(Position(bound[0][0], bound[0][1]), Size(bound[1][0], bound[1][1]))
def _hardsub_mask(self, hrdsb: vs.VideoNode, ref: vs.VideoNode) -> vs.VideoNode:
if self.refframe is not None:
mask = kgf.hardsubmask_fades(hrdsb[self.refframe], ref[self.refframe],
highpass=self.highpass, expand_n=self.expand)
else:
mask = kgf.hardsubmask_fades(hrdsb, ref, highpass=self.highpass, expand_n=self.expand)
assert isinstance(mask, vs.VideoNode)
return mask
def _bound_mask(self, ref: vs.VideoNode) -> vs.VideoNode:
if self.bound is not None:
mask = kgf.squaremask(ref, self.bound.size.x, self.bound.size.y,
self.bound.pos.x, self.bound.pos.y)
else:
mask = kgf.squaremask(ref, ref.width, ref.height, 0, 0)
assert isinstance(mask, vs.VideoNode)
return mask
def get_mask(self, hrdsb: vs.VideoNode, ref: vs.VideoNode) -> vs.VideoNode:
bm = self._bound_mask(ref)
hm = self._hardsub_mask(hrdsb, ref)
return core.std.MaskedMerge(core.std.BlankClip(hm), hm, bm)
def get_all_masks(hrdsb: vs.VideoNode, ref: vs.VideoNode, signs: List[HardsubSign]) -> vs.VideoNode:
"""
Scenefiltering helper, not used in encode
"""
assert ref.format is not None
mask = core.std.BlankClip(ref, format=ref.format.replace(color_family=vs.GRAY, subsampling_w=0, subsampling_h=0).id)
for sign in signs:
mask = lvf.misc.replace_ranges(mask, core.std.Expr([mask, sign.get_mask(hrdsb, ref)], 'x y +'), [sign.range])
return mask
def bounded_dehardsub(hrdsb: vs.VideoNode, ref: vs.VideoNode, signs: List[HardsubSign]) -> vs.VideoNode:
bound = hrdsb
for sign in signs:
bound = lvf.misc.replace_ranges(bound,
core.std.MaskedMerge(bound, ref, sign.get_mask(hrdsb, ref)),
[sign.range])
return bound

View File

@ -4,11 +4,10 @@ import lvsfunc as lvf
import vardefunc as vdf
from awsmfunc import bbmod
from lvsfunc.types import Range
from mvsfunc import BM3D
from typing import List, Optional
from .util import Range
import os
import vsutil

View File

@ -14,8 +14,6 @@ from typing import Any, BinaryIO, Callable, List, Optional, Sequence, Tuple, Uni
core = vs.core
Range = Union[int, Tuple[int, int]]
TITLE: str = "Vivy"
TITLE_LONG: str = f"{TITLE} - Fluorite Eye's Song"
RESOLUTION: int = 1080
@ -184,13 +182,16 @@ class AudioGetter():
print(f"{SUCCESS}Found Amazon audio{RESET}")
return
# as of Ep4 SubsPlease is using new funi 128kbps aac while erai has 256kbps still
try:
if os.path.isfile(ER_FILENAME.format(epnum=epnum)):
self.audio_file = ER_FILENAME.format(epnum=epnum)
self.video_src = core.ffms2.Source(ER_FILENAME.format(epnum=epnum))
if os.path.isfile(glob_crc(SUBSPLS_FILENAME.format(epnum=epnum))):
self.audio_file = glob_crc(SUBSPLS_FILENAME.format(epnum=epnum))
self.video_src = core.ffms2.Source(glob_crc(SUBSPLS_FILENAME.format(epnum=epnum)))
elif os.path.isfile(ER_FILENAME.format(epnum=epnum)):
self.audio_file = ER_FILENAME.format(epnum=epnum)
self.video_src = core.ffms2.Source(ER_FILENAME.format(epnum=epnum))
if (epnum >= 4):
print(f"{WARNING}Using SubsPlease, audio may be worse than Erai-Raws{RESET}")
else:
raise FileNotFoundError()
except FileNotFoundError:
@ -305,7 +306,8 @@ class SelfRunner():
try:
print(f"{STATUS}--- MUXING FILE ---{RESET}")
if self._mux(f"{TITLE.lower()}_{epnum:02d}_{args.suffix}.mkv", not args.no_metadata) != 0:
if self._mux(f"{TITLE.lower()}_{epnum:02d}_{args.suffix}.mkv", not args.no_metadata,
not args.no_metadata and start == 0 and end == self.clip.num_frames) != 0:
raise Exception("mkvmerge failed")
except Exception:
print(f"{ERROR}--- MUXING FAILED ---{RESET}")
@ -321,7 +323,7 @@ class SelfRunner():
print(f"{SUCCESS}--- ENCODE COMPLETE ---{RESET}")
def _mux(self, name: str, metadata: bool = True) -> int:
def _mux(self, name: str, metadata: bool = True, chapters: bool = True) -> int:
mkvtoolnix_args = [
"mkvmerge",
"--output", name,
@ -337,10 +339,12 @@ class SelfRunner():
mkvtoolnix_args += [
"--title", f"[{SUBGROUP}] {TITLE_LONG} - {self.epnum:02d}",
]
chapters = [f for f in ["{self.epnum:02d}.xml", "chapters.xml"] if os.path.isfile(f)]
if len(chapters) != 0:
if chapters:
chap = [f for f in ["{self.epnum:02d}.xml", "chapters.xml"] if os.path.isfile(f)]
if len(chap) != 0:
mkvtoolnix_args += [
"--chapters", chapters[0],
"--chapters", chap[0],
]
print("+ " + " ".join(mkvtoolnix_args))