Log in

View Full Version : Trim + Display segment on a progress bar


devhercule
4th September 2014, 16:29
Hi,

I request you again to improve an AviSynth code.

The code concatenates a set of video segments extracted from the video with a dissolve between each two concatenated segments.

A progress bar indicating the actual position in the original video is displayed.

The code is developped by "raffriff42" and "StainlessS" who have helped me a lot.

A = FFAudioSource("video.mp4")
V = FFVideoSource("video.mp4")
AudioDub(V, A)

ShowFrameNumber(scroll=true,x=30,y=30)
ShowTime(x=80,y=50)

ProgressBar()
Dissolve(Trim(0,200), Trim(1350,1700), Trim(13350,13700), Trim(99150,99400), Trim(150000,150300), Trim(170000,170300), Trim(190000,190300), Trim(192000,192278), 25)
return Last

Function ProgressBar(clip clp, int "x", int "y", int "wid", int "hgt", int "color", float "opacity", int "bar_color", float "bar_opacity", int "bord", int "bord_color", float "bord_opacity",Int "Decimals",Bool "Track")
{
clp
myName="ProgressBar: "
Function ProgressBar_Anim_LO(clip clp,clip bar,clip bgd,Float Perc,int x,int y,int bord,Float opbar,Float opbgd,Int decimals,bool Track){
clp
wid = bgd.Width wbar = wid*Perc wbgd = wid-wbar
(Round(wbar)>0) ? Last.OverLay(bar.Crop(0,0,Round(wbar),-0),x=x,y=y,opacity=opbar) : Last
(Round(wbgd)>0) ? Last.OverLay(bgd.Crop(0,0,Round(wbgd),-0),x=x+Round(wbar),y=y,opacity=opbgd) : Last
xt=Max(32.0,Min(wid-64.0,x+wbar-32.0+2.0))
(decimals>=0 && !Track) ? Last.Subtitle(String(Perc*100.0, "%0."+String(decimals)+"f")+"%",x=x+wid+bord+10,y=y-5,size=13,text_color=$ffd455) : NOP
(decimals>=0 && Track) ? Last.Subtitle(String(Perc*100.0, "%0."+String(decimals)+"f")+"%",x=xt,y=y) : NOP
Last
}
x = Default(x, 30) y = Default(y, Height-20)
wid = Max(0, Default(wid, Width-x-64)) hgt = Max(0, Default(hgt, 9))
color = Default(color, $ffffff) opacity = Float(Default(opacity, 0.0))
bar_color = Default(bar_color, $ffd455) bar_opacity = Float(Default(bar_opacity, 0.5))
bord = Max(0, Default(bord, 2)) bord_color = Default(bord_color, $000000) bord_opacity = Float(Default(bord_opacity, 0.5))
decimals = Min(Default(decimals, 2), 8)

Track=Default(Track,False)
Assert(x>=0 && x<Width,myName+"Invalid x coord")
Assert(y>=0 && y<Height,myName+"Invalid y coord")
Assert(wid>0 && x+wid<=Width,myName+"Invalid wid")
Assert(hgt>0 && y+hgt<=Height,myName+"Invalid hgt")
brd = Last.BlankClip(pixel_type="YV24", color=bord_color,width=wid,height=hgt)
brdmsk = Last.BlankClip(pixel_type="YV24", color=$FFFFFF,width=wid,height=hgt).Overlay(Last.BlankClip(pixel_type="YV24", color=$0,width=wid-2*bord,height=hgt-2*bord), x=bord, y=bord).ColorYUV(levels="TV->PC")
Last.Overlay(brd,x=x,y=y,mask=brdmsk,opacity=bord_opacity)
bgd=Last.BlankClip(pixel_type="YV24", color=color,width=wid-2*bord,height=hgt-2*bord)
bar=Last.BlankClip(pixel_type="YV24", color=bar_color,width=wid-2*bord,height=hgt-2*bord)
ix=x+bord iy=y+bord
Animate( 0, FrameCount-1, "ProgressBar_Anim_LO", bar,bgd,0.0,ix,iy,bord,bar_opacity,opacity,decimals,Track, bar,bgd,1.0,ix,iy,bord,bar_opacity,opacity,decimals,Track)
}

