<?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;
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
{
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)
{
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)
{
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;
}
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 (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>