<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication title="Video Inspector" xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="800" height="600" backgroundColor="#006699" initialize="InitControls();" fontFamily="Tahoma, Geneva" fontSize="12" viewSourceURL="srcview/index.html">
<mx:Script>
<![CDATA[
    import mx.collections.ArrayCollection;
//    import mx.events.MetadataEvent;

    private var vid : Video;
    private var ns : NetStream;
    private var nc : NetConnection;
    private var currfile : File;
    private var hasmetadata : Boolean;
    
    private function InitControls() : void
    {
        this.addEventListener("nativeDragEnter", DragEntered, false, 0, true);
        this.addEventListener("nativeDragDrop", DragDrop, false, 0, true);
    }
    
    private function VidControlClicked() : void
    {
        // toggle the Play/Pause button
        if (ns != null)
        {
            if (cmdControl.label == "Pause")
            {
                ns.pause();
                cmdControl.label = "Play";
            }
            else
            {
                ns.resume();
                cmdControl.label = "Pause";
            }
        }
    }
    
    public function onMetaData(metadata : Object) : void
    {
        var h : int;
        var w : int;
        var framerate : Number;
        var duration : int;
        var videocodec : String;
        var audiocodec : String;
        var outstr : String;
        
        hasmetadata = true;
        
        h = 0;
        w = 0;
        framerate = 0;
        duration = 0;
        videocodec = "No Video Track Found";
        audiocodec = "No Audio Track Found";

        outstr = "";
        
        trace("GOT OUR METADATA...", metadata);
        
        for (var itmx : Object in metadata)
        {
            switch (itmx)
            {
                case "creator":
                    if (String(metadata[itmx]).indexOf("YouTube") >= 0)
                    {
                        outstr += "This is a video pulled from YouTube. "; 
                    }
                    break;
                    
                case "height":
                    h = int(metadata[itmx]);
                    break;
                    
                case "width":
                    w = int(metadata[itmx]);
                    break;

                case "framerate":
                    framerate = Math.round(Number(metadata[itmx]));
                    break;

                case "duration":
                    duration = int(metadata[itmx]);
                    break;

                case "videocodecid":
                    videocodec = ParseVideoCodec(metadata[itmx]);        
                    break;

                case "audiocodecid":
                    audiocodec = ParseAudioCodec(metadata[itmx]);
                    break;

            }

            trace(itmx, metadata[itmx]);
        }
        
        if (h <= 0 || w <= 0)
        {
            // invalid height or width
            outstr += "No height or width was found for this video. ";
        }
        else
        {
            vid.width = w;
            vid.height = h;
            canHolder.width = w;
            canHolder.height = h;
            outstr += "Video dimensions: " + String(w) + "x" + String(h) + ". "; 
        }
        
        if (duration <= 0)
        {
            // missing duration... won't be able to use seeking 
            outstr += "Duration is missing. You won't be able to seek within this video.\n";    
        }
        else
        {
            outstr += "Duration is " + String(duration) + " seconds.\n";
        }

        if (videocodec == "No Video Track Found")
        {
            if (currfile.extension.toLowerCase() == "flv")
            {
                outstr += "This is a poorly encoded FLV video with no inspectable video track.\n";
            }
            else
            {
                outstr += "No playable video track was found for this video.\n";
            }    
        }
        else
        {
            outstr += "Video Codec is: " + videocodec + ".\n";
        }
        
        if (audiocodec == "No Audio Track Found")
        {
            if (currfile.extension.toLowerCase() == "flv")
            {
                outstr += "This is poorly encoded FLV video with no inspectable audio track.\n";
            }
            else
            {
                outstr += "No playable audio track was found for this video. ";
            }   
        }
        else
        {
            outstr += "Audio Codec is: " + audiocodec + ". ";
        }
        
        txtStatus.text = outstr;
    }
 
 
    private function ParseVideoCodec(codec : String) : String
    {
        var outstr : String;
        
        switch (codec)
        {
            case "2":
                outstr = "Sorenson H.263";
                break;
                
            case "3":
                outstr = "Screen video";
                break;
                
            case "4":
                outstr = "VP6 video";
                break;
                
            case "5":
                outstr = "VP6 video with alpha channel";
                break;
                
            case "avc1":
                outstr = "H.264";
                break;
                
            default:
                outstr = "Other Video Codec: " + codec;
                break;
        }
        
        return outstr;
    }

    private function ParseAudioCodec(codec : String) : String
    {
        var outstr : String;
        
        switch (codec)
        {
            case "0":
                outstr = "uncompressed";
                break;

            case "1":
                outstr = "ADPCM";
                break;

            case "2":
                outstr = "mp3 -- FLV";
                break;

            case "5":
                outstr = "Nellymoser 8kHz mono";
                break;

            case "6":
                outstr = "Nellymoser";
                break;

            case "mp4a":
                outstr = "H.264 -- AAC";
                break;

            case ".mp3":
                outstr = "H.264 -- MP3";
                break;

        }
     
        return outstr;
    }

/*
Image tracks encoded in JPEG, GIF and PNG are accessible as byte arrays through a new callback 'onImageData'. 
You can simply take that byte array and use the Loader class to display the images. 
*/        
    private function DragEntered(event : flash.events.NativeDragEvent) : void
    {
        if (event.clipboard.hasFormat(ClipboardFormats.FILE_LIST_FORMAT))
        {
            NativeDragManager.acceptDragDrop(this);
            trace("asset window drag acceptable");
        }
    }
    
    private function DragDrop(event : flash.events.NativeDragEvent) : void
    {
        var files : ArrayCollection;

        if (event.clipboard.hasFormat(ClipboardFormats.FILE_LIST_FORMAT))
        {
            files = new ArrayCollection(event.clipboard.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array);

            if (files.length > 1)
            {
                txtStatus.text = "I can only examine one file at a time. Please try again.";
                return;
            }

            currfile = files[0];
            
            if (ns != null)
            {
                ns.close();

                if (vid != null)
                {
                    vid.clear();
                    canHolder.rawChildren.removeChild(vid);
                }
            }
            
            nc = new NetConnection();
            nc.connect(null);
            ns = new NetStream(nc);
            ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, AsyncError);
            ns.addEventListener(IOErrorEvent.IO_ERROR, IOError);
            ns.addEventListener(NetStatusEvent.NET_STATUS, NetStatus);
            ns.addEventListener(StatusEvent.STATUS, StatusEventHandler);
            ns.client = this;
            
            vid = new Video();
            vid.attachNetStream(ns);
            ns.play(currfile.url);
            canHolder.rawChildren.addChild(vid);
            
            txtStatus.text = "";
            cmdControl.label = "Pause";
            hasmetadata = false;
        }
    }

    private function StatusEventHandler(event : flash.events.StatusEvent) : void
    {
        trace("STATUS EVENT: ", event.code, event.currentTarget);
    }
    
    private function NetStatus(event : NetStatusEvent) : void
    {
        trace("NETSTATUS EVENT:", event.info.code, event.info.level, event.currentTarget);

        switch (event.info.code)
        {
            case "NetStream.Play.NoSupportedTrackFound":
                txtStatus.text = "This is a video file, but it was not encoded with H.264 so it will not play in Flash.";
                ns.close();
                ns = null;
                break;
                
            case "NetStream.Play.FileStructureInvalid":
                txtStatus.text = "This does not seem to be a video file but rather a file of some other type.";
                ns.close();
                ns = null;
                break;
                
            case "NetStream.Buffer.Full":
                if (!hasmetadata)
                {
                    // if meta data doesn't come in by now, we aren't getting it.

                    if (currfile.extension.toLowerCase() == "flv")
                    {
                        txtStatus.text = "This must be a really old FLV file because it has no MetaData at all.\nYou won't be able to seek within this video or tell the duration.";
                    }
                }
                break;
        }
    }

    private function IOError(event : IOErrorEvent) : void
    {
        trace("IOERROR: ", event.errorID, event.currentTarget, event.text);
    }
    
    private function AsyncError(event : AsyncErrorEvent) : void
    {
        trace("ASYNC ERROR: ", event.error.message, event.error.errorID, event.currentTarget);
    }
]]>
</mx:Script>
    <mx:Text id="txtStatus" x="10" y="10" text="Drag a file on to this window to inspect it..." color="#FFFFFF" fontWeight="bold" width="700" height="62"/>
    <mx:Canvas id="canHolder" x="10" y="80" />
    <mx:Button id="cmdControl" x="728" y="25" label="Pause" click="VidControlClicked();"/>
        
</mx:WindowedApplication>