I want to improve the progress bar in the way to keep the history of viewed segments: I want to to display the viewed segments with a distingshed color once it is viewed.
The progress bar moves with the segments display, one a segment is displayed it appears with a different color in the progress bar.

I hope that i was clear

Here an image illustrating what i want to do.

Thank you

StainlessS
5th September 2014, 05:17
I dont have time to look at this for the next few days, but suggest that RT_Dbase funcs might assist to track viewed frames.
It would though be a quite heavy duty task finding where the start and end of each segment is and at every frame.

EDIT: I'm not even sure its possible.

raffriff42
5th September 2014, 13:48
Hoo-ha! The trick is to build the multi-colored bar ahead of time.

https://www.dropbox.com/s/h5h7hjpiszpz778/drawbar-ProgressBar3.jpg?raw=1
## Last=YV12

## begin user config section: ######################

## (debugging)
#ShowFrameNumber(x=30, y=30)
#ShowTime(x=80, y=50)
#return Last

## progress bar placement
global barhgt = 16 ## bar height (not tested at other heights)
global lftpad = 16 ## left pad
global rgtpad = 80 ## right pad
global botpad = 16 ## bottom pad

## colors etc
global outlclr = color_black ## outline color
global outlopc = 0.75 ## outline opacity (should be >= progress bar opacity)
global outlwid = 3 ## outline width (0 for no outline)
global progopc = 0.5 ## progress bar opacity
global txtclr = transparent_color(0.75, color_khaki) ## progress text color


## EDITING:
## scenes must be assigned clip var's
C1=Trim(150,350+30)
C2=Trim(900,1100+30)
C3=Trim(1350,1700)

## - assign each scene a color
## preset color chooser: see
## http://avisynth.nl/index.php?title=Color_presets
##
global gF = StackHorizontal(
\ BlankClip(Last, length=1, pixel_type="RGB32",
\ width=C1.FrameCount, color=color_khaki),
\ BlankClip(Last, length=1, pixel_type="RGB32",
\ width=C2.FrameCount, color=color_indianred),
\ BlankClip(Last, length=1, pixel_type="RGB32",
\ width=C3.FrameCount, color=color_khaki)
\ ).BilinearResize(Width-(lftpad+rgtpad), Height).ConvertToYV12
\ .AddBorders(lftpad, 0, rgtpad, 0)
\ .Loop(-1).Trim(0, -FrameCount)
## (you may want to save this as a still image and enhance in a paint program)
#return gF

## assembled timeline
C1.Dissolve(C2, 30).Dissolve(C3, 30)
#return Last

## /end user config section ########################

## progress bar master rectangle
global ox1 = lftpad
global ox2 = Width - rgtpad
global oy1 = Height - (barhgt+botpad)
global oy2 = oy1 + barhgt

## do it!
return ProgressBar3


##################################
### create a multicolored progress bar that is slowly revealed as video plays
##
function ProgressBar3(clip C)
{
## filled progress bar + fixed readout
Animate(C, 1, C.FrameCount, "simple_box_3",
\ gF, 1.0,
\ gF, ox2-ox1)

## outline
Last = (outlopc<=0.0 || outlwid<1) ? Last
\ : BoxMaskOverlay(
\ ox1, oy1, ox2, oy2,
\ color=outlclr, opacity=outlopc,
\ outline_width=outlwid, maskblur=0.5)

return Last
}

