Previous Page
Next Page

Recipe 16.12. Scrubbing Video

Problem

You want to scrub the playback of video (move the playhead forward or backward while the video plays).

Solution

Use a slider controller in conjunction with the seek( ) method.

Discussion

A common way to control video playback is to "scrub" the video using a slider controller. You can implement a scrub controller by building a slider that uses the seek( ) method to control a NetStream object.

The following sample code illustrates one way to write such a controller:

package com.oreilly.as3cb.components {

    import flash.display.Sprite;
    import flash.net.NetStream;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Rectangle;

    public class VideoScrubber extends Sprite {
        
        private var _thumb:Sprite;
        private var _track:Sprite;
        private var _stream:NetStream;
        private var _duration:Number;
        private var _scrubbing:Boolean;
        
        public function VideoScrubber(stream:NetStream, duration:Number) {
            _stream = stream;
            _duration = duration;
            _track = new Sprite(  );
            _track.graphics.lineStyle(  );
            _track.graphics.drawRect(0, -2.5, 100, 5);
            addChild(_track);
            _thumb = new Sprite(  );
            _thumb.graphics.lineStyle(  );
            _thumb.graphics.beginFill(0xFFFFFF);
            _thumb.graphics.drawRect(-5, -5, 10, 10);
            _thumb.graphics.endFill(  );
            addChild(_thumb);
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
            _thumb.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            _thumb.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
        }
        
        private function onMouseDown(event:MouseEvent):void {
            _scrubbing = true;
            var rectangle:Rectangle = new Rectangle(0, 0, _track.width, 0);
            _thumb.startDrag(false, rectangle);
        }
        
        private function onMouseUp(event:MouseEvent):void {
            _scrubbing = false;
            _thumb.stopDrag(  );
        }
        
        private function onEnterFrame(event:Event):void {
            if(_duration > 0) {
                if(_scrubbing) {
                    _stream.seek(_duration * _thumb.x / _track.width);
                }
                else {
                    _thumb.x = _stream.time / _duration * _track.width;
                }
            }
        }
        
    }
}

In the preceding code example, the constructor accepts a NetStream parameter and a parameter specifying the duration of the video. The constructor then creates the elements for a slider control. When the user clicks on the slider, the code calls the startDrag( ) method and sets _scrubbing to true. While _scrubbing is true, the code calls the seek( ) method of the stream, passing it the playback time value corresponding to the placement of the slider control.

Note that the preceding example does not detect mouseUp events because it's possible that the mouse could be outside the slider control when the user releases the button. The solution to this issue is rather complex (hence the reason it's not discussed in this recipe). The solution is detailed in Recipe 6.9.


See Also

Recipe 6.9


Previous Page
Next Page
Converted from CHM to HTML with chm2web Pro 2.85 (unicode)