Scrubbing an FLV using the VideoDisplay control and a slider
In yet *another* post about the VideoDisplay control, this time we look at formatting playback times using the DateFormatter class/tag, creating a basic scrubber using an HSlider control, and applying a mildly annoying Zoom effect to the video.
Also, we tweak the slider control (or more accurately HSlider) and prevent users from clicking on the slider track (thanks to the allowTrackClick property, we set the liveDragging property to false to make sure we arent needlessly seeking around the video every time the slider thumb moves, and finally we invert the thumb arrow for no other reason than I didn’t know you could do that so easily.
Oh, and I also created a faux looping video by using the autoRewind property, and calling the play() method in the rewind event handler.
Full code after the jump.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" verticalAlign="top" backgroundColor="white">
<mx:Script>
<![CDATA[
private function formatTime(item:Date):String {
return dateFormatter.format(item);
}
private function videoDisplay_playheadUpdate():void {
/* If playhead time is 0, set to 100ms so the DateFormatter doesnt return an empty string. */
var pT:Number = videoDisplay.playheadTime || 0.1;
var tT:Number = videoDisplay.totalTime;
/* Convert playheadTime and totalTime from seconds to milliseconds and create new Date objects. */
var pTimeMS:Date = new Date(pT * 1000);
var tTimeMS:Date = new Date(tT * 1000);
timeLabel.text = formatTime(pTimeMS) + " / " + formatTime(tTimeMS);
}
private function slider_thumbPress():void {
videoDisplay.pause();
}
private function slider_thumbRelease():void {
videoDisplay.playheadTime = slider.value;
videoDisplay.play();
}
private function videoDisplay_ready():void {
videoDisplay.visible = true;
controlBar.visible = true;
}
]]>
</mx:Script>
<!-- Only show minutes and seconds. -->
<mx:DateFormatter id="dateFormatter" formatString="NN:SS" />
<mx:Zoom id="zoom" />
<mx:Panel title="{videoDisplay.source.split('/').pop()} ({videoDisplay.state})">
<mx:VideoDisplay id="videoDisplay" visible="false" showEffect="{zoom}"
playheadUpdate="videoDisplay_playheadUpdate()"
ready="videoDisplay_ready()"
rewind="videoDisplay.play()"
source="http://www.helpexamples.com/flash/video/cuepoints.flv" />
<mx:ControlBar id="controlBar" visible="false">
<mx:HSlider id="slider" width="100%"
allowTrackClick="false"
invertThumbDirection="true"
liveDragging="false"
maximum="{videoDisplay.totalTime}"
minimum="0"
thumbPress="slider_thumbPress()"
thumbRelease="slider_thumbRelease()"
tickInterval="1"
value="{videoDisplay.playheadTime}" />
<mx:Label id="timeLabel" textAlign="right" />
</mx:ControlBar>
</mx:Panel>
</mx:Application>
View source enabled in the following example.
Peter deHaan
Peter deHaan currently works for Adobe on the Flex SDK QA team. While not working on Flex, Flash, and ColdFusion applications, Peter enjoys making up bios and writing in 3rd person. Peter's rarely updated blog can be found at blogs.adobe.com/pdehaan/, actionscriptexamples.com, airexamples.com, and coldfusionexamples.com.
-
Add Widgets (Content Sidebar)
This is your Content Sidebar. Edit this content that appears here in the widgets panel by adding or removing widgets in the Content Sidebar area.
13 Responses to Scrubbing an FLV using the VideoDisplay control and a slider
-
Categories
- Accordion
- AccordionHeader
- ActionScript
- AddChild
- AdvancedDataGrid
- Alert
- alpha
- Animate
- AnimateProperties
- Application
- Application (Spark)
- ArrayCollection
- BarChart
- baseColor
- beta
- beta1
- beta2
- Bitmap
- Bitmap/BitmapData
- BitmapData
- BitmapFill
- BitmapFill (Spark)
- BitmapGraphic
- BitmapImage
- BitmapImage (Spark)
- BitmapImageResizeMode
- Border (Spark)
- BorderContainer (Spark)
- Box
- BuildInfo
- Button
- Button (Spark)
- ButtonBar
- ButtonBar (Spark)
- ByteArray
- Camera
- Charting
- CheckBox
- CheckBox (Spark)
- ClassFactory
- CollectionEvent
- Color
- ColorPicker
- ColorUtil
- ComboBox
- ComboBoxArrowSkin
- Compiler
- Component
- Component (Spark)
- Configuration
- Container
- ContextMenu
- ContextMenuEvent
- ContextMenuItem
- CSSCondition
- CSSSelector
- CSSStyleDeclaration
- CurrencyFormatter
- CursorManager
- Data Binding
- DataGrid
- DataGrid (Spark)
- DataGridColumn
- Date
- DateBase
- DateChooser
- DateField
- DateFormatter
- Debugging
- DefaultComplexItemRenderer
- DefaultTileListEffect
- DropDownList
- DropDownList (Spark)
- DropDownListButtonSkin
- DropDownListSkin
- DropShadowFilter
- E4X
- Effects
- Ellipse
- EmailValidator
- Embed
- Event
- Fade
- FileFilter
- FileReference
- fill
- Filters
- Flash
- Flash Integration
- FlashVars
- Flex 3 SDK
- Flex Builder
- Flex Builder 3
- Flex SDK
- Flex4
- FLVPlayback
- FocusManager
- FontLookup
- Fonts
- Form
- Form (Spark)
- FormHeading (Spark)
- FormItem
- FormItem (Spark)
- Forms
- FTETextField (Spark)
- FullScreen
- FullScreenEvent
- FxAnimateColor
- FxButtonBar
- FxCheckBox
- FXG
- FxHScrollBar
- FxHSlider
- FxList
- FxNumericStepper
- FxRadioButton
- FxRotate3D
- FxScroller
- FxTextArea
- FxTextInput
- FxToggleButton
- FxVScrollBar
- FxVSlider
- getStyleDeclaration()
- GradientEntry
- Graphic (Spark)
- HBox
- HDividedBox
- HGroup (Spark)
- HorizontalLayout
- HorizontalList
- HSBColor (Spark)
- HScrollBar (Spark)
- HSlider
- HSlider (Spark)
- HTML template
- ID3Info
- Image
- Image (Spark)
- ImageSnapshot
- itemRenderer
- JointStyle
- Label
- Label (Spark)
- Legend
- LegendItem
- LigatureLevel
- Line
- LinearGradientStroke
- LineScaleMode
- LinkBar
- LinkButton
- List
- List (Spark)
- Menu
- MenuBar
- Metadata
- MetadataEvent
- Model
- Mouse
- MouseCursor
- MouseEvent
- Move
- Namespace
- NavigatorContent (Spark)
- needsSWF
- NetConnection
- NetStream
- Nightly Builds
- NumberBaseRoundType
- NumberFormatter
- NumberValidator
- NumericCompare
- NumericStepper
- NumericStepper (Spark)
- ObjectProxy
- ObjectUtil
- paddingLeft
- paddingRight
- Panel
- Panel (Spark)
- Parallel
- Path
- PieChart
- PieSeries
- PieSeriesItem
- PopUpAnchor (Spark)
- PopUpButton
- PopUpManager
- ProgrammaticSkin
- ProgressBar
- PropertyChangeEvent
- QName
- RadialGradient
- RadioButton
- RadioButton (Spark)
- RadioButtonGroup
- RadioButtonGroup (Spark)
- Rect
- RegExp
- Regular Expressions
- Repeater
- RichEditableText
- RichText
- RichText (Spark)
- RichTextEditor
- Rotate
- Rotate3D (Spark)
- Scroller (Spark)
- Sequence
- setStyle()
- SimpleText
- SimpleText (Spark)
- skinClass
- Slider
- SliderEvent
- SolidColor
- SolidColorStroke
- Sort
- SortField
- Sound
- SoundEffect
- Spinner (Spark)
- SpriteVisualElement (Spark)
- StageDisplayState
- States
- StringUtil
- StringValidator
- StyleManager
- Styles
- SWFLoader
- SWFObject
- System
- SystemManager
- TabBar
- TabBar (Spark)
- TabNavigator
- TabStopFormat
- Text
- Text Layout Framework (TLF)
- TextArea
- TextArea (Spark)
- TextBox
- TextConverter
- TextEvent
- TextFlow
- TextFlowUtil
- TextFormat
- TextGraphic
- TextInput
- TextInput (Spark)
- TextLayoutFormat
- TextView
- Themes
- TileLayout
- TileList
- TileOrientation
- Timer
- TitleWindow
- TitleWindow (Spark)
- TLF
- ToggleButton (Spark)
- ToggleButtonBar
- ToolTip
- Transition
- Tree
- TruncationOptions
- UIComponent
- UIFTETextField
- Updater
- URLLoader
- URLRequest
- URLUtil
- URLVariables
- ValidationResultEvent
- Validator
- Validators
- VBox
- VDividedBox
- Vector
- VerticalLayout
- VerticalLayout (Spark)
- VGroup (Spark)
- Video
- VideoDisplay
- VideoElement
- VideoElement (Spark)
- VideoEvent
- VideoPlayer (Spark)
- VideoPlayerScrubBar
- ViewStack
- VScrollBar (Spark)
- VSlider
- VSlider (Spark)
- XML
- XMLList
- XMLListCollection
- ZipCodeValidator
- ZipCodeValidatorDomainType
- Zoom
-
Articles
- December 2010
- November 2010
- October 2010
- September 2010
- August 2010
- July 2010
- June 2010
- May 2010
- April 2010
- March 2010
- February 2010
- January 2010
- December 2009
- November 2009
- October 2009
- September 2009
- August 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
-
Meta


Sorry for the audio, it would appear my speakers were muted while I was building this. I’ll mute the audio stream in the FLV and republish the SWF when I get home.
Update @ 8:23pm :: Fixed, volume muted.
Player is great! Quick question. How hard do you think it would be to capture the playhead time into an xml file for captions?
Thanks!
SMackhead,
It shouldn’t be hard at all. The only trick would be you would need to send the data to a server-side script to write out the XML data to a file remotely. Due to security reasons, Flash Player cannot create files on a user’s machine (unless you’re creating an Adobe AIR project).
Peter
Nice player!
One question, though. What if I actually WANT “liveDragging”, meaning that I could scrub through the vid getting an update on what is to be seen while I´m dragging the thumb?
I thought adding something like this should do the trick… but it doesn’t :(
private function slider_thumbPress():void { videoDisplay.pause(); } private function slider_thumbDrag():void { videoDisplay.playheadTime = slider.value; } private function slider_thumbRelease():void { videoDisplay.play(); }and
Any Ideas? The thumb just gets stuck at the first half of the flv and doesn’t move any more while the flv stops.
SaltamonteZ,
Are you sure the entire video has loaded? I assume you can’t scrub past a point in a video if it hasn’t loaded yet.
Peter
Hey peterd ,
It has defects?
I slidered the thumb on right, and I saw the title have updated to “cuepoints.flv(seeking)”. but the video doesn’t play anymore, it was stuck there.
Any suggestion?
Cheers
Hi peter,
Thanx for all the examples, great work!
Regarding the scrubber, I noticed that after the slider_thumbRelease the slider jumps for a second back to the original slider_thumbPress position. How can this be avoided?
…when I do a ‘trace(videoDisplay.playheadTime) after videoDisplay.playheadTime = slider.value in the slider_thumbRelease method, I get the time of the original location and NOT the new location.
thanks again
Hi Sam,
the strange slider movement could be avoided.
Put the following line
as last line into the function:
private function videoDisplay_playheadUpdate():void {and remove (delete)
value="{videoDisplay.playheadTime}"from the attributes of HSlider slider in the MXML part.
Thats it.
Btw.: Thank you Peter for this nice example.
Hi Peter,
Thanks for the examples. Just playing around with it..
The video time display is incorrect though. Since Flex creates new dates in the local time zone, if your timezone is not GMT, you will get incorrect time display. (It shows 30:01 for me instead of 00:01 since I am in GMT+530).
Here’s a fix for that:
In the
videoDisplay_playheadUpdate()function:HTH.
:Nirav
Nice example. I would like to make the slider move more smoothly as the video plays. Messing with the playheadUpdateInterval never gets it right. Does anyone know of any tricks people have done to make the scrollbar smoother?
Hey petered this is a real nice example.
I figured Out how to make the slider show the correct time (min, sec) when forwarding or rewinding the videos.
Here is what you need to do.
Create a function to handle the conversion.
private function timeConversion(item:Object):String{
var pT:Number = item.valueOf() || 0.1;
var pTimeMS:Date = new Date(pT * 1000);
return formatTime(pTimeMS);
}
add the following line to your HSlider component.
dataTipFormatFunction=”timeConversion”
Hope it Helps.
Hello please urgent im playing 1:33:50 mins video it shows 12:33:50 for me instead of 00:00:01 since I am in GMT+530…
Please Help me…
Hi Guys!
Great post I must say.
I was just wondering if there is a way to increase granularity on Ms VideoDisplay control? Let’s say I want live dragging but I want it to update its playhead time in milliseconds instead of seconds? It passe 30 frames in 1 second which is not really live dragging :)
Thanks.