##################################
### video clip as progress bar + fixed readout
##
function simple_box_3(clip C, clip F, float "wid")
{
## progress bar
bx1 = ox1 + 1
bx2 = bx1 + Round(wid)
by1 = oy1 + 1
by2 = by1 + barhgt - 2

## progress readout
progress = wid/(C.width-(lftpad+rgtpad))*100

return C.BoxMaskOverlay(
\ bx1, by1, bx2, by2,
\ outline_width=0, over=F,
\ opacity=progopc, maskblur=0.3+Abs(wid-Round(wid)))
\ .Subtitle(String(progress, "%0.2f")+"%",
\ x=ox2+8, y=by1-1, size=barhgt-1, text_color=txtclr)
}

##################################
### DrawBox mask
##
## @ x1, y1 - left, top of rectangle mask
## @ x2, y2 - right, bottom of rectangle mask
## @ wid, hgt - width, height of rectangle mask; x2, y2 have priority
## @ outline_width - if zero (default), draw a filled rectangle; else draw outline
## @ preclear - if true (default), start with a pure white (opaque) clip,
## else keep C inside rect & set to black outside
##
function BoxMask3(clip C,
\ int "x1", int "y1", int "x2", int "y2",
\ int "wid", int "hgt", float "outline_width",
\ bool "preclear")
{
preclear = Default(preclear, true)
w = C.Width
h = C.Height
x1 = Default(x1, 0)
y1 = Default(y1, 0)
x2 = Default(x2, x1+Default(wid, w))
y2 = Default(y2, y1+Default(hgt, h))
o = Default(outline_width, 0.0)
o = 0.1 * Round(10.0 * Default(outline_width, 0.0))
o2 = o / 2.0

C = (preclear==false) ? C.ConvertToY8
\ : BlankClip(C.ConvertToY8, color=$ffffff)

## arg validation v2:
x1 = Min(Max( 0 , x1 ), C.Width-2)
x2 = Min(Max(x1+1, x2 ), C.Width-1)
y1 = Min(Max( 0 , y1 ), C.Height-2)
y2 = Min(Max(y1+1, y2 ), C.Height-1)

## letterbox args:
llft = x1
ltop = y1
lrgt = Min(Max( 0, w-x2 ), C.Width-(llft+1))
lbot = Min(Max( 0, h-y2 ), C.Height-(ltop+1))

return (o>0.0)
\ ? C.BoxMask3(x1+Ceil(o2), y1+Ceil(o2), x2-Floor(o2), y2-Floor(o2)).Invert
\ .BoxMask3(x1-Floor(o2), y1-Floor(o2), x2+Ceil(o2), y2+Ceil(o2), preclear=false)
\ : C.Letterbox(ltop, lbot, llft, lrgt, color=$0).ColorYUV(levels="TV->PC")
}

#######################################
### overlay a clip or solid color using BoxMask3
##
## @ x1, y1 - left, top of rectangle mask
## @ x2, y2 - right, bottom of rectangle mask
## @ wid, hgt - width, height of rectangle mask; x2, y2 have priority
## @ outline_width - if zero, draw a filled rectangle; else draw outline
## @ over - if supplied, use for overlay fill, overriding "color"
## @ color - default black
## @ mode, opacity - cf. Overlay
## @ maskblur - mask blur
##
function BoxMaskOverlay(clip C,
\ int "x1", int "y1", int "x2", int "y2",
\ int "wid", int "hgt", int "outline_width",
\ clip "over", int "color",
\ string "mode", float "opacity", float "maskblur")
{
color = Default(color, $0)
mode = Default(mode, "blend")
opacity = Float(Min(Max(0, Default(opacity, 1)), 1))
a_blur = Default(maskblur, 0.0)

w = C.Width
h = C.Height
x1 = Default(x1, 0)
y1 = Default(y1, 0)
x2 = Default(x2, x1+Default(wid, w))
y2 = Default(y2, y1+Default(hgt, h))
o = Min(Default(outline_width, 0), w/8)

over = (IsClip(over) && over.Width==C.Width && over.Height==C.Height)
\ ? over.AssumeFPS(C).Loop
\ : BlankClip(C, color=color)

return (opacity<0.001) ? C
\ : C.Overlay(over,
\ mask=C.BoxMask3(x1, y1, x2, y2, outline_width=o, preclear=true)
\ .Blur(a_blur),
\ mode=mode,
\ opacity=opacity)
}

