View Full Version : I created a motion menu function for Avisynth
compunerd632
31st July 2002, 16:48
I wrote a function that will create a six-thumbnail motion menu of any size and length. It does a title at the top of the menu and captions for each thumbnail clip. Here's a screenshot of what it can do (you might have to wait a bit):
http://jmj101.cjb.net/jmj101/menudemo.jpg
(I used the same clip for all, but you can do 6 separate ones). Anyway, here's the code:
#################################################
#Six-part Motion Menu, written by Matt Longbrake#
#################################################
#This function creates a six-thumbnail motion menu of any size and length.
#Usage: menu(clip1,"clip1 caption",clip2,"clip2 caption",..."clip6 caption","Menu Title",menu width,menu height,menu length (in frames))
#Setting width or height to 0 will use a default size of 640x480.
#Setting length to 0 will use the full length of the thumbnails.
function menu(clip a, string txt1, clip b, string txt2, clip c, string txt3, clip d, string txt4, clip e, string txt5, clip f, string txt6, string title, int x, int y, int length) {
a = a.BicubicResize(180,136).AddBorders(30,108,20,0)
b = b.BicubicResize(180,136).AddBorders(0,108,20,0)
c = c.BicubicResize(180,136).AddBorders(0,108,30,0)
d = d.BicubicResize(180,136).AddBorders(0,40,20,0).Subtitle(txt1).AddBorders(30,0,0,0)
e = e.BicubicResize(180,136).AddBorders(0,40,20,0).Subtitle(txt2)
f = f.BicubicResize(180,136).AddBorders(0,40,30,0).Subtitle(txt3)
top = StackHorizontal(a,b,c)
middle = StackHorizontal(d,e,f)
g = BlankClip(a,width=200,height=60).Subtitle(txt4)
h = BlankClip(a,width=200,height=60).Subtitle(txt5)
i = BlankClip(a,width=210,height=60).Subtitle(txt6)
bottom = StackHorizontal(g,h,i).AddBorders(30,0,0,0).ConvertToYuy2
StackVertical(top,middle,bottom)
Subtitle(title,38,64,0,a.framecount,"",36)
(x == 0) || (y == 0) ? last : BicubicResize(x,y)
length == 0 ? last : Trim(0,length-1)
}
Hopefully this is of some help to someone! BTW, sorry about the wide post.
Thank you for posting your script.
Do you recognize a speedup if you add brackets to your
bottom = StackHorizontal(g,h,i).AddBorders(30,0,0,0).ConvertToYuy2
command, i.e. change it to:
bottom = StackHorizontal(g,h,i).AddBorders(30,0,0,0).ConvertToYuy2()
?
I read that this could make quite a difference.
bb
compunerd632
1st August 2002, 15:31
I just tried it and it didn't seem to help or hurt the speed. This was also on a Celeron 466 where I tested so there might be a speedup with a faster processor.
kayman
4th August 2002, 16:57
can you explain it please, what each line does im new to avsynth , i dont see any line for importing avis.
:)
kayman
dividee
4th August 2002, 17:59
This is a function definition. You have to provide your own sources.
You use it either by pasting the text in you script or by using the import filter:
Import("menu.avs")
After that, you open 6 clips and name them:
c1=AVISource("clip1.avi")
c2=AVISource("clip2.avi")
...
Then, you call the function:
menu(c1,"chapter 1",c2,"chapter 2",c3,"chapter 3",c4,"chapter 4",c5,"chapter 5",c6,"chapter 6","kaymans svcd",480,576,100)
will produce a 480x576 menu that is 100 frames long. Note that all clips much have the same color format, so if you mix RGB and YUY2 clips you have to convert them to the same format before calling the function.
Edit: I forgot the menu title
kayman
4th August 2002, 18:19
great thanks cant wait to try it out this is exatctly what i want to do but didnt have the know how to write one
kayman
4th August 2002, 18:24
um 1 more thing say if i want a title like "kaymans svcd" at the top
and chapter 1 - 6 under each image how would i do that or can i?
dividee
4th August 2002, 20:52
Oops I forgot the menu title in my example above
I edited my post and changed the call to reflect your question
matrix
4th August 2002, 21:21
say if i want a title like "kaymans svcd" at the top
You can use subtitle, like this:
.Subtitle("Kaymans SVCD",180,50,0,100,"Arial",22,$FFFFFF)
where first argument is horiz. position, second is vertical pos. and the frames, first frame, last frame. Plus the "font", size, color.
Same thing for the chapters, but you have to figure out the actual position for everything; title and chapters.
compunerd632
6th August 2002, 03:28
The subtitle part is built in to the function. When you call it you put menu(nameofvideoclip,"Chapter 1"...), this makes a caption of Chapter 1 under the first clip. You specify the caption for each clip. After the clips is the title, which is put at the top of the menu. If you look at the code there is a line that starts with "#Usage" that tells you what all the arguments are. I'm on a family vacation right now, but when I get home I can write a description of how it works.
dividee:
The call you posted would make a 480x576 menu, not 800x600, just thought I'd point that out.
dividee
6th August 2002, 04:14
I corrected that :o
I first made a 800x600 one, then edited it but forgot to change the text. I'm doing mistake after mistake in this thread...
kayman
7th August 2002, 01:06
ive been trying to manually wdit the avs , but i cant get to display only 4 boxes can some avs master help me out again?
kayman
dividee
7th August 2002, 01:20
Please post your script so we can see what you're doing wrong.
kayman
7th August 2002, 01:24
-main avs -
Import("menu.avs")
c1=AVISource("clip1.avi")
c2=AVISource("clip2.avi")
c3=AVISource("clip3.avi")
c4=AVISource("clip4.avi")
menu(c1,"chapter 1",c2,"chapter 2",c3,"chapter 3",c4,"chapter 4","kaymans svcd",480,576,100)
-end-
-menu avs-
function menu(clip a, string txt1, clip b, string txt2, clip c, string txt3, clip d, string txt4, string title, int x, int y, int length) {
a = a.BicubicResize(180,136).AddBorders(30,108,20,0)
b = b.BicubicResize(180,136).AddBorders(0,108,20,0)
c = c.BicubicResize(180,136).AddBorders(0,108,30,0)
d = d.BicubicResize(180,136).AddBorders(0,40,20,0).Subtitle(txt1).AddBorders(30,0,0,0)
e = e.BicubicResize(180,136).AddBorders(0,40,20,0).Subtitle(txt2)
f = f.BicubicResize(180,136).AddBorders(0,40,30,0).Subtitle(txt3)
top = StackHorizontal(a,b,c)
middle = StackHorizontal(d,e,F)
g = BlankClip(a,width=200,height=60).Subtitle(txt4)
bottom = StackHorizontal(g).AddBorders(30,0,0,0)
StackVertical(top,middle,bottom)
Subtitle(title,38,64,0,a.framecount,"",36)
(x == 0) || (y == 0) ? last : BicubicResize(x,y)
length == 0 ? last : Trim(0,length-1)
}
-end-
dividee
7th August 2002, 03:16
I started to modify the script for 4 clips, but doing the calculations for the positions of each tumbnail is painful.
So I rewrote the script using Layer. I think it makes a script more easier to read and modify:
Here is the original function, rewritten using Layer:
function menu6(clip a, string txt1, clip b, string txt2, clip c, string txt3, clip d, string txt4, clip e, string txt5, clip f, string txt6, string title, int x, int y, int length) {
BlankClip(a, width=640, height=480)
Layer(a.BicubicResize(180,136),"add",256, 30,108).Subtitle(txt1, 38,262)
Layer(b.BicubicResize(180,136),"add",256,230,108).Subtitle(txt2,238,262)
Layer(c.BicubicResize(180,136),"add",256,430,108).Subtitle(txt3,438,262)
Layer(d.BicubicResize(180,136),"add",256, 30,284).Subtitle(txt4, 38,438)
Layer(e.BicubicResize(180,136),"add",256,230,284).Subtitle(txt5,238,438)
Layer(f.BicubicResize(180,136),"add",256,430,284).Subtitle(txt6,438,438)
Subtitle(title,38,64,size=36)
(x == 0) || (y == 0) ? last : BicubicResize(x,y)
length == 0 ? last : Trim(0,length-1)
}
It should produce the same output as compunerd's script.
Here is a version with 4 thumbnails:
function menu4(clip a, string txt1, clip b, string txt2, clip c, string txt3, clip d, string txt4, string title, int x, int y, int length) {
BlankClip(a, width=640, height=480)
Layer(a.BicubicResize(180,136),"add",256,100,108).Subtitle(txt1,108,262)
Layer(b.BicubicResize(180,136),"add",256,360,108).Subtitle(txt2,368,262)
Layer(c.BicubicResize(180,136),"add",256,100,284).Subtitle(txt3,108,438)
Layer(d.BicubicResize(180,136),"add",256,360,284).Subtitle(txt4,368,438)
Subtitle(title,38,64,size=36)
(x == 0) || (y == 0) ? last : BicubicResize(x,y)
length == 0 ? last : Trim(0,length-1)
}
When you use AVISource, some codecs returns RGB32 data with garbage in the alpha channel.
As Layer use that channel, you should set the clips mask to on with something like:
clip=clip.Mask(BlankClip(clip,color=$FFFFFF))
in case you experience any problem.
@compunerd632
Why are you using ConvertToYUY2 in your script? It shouldn't be necessary and limit you script to YUY2.
Without that line it works in both colorspaces.
kayman
7th August 2002, 03:50
thanks!
just 1 more question how do i "call" in my edit.avs? is it the same function
?
Richard Berg
7th August 2002, 03:50
When you use AVISource, some codecs returns RGB32 data with garbage in the alpha channel.
Thought we'd finally fixed this? If not, it's easy enough to do -- the only time you need to actually pay attention to the alpha channel is when importing raw RGB32, and I can't think of any codecs offhand that return this.
dividee
7th August 2002, 03:57
Actually that's what I'm referring to (codecs that returns RGB32).
The divx3.11 codec returns RGB32 data only AFAIK, and with garbage in alpha. (Yes that's stupid for a MPEG type codec no to return YUY2, but that's the case). I don't know if we should reset alpha in AVISource, there might be codec out there that returns genuine alpha info.
kayman
7th August 2002, 04:03
i got it to open up but hte 4 windows are all black no imagepresent
c1=AVISource("clip1.avi")
c2=AVISource("clip2.avi")
c3=AVISource("clip3.avi")
c4=AVISource("clip4.avi")
menu4(c1,"chapter 1",c2,"chapter 2",c3,"chapter 3",c4,"chapter 4","kaymans svcd",480,576,450)
dividee
7th August 2002, 04:17
Is your data RGB32 ? If yes, could you try this:
c1=AVISource("clip1.avi")
c2=AVISource("clip2.avi")
c3=AVISource("clip3.avi")
c4=AVISource("clip4.avi")
c1=c1.Mask(BlankClip(c1,color=$FFFFFF))
c2=c2.Mask(BlankClip(c2,color=$FFFFFF))
c3=c3.Mask(BlankClip(c3,color=$FFFFFF))
c4=c4.Mask(BlankClip(c4,color=$FFFFFF))
menu4(c1,"chapter 1",c2,"chapter 2",c3,"chapter 3",c4,"chapter 4","kaymans svcd",480,576,450)
kayman
7th August 2002, 04:23
its dv data ill give it a go
your my hero by th way
works super thanks!!!!!!
dividee
7th August 2002, 04:26
Thanks :)
But compunerd is the creator, I'm just the technician.
compunerd632
7th August 2002, 18:20
The reason I used the ConvertToYuy2 is because the blankclip I used made a black rgb clip which wouldn't stack with yuv clips. I figured most clips would be yuv so I had to convert the blankclip to stack with other data. Also, to make a 4 clip one you could just use blank clips for two of the six spaces. That would not have even spacing, but it would be a quick solution.
dividee
7th August 2002, 18:53
Since you use the "a" clip as a template, BlankClip should give you a clip with the same color space as "a". If not, this is a bug in avisynth, but I tested it and on my version it behaves as it should.
compunerd632
10th August 2002, 19:44
Ok guys, I put all this together into a script that has 6, 4, and 2 clip functions. Thanks to Dividee for the tip on Layer. Here it is:
################################
#Motion Menus by Matt Longbrake#
################################
# With help from Dividee
# These functions create a motion menu of any size and length.
# There are versions for 6, 4, and 2 clip menus.
# Usage: Import this script into your script with something like Import("menu.avs")
# Call the function with menu6, menu4, or menu2
# Arguments are:
# menu6(clip1,"clip1 caption",clip2,"clip2 caption",...,"Menu Title",width,height,length (in frames))
# Notes: Using 0 for width or height will return a 640x480 clip
# Using 0 for length will make the menu the same length as the first clip
function menu6(clip a, string txt1, clip b, string txt2, clip c, string txt3, clip d, string txt4, clip e, string txt5, clip f, string txt6, string title, int x, int y, int length) {
BlankClip(a, width=640, height=480)
Layer(a.BicubicResize(180,136),"add",256, 30,108).Subtitle(txt1, 38,260)
Layer(b.BicubicResize(180,136),"add",256,230,108).Subtitle(txt2,238,260)
Layer(c.BicubicResize(180,136),"add",256,430,108).Subtitle(txt3,438,260)
Layer(d.BicubicResize(180,136),"add",256, 30,284).Subtitle(txt4, 38,436)
Layer(e.BicubicResize(180,136),"add",256,230,284).Subtitle(txt5,238,436)
Layer(f.BicubicResize(180,136),"add",256,430,284).Subtitle(txt6,438,436)
Subtitle(title,38,64,size=36)
(x == 0) || (y == 0) ? last : BicubicResize(x,y)
length == 0 ? last : Trim(0,length-1)
}
function menu4(clip a, string txt1, clip b, string txt2, clip c, string txt3, clip d, string
txt4, string title, int x, int y, int length) {
BlankClip(a, width=640, height=480)
Layer(a.BicubicResize(180,136),"add",256,100,108).Subtitle(txt1,108,260)
Layer(b.BicubicResize(180,136),"add",256,360,108).Subtitle(txt2,368,260)
Layer(c.BicubicResize(180,136),"add",256,100,284).Subtitle(txt3,108,436)
Layer(d.BicubicResize(180,136),"add",256,360,284).Subtitle(txt4,368,436)
Subtitle(title,108,64,size=36)
(x == 0) || (y == 0) ? last : BicubicResize(x,y)
length == 0 ? last : Trim(0,length-1)
}
function menu2(clip a, string txt1, clip b, string txt2, string title, int x, int y, int
length) {
BlankClip(a, width=640, height=480)
Layer(a.BicubicResize(280,210),"add",256, 30,160).Subtitle(txt1, 38,386)
Layer(b.BicubicResize(280,210),"add",256,330,160).Subtitle(txt2,338,386)
Subtitle(title,38,96,size=36)
(x == 0) || (y == 0) ? last : BicubicResize(x,y)
length == 0 ? last : Trim(0,length-1)
}
bugs7
1st October 2002, 00:43
With this sample, i'mad a motion svcd/dvd menu menu with 9 clip, background image, and next/previous button.
this here (http://forum.media-video.com/viewtopic.php?t=8019) but it's in french.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.