본문 바로가기

동영상 지식/avisynth 스크립트

avs 필터 선택적&반복적 적용 스크립트

먼저 가장 자주 쓰이는 선택적으로 1회 적용에 쓰이는 SceneAdjust.avsi

function sceneadjust(clip a, int "start", int "end", string "filters")  {
start = Default(start,0)
end = Default(end,a.framecount)

part1 = (start <= 1) ? a.Trim(0,-1)  : a.trim(0,start-1)
part3 = (end >= a.framecount-1) ? a.trim(0,-1) : a.trim(end+1,a.framecount)
a=part1+Eval("a."+filters).trim(start,end)+part3
a = (start <= 1)? a.trim(1,a.framecount) : a
(end >= a.framecount-1) ? a.trim(0,a.framecount-2):a
}


매우 유용한 스크립트에요. 이걸로 직접 트림을 쓰지 않아도 선택적 필터 적용을 아주 쉽게 할 수 있어요.

avisynth 플러그인 폴더에 avsi파일로 저장해두시면 따로 임포트 안해도 바로 사용 가능하구요.

사용법은 간단합니다.

sceneadjust(start=a, end=b, filters="c")#a번프레임부터 b번 프레임 까지만 c필터 적용.
이렇게 쓰시면 되요.






그럼 이제 선택적 적용을 반복하는 스크립트를 알려드릴게요. sceneadjust를 변형해 보았습니다.

영상 a를 b프레임에서 c프레임까지 d장 프레임마다 e장씩 f필터를 적용하는 스크립트입니다.


FFVideoSource("template.mp4", threads=8)
#SceneAdjust를 변형하여 셀렉트레인지루프라는 이름을 아무렇게 막 지은 함수를 일단 만들겠습니다.
function SelectRangeLoop(clip c,int n,int m,int lp,int am,string "filters")
{
    start = Default(n,0)
    end = Default(n+am,c.framecount)
    part1 = (start <= 1) ? c.Trim(0,-1)  : c.trim(0,start-1)
    part3 = (end >= c.framecount-1) ? c.trim(0,-1) : c.trim(end+1,c.framecount)
    c=part1+Eval("c."+filters).trim(start,end)+part3
    c = (start <= 1)? c.trim(1,c.framecount) : c
    (end >= c.framecount-1) ? c.trim(0,c.framecount-2):c
    return (n>m) ? c : SelectRangeLoop(c,n+lp,m,lp,am,filters)
}
SelectRangeLoop(a,b,c,d,e,"f") #함수를 이렇게 사용하는데요.
#영상 a를 b프레임에서 c프레임까지 d장 프레임마다 e장씩 f필터를 적용이니 원하는 값으로 바꿔넣으시면 됩니다.
#예: SelectRangeLoop(last,0,last.framecount,100,30,"Blur(1)")


이건 재귀함수를 이용하는것이기 때문에 너무 반복이 많으면 오버플로우 때문인지 작동이 안되더군요.

그래서 다른 방법도 찾아봤습니다.


FFVideoSource("template.mp4", threads=8) source=last #↓이부분에 필터 적용을 합니다. adj=last msk=BlankClip(length=1, width=source.width,height=source.height,fps=source.framerate, color=$000000) \+BlankClip(length=2, width=source.width,height=source.height,fps=source.framerate, color=$ffffff) \+BlankClip(length=1, width=source.width,height=source.height,fps=source.framerate, color=$000000) \+BlankClip(length=1, width=source.width,height=source.height,fps=source.framerate, color=$ffffff) msk=msk.Loop(times=-1, start=0) Overlay(source,adj, x=0, y=0, mask=msk,opacity=1.0, mode="blend") #이건 color=$000000 부분은 냅두고 $ffffff부분만 필터적용을 하겠다는 소립니다. #즉 여기선 한프레임 놔두고 두프레임 적용하고 한프레임 놔두고 한프레임 적용한다는 뜻입니다. #적용/미적용을 따지면, '적미미적미'가 되서 60프레임중에 24프레임을 놔두고 36프레임을 적용한다는 소리입니다. #실제로는 미적용 프레임도 렌더링을 하는거라 CPU부하량은 염두해주셔야 합니다.


이건 좀 편법인데요, 오버레이 덮어씌우기와 마스크를 이용해서 렌더를 두개 해서 원하는 프레임만 덮어씌우는 방법이에요.

필터를 여러번 적용하는게 아니라 한번 적용하는거라 메모리 걱정도 없습니다만 적용 미적용 관계없이 다 렌더를 하니 느리겠죠..


솔직히 첫번째 스크립트만 자주 쓰지, 선택적 적용을 반복해서 해야할 경우가 있나 싶지만 사람일은 모르는거니 일단 써두는걸로..