#######################################
## given Avisynth color, set its transparency
## @ a - 0.0 = transparent, 1.0 = opaque.
##
function transparent_color(float a, int color) {
a = 255 - Min(Max(0, Round(a * 256.0)), 255)
return BitOr(a*$1000000, BitAnd(color, $00ffffff))
}
__END__

StainlessS
5th September 2014, 14:02
Clever cloggs :)

devhercule
5th September 2014, 15:50
Yess it is very clever idea (Y).
I will try to implment it in my posted code.

Because in the progress bar there is not only trim segments, the rest of the video is also represented in the progress bar. so i must keep one color for selected segments with trim and another coloer for the rest of the video.

In the attached image: Red represent segments with trim, and YELLOW represents the rest of the video wich is not selected

devhercule
8th September 2014, 16:01
Hi, i could not integrate the code posted by raffriff42 in my code. Any help!!

raffriff42
10th September 2014, 05:52
OK, devhercule, here you are, sorry for the delay.
Some adjustments had to be made to work with long form videos. Hopefully I stamped out all the bugs :)A = FFAudioSource("video.mp4")
V = FFVideoSource("video.mp4")
AudioDub(V, A)

ShowFrameNumber(scroll=true,x=30,y=30)
ShowTime(x=80,y=50)
#return Last

## ProgressBar.avsi = previous post, starting from "function ProgressBar3"
Import(pathMisc + "ProgressBar.avsi")
## (or just copy & paste)

## begin user configurable section: ######################

## progress bar placement
global barhgt = 16 ## bar height (not tested at other heights)
global lftpad = 16 ## left pad
global rgtpad = 80 ## right pad
global botpad = 16 ## bottom pad

## colors etc
color_1 = color_khaki
color_2 = color_indianred
global outlclr = color_black ## outline color
global outlopc = 0.75 ## outline opacity (should be >= progress bar opacity)
global outlwid = 3 ## outline width (0 for no outline)
global progopc = 0.5 ## progress bar opacity
global txtclr = transparent_color(0.75, color_1) ## progress text color

## EDITING:
#Dissolve(Trim(0,200),
#\ Trim(1350,1700),
#\ Trim(13350,13700),
#\ Trim(99150,99400),
#\ Trim(150000,150300),
#\ Trim(170000,170300),
#\ Trim(190000,190300),
#\ Trim(192000,192278),
#\ 25)
## scenes must be assigned clip var's
C101 = Trim( 0, 200)
C102 = Trim( 1350, 1700)
C103 = Trim( 13350, 13700)
C104 = Trim( 99150, 99400)
C105 = Trim(150000, 150300)
C106 = Trim(170000, 170300)
C107 = Trim(190000, 190300)
C108 = Trim(192000, 192278)

## sanity check (StackHorizontal below does not like empty clips)
Assert(C107.FrameCount>1, "empty clip not allowed")
Assert(C108.FrameCount>1, "empty clip not allowed")

