Degrafa Video Player, Part 1

, , , ,

I’m going to combine my earlier Degrafa skinning efforts with my more recent video work to create a Degrafa-skinned video player. In this post, I’ll build out all the components required for a video player control bar. And in Part 2, I’ll weld the control bar to an Open Video Player OvpNetStream backend.


To get started, I built out a simple button skin with a slight shine on the top half. I also added rounded corners to give the classic web 2.0 look-and-feel. There’s really not much to look at:

Flash is required. Get it here!
Play-Pause Button

I’m using a toggleable Button component as the base of my Play-Pause button. By leveraging Degrafa’s stateful skins, I simply change the visibility of the Play and Pause geometry depending on the skin’s state. Here’s a snippet from the states block of the skin:

    <State name="upSkin">
        <SetProperty target="{rect}" name="fill" value="{upFill}"/>
        <SetProperty target="{play}" name="visible" value="true"/>
    <State name="selectedUpSkin">
        <SetProperty target="{rect}" name="fill" value="{upFill}"/>
        <SetProperty target="{play}" name="visible" value="false"/>

Additionally, the play arrow and pause bars are dynamically sized based on the button height, so they readily scale to any size. The result:

Flash is required. Get it here!

Getting total control over a Slider skin is not easy in Flex 3. There are two issue that I find quite annoying: the thumb size is hard-coded into the class and the highlight skin is offset from the track. Fortunately, the web is full of workarounds for the thumb size issue, but for this skin I only needed to hard-code an offset (+6,+6) to bring the thumb’s origin to (0,0) and make all my geometry line up correctly. Similarly, I added a 1 pixel offset to the highlight skin to bring its origin to (0,0) to match the track. The result:

Flash is required. Get it here!
Volume Slider

For consistency, the Volume slider re-uses the Scrubber’s thumb skin, but the track and highlight are wedges (Polygon‘s in Degrafa). The only clever piece of code is the highlight skin’s overridden updateDisplayList() function:

override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
    super.updateDisplayList(unscaledWidth, unscaledHeight);
    awidth = unscaledWidth;
    aheight = unscaledHeight;
    if (this.hasOwnProperty('parent') &&
             this.parent.hasOwnProperty('parent') &&
             this.parent.parent.hasOwnProperty('width') &&
             this.parent.parent.width > 0) {
        _ratio = awidth / this.parent.parent.width;
    } else {
        _ratio = 0.00001;

In order to correctly draw the highlight wedge, we first need to know the dimensions of the track. For simplicity, the Volume track height is hard-coded in both the track skin and highlight skin, but the width of the track is variable. In this case, the width of the track is the same as the width of the HSlider component itself. So in the updateDisplayList() code above, the track width is found and used to compute the ratio of widths. This ratio is later used to draw the highlight geometry. The end result:

Flash is required. Get it here!
The Full Control Bar

Just displaying all the components side-by-side gives us the beginnings of a video player control bar:

Flash is required. Get it here!

Not too shabby. In Part 2, I’ll assemble the final video player frontend including the pretty control bar components above, and weld it to an OvpNetStream-powered backend.






I am having trouble offsetting the highlight skin on the slider. Could you elaborate on how you hard-coded it above?




Nothing magic going on, I just set the y of the highlight skin’s geometry and adjusted it up and down until things looked good. In my case, the track was 6px tall and set at y = -3 and the highlight was 4px tall and also needed to be at y = -3 for things to line up. So I needed an extra -1 offset from what I expected. I believe this extra offset is buried somewhere deep inside Flex and is due to how it draws and skins the HSlider component. Skinning with Degrafa is precise enough to expose the issue.

Everything is view source enabled, so just right-click and see what I did.

© 2021