Flex 3 Cookbook: Chapter 8, Images, Bitmaps, Videos, Sounds
Pages: 1, 2, 3, 4, 5, 6, 7, 8

Using the mx.controls.VideoDisplay simplifies working with a cue point object quite substantially. When using the CuePointEvent dispatched by the CuePointManager, unlike in the preceding case, the received event possesses only three properties: cuePointTime, cuePointName, and cuePointType. If you need more or different information from the cue point, you can write a custom class to return the cue point data and set it to the cuePointManager property of the VideoDisplay object. The complete code listing is shown here:

<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="400" height="300">
    <mx:Script>
        <![CDATA[
            import mx.events.CuePointEvent;

            private function onCuePoint(event:CuePointEvent):void {
                trace(event.cuePointName+" "+event.cuePointTime+" 
"+event.cuePointType+" ");
            }

        ]]>
    </mx:Script>
    <mx:VideoDisplay id="vid" cuePoint="onCuePoint(event)"/>
</mx:VBox>

Section 8.14: Create a Video Scrubber

Problem

You need to create a control that a user can use to scrub through a video as it plays.

Solution

Create a draggable Sprite object and listen for any DragEvent events dispatched from it. In the event handler for the DragEvent, set the amount to seek forward or backward in the NetStream that is streaming the video to the Video object.

Discussion

You can use any draggable display object to set the new position at which the video should be played. In this example, the seek method of the NetStream begins playback from the specified point in seconds from the beginning of the video:

ns.seek((playhead.x/timeline.width) * length);

To determine which second in the video that the user meant to seek, divide the position of the dragged Sprite by the width of the timeline area and multiply by the length of the video. The NetStream will take care of locating the appropriate frames in the video and restarting the streaming from that point.

    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.events.NetStatusEvent;
    import flash.media.Video;
    import flash.net.NetConnection;
    import flash.net.NetStream;

    import mx.core.UIComponent;

    public class Scrubber extends UIComponent
    {

        private var playhead:Sprite;
        private var timeline:Sprite;
        private var ns:NetStream;
        private var nc:NetConnection;
        private var obj:Object = {};
        private var length:int;
        private var vid:Video;

        public function Scrubber () {
            super();
            playhead = new Sprite();
            addChild(playhead);
            playhead.graphics.beginFill(0x0000ff, 1);
            playhead.graphics.drawCircle(0, 0, 5);
            playhead.graphics.endFill();
            playhead.addEventListener(MouseEvent.MOUSE_DOWN, startSeek);
            timeline = new Sprite();
            timeline.graphics.beginFill(0xcccccc, 1);
            timeline.graphics.drawRect(0, 0, 200, 10);
            timeline.graphics.endFill();
            addChild(timeline);
            timeline.addChild(playhead);
            playhead.y = 4;
            vid = new Video();
            addChild(vid);
            vid.y = 100;

            nc = new NetConnection();
            nc.addEventListener(NetStatusEvent.NET_STATUS, netStatus);
            nc.connect(null);
        }

        private function netStatus(event:NetStatusEvent):void {
            obj.onMetaData = onMetaData;
            ns = new NetStream(nc);
            ns.client = obj;
            vid.attachNetStream(ns);
            ns.play("http://localhost:3001/test.flv");
        }

        private function onMetaData(obj:Object):void {
            length = obj.duration;
            trace(length);
        }

        private function startSeek(mouseEvent:MouseEvent):void {
            playhead.startDrag(false, timeline.getBounds(this));
            addEventListener(MouseEvent.MOUSE_MOVE, seek);
            playhead.addEventListener(MouseEvent.ROLL_OUT, endSeek);
            playhead.addEventListener(MouseEvent.MOUSE_UP, endSeek);
        }

        private function seek(mouseEvent:MouseEvent):void {
            ns.seek((playhead.x/timeline.width) * length);
        }

        private function endSeek(mouseEvent:MouseEvent):void {
            removeEventListener(MouseEvent.MOUSE_MOVE, seek);
            playhead.stopDrag();
        }

This excerpt is from Flex 3 Cookbook. This highly practical book contains more than 300 proven recipes for developing interactive Rich Internet Applications and Web 2.0 sites. You'll find everything from Flex basics and working with menus and controls, to methods for compiling, deploying, and configuring Flex applications. Each recipe features a discussion of how and why it works, and many of them offer sample code that you can put to use immediately.

buy button

Section 8.15: Read ID3 Data from an MP3 File

Problem

You want to read ID3 data from an MP3 file.

Solution

Use the Event.ID3 method that the Sound class will dispatch when the ID3 data has been parsed.

Discussion

The Sound class dispatches an event when the ID3 data has been parsed from a loaded MP3 file. That data is then stored as an ID3Info object, which defines variables to access all the properties written into the initial bytes of the MP3:

private var sound:Sound;

public function _8_16()
{
    sound = new Sound();
    sound.addEventListener(Event.ID3, onID3InfoReceived);
    sound.load(new URLRequest("../assets/1.mp3"));
}

private function onID3InfoReceived(event:Event):void
{
    var id3:ID3Info = event.target.id3;
    for (var propName:String in id3)
    {
        trace(propName + " = " + id3[propName]);
    }
}

The information from a song I was listening to while I wrote this recipe appears like this:

TCON = Alternative & Punk
TIT2 = The Pink Batman
TRCK = 2/9
TPE1 = Dan Deacon
TALB = Spiderman Of The Rings
TCOM = Dan Deacon

The ID3 info of an MP3 file is simply a grouping of bytes in a certain order that are read and turned into strings or integers. MP3 is the only file format that the Flash Player supports out of the box. Developer Benjamin Dobler of RichApps (www.richapps.de), however, has done some exceptional work with the WAV format. Getting the WAV file to play back in the Flash Player is slightly more tricky. If you're interested, go to Benjamin's site and take a look. If you want to parse the data from a WAV file, it looks like this:

public var bytes:ByteArray;
public var chunkId:String;
public var chunkSize:int;
public var chunkFormat:String;
public var subchunk1Id:String;
public var subchunk1Size;
public var audioFormat;
public var channels;
public var sampleRate;
public var bytesPersecond;
public var blockAlign;
public var bitsPerSample;
public var dataChunkSignature:String;
public var dataChunkLength;

public function read(bytes:ByteArray):void{
    this.bytes = bytes;
    // Read Header
    bytes.endian = "littleEndian";
    chunkId = bytes.readMultiByte(4,"utf"); //RIFF
    chunkSize = bytes.readUnsignedInt();
    chunkFormat = bytes.readMultiByte(4,"utf"); //WAVE
    subchunk1Id = bytes.readMultiByte(4,"iso-8859-1"); // 12 Header Signature
    subchunk1Size = bytes.readInt(); // 16 4 <fmt length>
    audioFormat = bytes.readShort(); // 20 2 <format tag> sample
    channels = bytes.readShort(); // 22     2 <channels> 1 = mono, 2 = stereo
    sampleRate = bytes.readUnsignedInt();// 24     4 <sample rate>
    bytesPersecond = bytes.readUnsignedInt(); //28 4 <bytes/second>     Sample-Rate *
Block-Align
    blockAlign = bytes.readShort(); // 32 2 <block align> channel * bits/sample / 8
    bitsPerSample = bytes.readUnsignedShort(); //34 2 <bits/sample> 8, 16 or 24
    dataChunkSignature = bytes.readMultiByte(4,"iso-8859-1"); //RIFF
    dataChunkLength = bytes.readInt();
}

If you want to read the header info from an AU file, it would look like this:

public var bytes:ByteArray;
public var magicId;
public var header;
public var datasize;
public var channels;
public var comment;
public var sampleRate;
public var encodingInfo;

public function read(bytes:ByteArray):void{
    this.bytes = bytes;
    // Read Header
    bytes.endian = "bigEndian";
    magicId = bytes.readUnsignedInt();
    header = bytes.readInt();
    datasize = bytes.readUnsignedInt();
    encodingInfo = bytes.readUnsignedInt();
    sampleRate = bytes.readUnsignedInt();
    channels = bytes.readInt();
    comment = bytes.readMultiByte(uint(header)-24, "utf");
}

MP3 files may be the easiest format from which to read data, but they are certainly not the only format from which you can read.

Section 8.16: Display a Custom Loader while Loading Images

Problem

You want to display custom animation while an image loads.

Solution

Create a custom graphic and listen for the ProgressEvent.PROGRESS event from the Image object loading the image. Then draw into the graphic by using the bytesLoaded and bytesTotal properties.

Pages: 1, 2, 3, 4, 5, 6, 7, 8

Next Pagearrow