## - assign each scene a color
## preset color chooser: see
## http://avisynth.nl/index.php?title=Color_presets
## http://avisynth.nl/index.php?title=Color_presets&oldid=3660
##
wscale = Min(Max(1.0, Last.FrameCount/4096.0), Last.Width/2.0)
wmin = 2
global gF = StackHorizontal(
\ BlankClip(Last, length=1, pixel_type="RGB32",
\ height=barhgt+2*outlwid,
\ width=Max(wmin, Round(C101.FrameCount/wscale)),
\ color=color_1)
\ ,BlankClip(Last, length=1, pixel_type="RGB32",
\ height=barhgt+2*outlwid,
\ width=Max(wmin, Round(C102.FrameCount/wscale)),
\ color=color_2)
\ ,BlankClip(Last, length=1, pixel_type="RGB32",
\ height=barhgt+2*outlwid,
\ width=Max(wmin, Round(C103.FrameCount/wscale)),
\ color=color_1)
\ ,BlankClip(Last, length=1, pixel_type="RGB32",
\ height=barhgt+2*outlwid,
\ width=Max(wmin, Round(C104.FrameCount/wscale)),
\ color=color_2)
\ ,BlankClip(Last, length=1, pixel_type="RGB32",
\ height=barhgt+2*outlwid,
\ width=Max(wmin, Round(C105.FrameCount/wscale)),
\ color=color_1)
\ ,BlankClip(Last, length=1, pixel_type="RGB32",
\ height=barhgt+2*outlwid,
\ width=Max(wmin, Round(C106.FrameCount/wscale)),
\ color=color_2)
\ ,BlankClip(Last, length=1, pixel_type="RGB32",
\ height=barhgt+2*outlwid,
\ width=Max(wmin, Round(C107.FrameCount/wscale)),
\ color=color_1)
\ ,BlankClip(Last, length=1, pixel_type="RGB32",
\ height=barhgt+2*outlwid,
\ width=Max(wmin, Round(C108.FrameCount/wscale)),
\ color=color_2)
\ )
\ .AddBorders(0, Height-(botpad+outlwid), 0, botpad-outlwid)
\ .BilinearResize(Width-(lftpad+rgtpad), Height)
\ .AddBorders(lftpad, 0, rgtpad, 0)
\ .Loop(-1).Trim(0, -FrameCount).ConvertToYV12
## (you may want to save this still image and enhance in a paint program)
#return gF

## assembled timeline
Dissolve(C101, C102, C103, C104, C105, C106, C107, C108, 25)

## /end user configurable section ########################

## progress bar master rectangle
global ox1 = lftpad
global ox2 = Width - rgtpad
global oy1 = Height - (barhgt+botpad)
global oy2 = oy1 + barhgt

ProgressBar3

return Last

__END__

devhercule
28th November 2014, 11:47
I would like to clarify a small detail in my need.

if we consider a video of 1 hour, and the trim concerns 5 video segments

I want to have a bar with a color "A", in which, the five trim segments are colored with a color "B".

and not the five trim segments once with color "A" and other with a color "B"

The image in my first post illustrate that : red parts represent the trim segments and the yellow represent the rest of the original video which is not presented by trim.

example: trim(5,12)+trim(20,21)+trim(32,41) :

begin .. 4 : yellow
5 .. 12 : red
13 .. 19 : yellow
20 .. 21 : red
22 .. 31 : yellow
32 .. 41 : red
40 .. end : yellow

Thanks :-)

devhercule
2nd December 2014, 08:57
any help please
:thanks:

raffriff42
2nd December 2014, 21:01
I want to have a bar with a color "A", in which, the five trim segments are colored with a color "B"...
and not the five trim segments once with color "A" and other with a color "B"That is like saying "I don't want a black zebra with white stripes, I want a white one with black stripes." There is no real difference between the two.

As far as I can tell, I have satisfied your request. I don't know what else I can do.

devhercule
3rd December 2014, 10:26
I took your code and i tested it

i give you a use case here with difference between your code and what i need :

trim(5,12)+trim(20,26)+trim(32,41)

your code :

5 .. 12 : yellow
20 .. 26 : red
32 .. 41 : yellow

3 segments represent 100% of the progress bar

My need :

begin .. 4 : red
5 .. 12 : yellow
13 .. 19 : red
20 .. 26 : yellow
27 .. 31 : red
32 .. 41 : yellow
40 .. end : red

The whole video represents 100 % of the progress bar


Is it possible to do this? I do not know if I have well expressed my request :)

StainlessS
3rd December 2014, 12:19
You really should decide what you want before you post a thread and not keep moving the goal posts.

devhercule
3rd December 2014, 15:06
I'm sorry, I have problems in English :(
In my last post, I tried to well express my request

Thank you in advance :)