View Full Version : Cyclic clip switching?


Stereodude
5th January 2019, 02:04
If I have 3 synchronized video clips and I want to cycle between them on a periodic basis, is there a more elegant way to do this than a very long list of unalignedsplice'd trim statements?

source1=AVIsource("Test1.avi", audio = false, pixel_type = "YV12")
source2=AVIsource("Test2.avi", audio = false, pixel_type = "YV12")
source3=AVIsource("Test3.avi", audio = false, pixel_type = "YV12")

(source1.trim(0,499) + source2.trim(500,999) + source3.trim (1000,1499) + source1,trim(1500,1999) + ... )

This was the best I could come up with, which is better, but still a tad complicated as I have to generate the test.txt file.

source1=AVIsource("Test1.avi", audio = false, pixel_type = "YV12")
source2=AVIsource("Test2.avi", audio = false, pixel_type = "YV12")
source3=AVIsource("Test3.avi", audio = false, pixel_type = "YV12")

ConditionalSelect(source1, "(xyx_out==1) ? 0 : ((xyx_out==2) ? 1 : 2)", source1, source2, source3, false)
ConditionalReader("test.txt", "xyx_out", false)
with a test.txt file that looks like:
Type int
Default 0

R 0 499 1
R 500 999 2
R 1000 1499 3
R 1500 1999 1
...


This seemed like a good start
source1=AVIsource("Test1.avi", audio = false, pixel_type = "YV12").selectrangeevery(1500,500,0)
source2=AVIsource("Test2.avi", audio = false, pixel_type = "YV12").selectrangeevery(1500,500,499)
source3=AVIsource("Test3.avi", audio = false, pixel_type = "YV12").selectrangeevery(1500,500,999)
but I can't figure out how to interleave the resulting three clips every 500 frames as the interleave filter doesn't allow an range interval to be specified and only works on a per frame basis

Is there some cleaner/easier solution I'm missing? (I'm using AVIsynth+ if it matters)

Groucho2004
5th January 2019, 03:27
Maybe some looping with GScript (http://avisynth.nl/index.php/Gscript)?

poisondeathray
5th January 2019, 05:02
another hackish way is to use a mask to control visibility of a layer


rough script, proof of concept


length=500

r=blankclip(length=10000, color=color_red).showframenumber()
g=blankclip(length=10000, color=color_green).showframenumber()
b=blankclip(length=10000, color=color_blue).showframenumber()

black=blankclip(r).trim(0,length-1)
white=blankclip(r,color=color_white).trim(0,length-1)

white+black+black
loop(1000) #should calculate, but big loop# for testing now
wbb_loop=last

black+black+white
loop(1000) #should calculate, but big loop# for testing now
bbw_loop=last

gr=overlay(g,r,mask=wbb_loop)

overlay(gr,b , mask=bbw_loop)



needs cleanup:

-you need to replace the r,g,b with a,b,c avisource() or real source filter, but blankclip should take on the characteristics of the "a" clip)

-there is probably a smarter way to calcuate the length, like a.length*3 for 3* frames, to replace the loop() command

-remember to make the mask layers fullrange if using YUV, YUV sources

-maybe masktools mask (mt_merge) better way to control visibility, it's supposed to be faster processing, but not sure of current benchmarks in avs+

StainlessS
5th January 2019, 05:19
Maybe some looping with GScript (http://avisynth.nl/index.php/Gscript)?

this seems to work-ish

LEN=10000
BLKSZ=10 # Set to 500
A=BlankClip(Length=LEN,Pixel_type="YV12",COLOR=$FF0000).ShowFrameNumber
B=BlankClip(Length=LEN,Pixel_type="YV12",COLOR=$00FF00).ShowFrameNumber
C=BlankClip(Length=LEN,Pixel_type="YV12",COLOR=$0000FF).ShowFrameNumber

BLKS = Min(A.FrameCount,B.FrameCount,C.FrameCount) / BLKSZ

Z = A.BlankClip(Length=0)

for(n=0,BLKS-1) {
M = n % 3
Z = Z ++ (M==0?A:M==1?B:C).Trim(n*BLKSZ,-BLKSZ)
}

Return Z

EDIT: No attempt to make it play nice at end of clip [based on shortest clip, may be truncated].
EDIT: Not sure if I remember that stickboy has an InterLeaveEvery() type function.
EDIT: YES he does, here (In the ApplyEvery plugin):- http://www.avisynth.nl/users/stickboy/

Stereodude
7th January 2019, 02:39
Thanks for the replies and suggestions guys. I need to take a closer look at some of them.

Stereodude
7th January 2019, 18:05
I ended up taking a slight different tack for my task. I wanted to make a script that compared the original source with my post processed version. After trying my original idea cycling between three different static side by side comparison views I decided to try something I thought would be better.

Your scripts gave me the basic template to modify. I would have never gotten to what I wanted without your templates showing me what was possible. So, a big thank you to you guys!

Now I just need the bug I discovered in AVIsynth+ fixed. (The script crashes if LEN is too large and for this to work in a single script needs to be the same as LEN2)
LEN2=103848
LEN=15900
A=BlankClip(Length=LEN2, height=786, width=1920, Pixel_type="YV12",COLOR=$FF0000).ShowFrameNumber
B=BlankClip(Length=LEN2, height=786, width=1920, Pixel_type="YV12",COLOR=$00FF00).ShowFrameNumber

Z = A.BlankClip(Length=0)
frame=0

while( frame < LEN) {
for(n=2, 958, 2) {
Z = Z ++ stackhorizontal(stackhorizontal(A.crop(0,0,n,-0),B.crop(n,0,960,-0)),A.crop(960+n,0,-0,-0)).trim(frame,end=frame)
frame = frame + 1
if ( frame == LEN) { Return Z }
}

for(n=958, 2, -2) {
Z = Z ++ stackhorizontal(stackhorizontal(A.crop(0,0,n,-0),B.crop(n,0,960,-0)),A.crop(960+n,0,-0,-0)).trim(frame,end=frame)
frame = frame + 1
if ( frame == LEN) { Return Z }
}
}

Return Z

StainlessS
7th January 2019, 18:34
I doubt that its a problem in avs+, me guesses that it is your very mysterious script that is the problem.

Can you put into words what it is that its intended to do.

Stereodude
7th January 2019, 18:51
I doubt that its a problem in avs+, me guesses that it is your very mysterious script that is the problem.

Can you put into words what it is that its intended to do.
Well, you could run it and see. The sample script I posted is completely self-contained and shows the crashing issue. It is not dependent on any external files.

But, the idea is to have a 960 pixel wide window that slides left and right bouncing between the two edges of the complete frame that has a window to the original source in it. The rest of the video frame contains the post processed version. It's like a moving before / after split screen.

The script crashes depending on the length of the while loop and the limit isn't hard or exact. The limit changes a little bit depending on the program loading the script.

Frank62
9th January 2019, 18:23
After a bit thinking, I found this:
First mix up, then "rotate" one frame, and select back, what you want:

v=interleave(a,b,c)
v=selectrangeevery(v,1501,1500,0)
v=selectevery(v,3,0)

Unfortunately you will miss one frame with each "rotation", but I am sure there is a solution for this.