AS3.0: boosting .flv volume by hacking the NetStream object out of FLVPlayback

Use Case
You’re handed an AS3.0 project that’s been built by someone else and that developer used the FLVPlayback component to play multiple videos. All’s worked OK in the past, but suddenly, you get 1 video, already in .FLV format and it’s volume is way lower than all the rest of the videos. The client’s going to notice, everybody knows this much. When you ask the logical question: why not just send the file back to the video editor and have her boost the volume in After Effects or Audacity? You’re told no, it’s too late, the video budget’s been spent already and nobody caught the problem during video assets QA.

Lucky for them, you can use AS3.0 to boost the volume of a video with low sound quality.

This is easier to do with custom video players because by default, the FLVPlayback component doesn’t give you any sort of getNetStream() method. Thanks to a good Developer at Firefly there’s a way to grab the NetStream from FLVPlaback. Once we have it, you combine it with a SoundTransform instance and you’re good to go.

package com.yourpackage.path
{
	//...
	import flash.media.SoundTransform;	
	import flash.net.NetStream;
    import flash.display.Sprite; 
    import fl.video.FLVPlaback; 

	public class MyPlayer extends Sprite 
	{
		private var videoSound:SoundTransform = new SoundTransform();
		private var ns:NetStream;
        private var vidPlayer:FLVPlaback = new FLVPlaback();
		//...
	
		public MyPlayer()
		{
			//...
			//used for NetStream capture
			idPlayer.addEventListener(VideoEvent.STATE_CHANGE, onVideoStateChange);
			//...
		
			boostVolume();
		}
	
		// grab the NetStream using the evt.vp index
		public function onVideoStateChange(e:VideoEvent)
		{
			ns = vidPlayer.getVideoPlayer(e.vp).netStream;
		}
	
		public function boostVolume():void
		{			
			videoSound.volume = 2.4;
			ns.soundTransform = videoSound;
		}
	
		public function normalizeSound():void
		{
			videoSound.volume = 1;
			ns.soundTransform = videoSound;
		}
		
	    //...
	} 
}

Quick note on Event.MOUSE_LEAVE in AS3.0 & Firefox on PC

If you’re using MOUSE_LEAVE to check for the user’s mouse leaving your SWF in a browser and it’s not working on Firefox on Windows only — check your Embed code. If your problem occurs only on Firefox on PC (i.e. it works everywhere else) and there’s a WMODE parameter defined in your Embed tag or SWFObject instance, try removing WMODE and see if it fixes the FF issue. Thanks for the tip, Nate!

The downside of this fix, of course, is that it doesn’t work if you need your SWF to have a transparent background.

AS3.0 Signals example juxtaposed with native version

AS3.0 Signals is an event handling framework from Robert Penner that’s gaining popularity lately. There’s a good video tutorial by John Lindquist and tutorials here.

Here’s a quick comparison of an old XML processing class written both ways for comparison. For this simple example, Signals was about 10 to 50 milliseconds faster than using regular AS3 events. The results varied a lot each time I compiled.

Using the Signals framework for events:

XML processing class:

package com.timshaya.net
{
	import org.osflash.signals.Signal;
	import org.osflash.signals.natives.NativeSignal;
	
	import flash.events.Event;
	import flash.net.URLLoader;
	import flash.net.URLRequest;	

	public class XmlGrabber 
	{		
		private var loadDone				:NativeSignal;									
		public var dataDone					:Signal;										
		public var cityItems				:Array = [];								

		private var xmlData					:XML;		
		private var loader					:URLLoader;
		private var reqst					:URLRequest;
		private var trgt					:URLLoader;
		
		public function XmlGrabber(pth:String):void 
		{
			loader = new URLLoader(); 
			reqst = new URLRequest(pth);
						
			dataDone = new Signal();	
			loadDone = new NativeSignal(loader, Event.COMPLETE, Event); 
			loadDone.addOnce(loadCompleted);					
			
			loader.load(reqst);	
		}	
		
		public function loadCompleted(e:Event):void 
		{
			var trgt:URLLoader = URLLoader(e.target);
			xmlData = new XML(trgt.data); 
			//trace(xmlData);
			
			if (trgt!=null) 
			{
				for each (var a:XML in xmlData.evnt) 
				{
					cityItems.push(a); 
					//trace("\n cityItems[a]: " + a.@city + "\n"); 
				} 													
			} else trace("error: check your data & datatype");
			
			dataReady();
		}
		
		public function dataReady():void 
		{	
			dataDone.dispatch(); 
		}
	}
}

Test class:

package 
{	
	import org.osflash.signals.Signal;	
	import org.osflash.signals.natives.NativeSignal;
	import com.timshaya.net.XmlGrabber; 	
	
	import flash.display.Sprite;	
	import flash.events.Event;	
	import flash.utils.getTimer;

	[SWF (width="600", height="400", backgroundColor="#FFFFFF", frameRate="30")]	
	public class Test extends Sprite 
	{	
		private var addToStage				:NativeSignal;
		private var xml						:XmlGrabber;		
		private var xmlPth                  :String = "xml/"; 
		private var xmlName  				:String = "events.xml"; 				
		private var timer					:Number;
		
		public function Test():void 		
		{										
			addToStage = new NativeSignal(this, Event.ADDED_TO_STAGE, Event); 
			addToStage.addOnce(initApp);			
		}

		public function initApp(e:Event):void 
		{
			timer = getTimer();
			
			xml = new XmlGrabber(xmlPth + xmlName);
			xml.dataDone.add(createPage); 									
		}

		public function createPage():void 
		{							
			trace("Test::createPage()");		
			trace("\t time elapsed: " + (getTimer() - timer));			
						
			trace("\t xml.cityItems[0].@city = " + xml.cityItems[0].@city); 
			trace("\t xml.cityItems[0].@state = " + xml.cityItems[0].@state);			
		} 				
	}
}

Same code using native AS3 events:

XML processing class:

package com.timshaya.net
{
	import flash.events.Event;
	import flash.net.URLLoader;
	import flash.net.URLRequest;	
	import flash.events.EventDispatcher;

	public class XmlGrabberOld extends EventDispatcher 
	{		
		public var cityItems				:Array = [];		

		private var xmlData					:XML;		
		private var loader					:URLLoader;
		private var reqst					:URLRequest;
		private var trgt					:URLLoader;

		public static var DATA_READY		:String	= "list_ready";
		
		public function XmlGrabberOld(pth:String):void 
		{
			loader = new URLLoader(); 
			reqst = new URLRequest(pth);
			loader.load(reqst);
			loader.addEventListener(Event.COMPLETE, listOnComplete, false, 0, true);	
		}
		
		private function listOnComplete(e:Event):void
		{			
			var trgt:URLLoader = URLLoader(e.target);
			xmlData = new XML(trgt.data);
			//trace(xmlData);
			
			if (trgt!=null) 
			{
				for each (var a:XML in xmlData.evnt) 
				{
					cityItems.push(a); 
					//trace("\n cityItems[a]: " + a.@city + "\n"); 
				} 					
			} else trace("error: check your data & datatype");			

			dataReady();
		}
		
		private function dataReady():void
		{
			dispatchEvent(new Event(XmlGrabberOld.DATA_READY));
		}
		
	}
}

Test class:

package 
{		
	import com.timshaya.net.XmlGrabberOld;

	import flash.display.Sprite;	
	import flash.events.Event;	
	import flash.utils.getTimer;

	[SWF (width="600", height="400", backgroundColor="#FFFFFF", frameRate="30")]	
	public class TestOld extends Sprite 
	{	
		private var xml						:XmlGrabberOld;		
		private var xmlPth                  :String = "xml/"; 
		private var xmlName  				:String = "events.xml"; 		
		private var timer					:Number;
		
		public function TestOld():void 		
		{								
			addEventListener(Event.ADDED_TO_STAGE, initApp);		
		}

		public function initApp(e:Event):void 
		{
			timer = getTimer();
		
			xml = new XmlGrabberOld(xmlPth + xmlName);
			xml.addEventListener(XmlGrabberOld.DATA_READY, createPage);											
		}

		public function createPage(e:Event):void 
		{						
			trace("TestOld::createPage()");		
			trace("\t time elapsed: " + (getTimer() - timer));		
			
			trace("\t xml.cityItems[0].@city = " + xml.cityItems[0].@city); 
			trace("\t xml.cityItems[0].@state = " + xml.cityItems[0].@state);						
		} 						
		
	}
}

Sample xml file, events.xml:

<?xml version="1.0" encoding="ISO-8859-1"?>
<evnts>		
	
	<evnt lnk="test.aspx?c=0" city="Atlantic City" state="New Jersey" />
	<evnt lnk="test.aspx?c=1" city="Clifton" state="New Jersey" />	
	<evnt lnk="test.aspx?c=2" city="Allentown" state="Pennsylvania" />
	<evnt lnk="test.aspx?c=3" city="Akron" state="Ohio" />
	<evnt lnk="test.aspx?c=4" city="Wichita Falls" state="Texas" />
	<evnt lnk="test.aspx?c=5" city="Austin" state="Texas" />
	<evnt lnk="test.aspx?c=6" city="Orlando" state="Florida" />
	<evnt lnk="test.aspx?c=7" city="Atlanta" state="Georgia" />
	<evnt lnk="test.aspx?c=8" city="San Francisco" state="California" />
	<evnt lnk="test.aspx?c=9" city="Los Angeles" state="California" />
	<evnt lnk="test.aspx?c=10" city="San Diego" state="California" />	
	
</evnts>

Instantiating SlideShoPro in an AS3.0 Class

A simple user class:

package
{
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;

	import com.slideshow.MySlideShowPro;

	public class Main extends Sprite
	{
		private var mssp:DisplayObjectContainer;

		public function Main()
		{
			mssp = new MySlideShowPro(500, 350); //(width, height)
			mssp.x = 20;
			mssp.y = 20;
			addChild(mssp);
		}

	}
}

A sample basic SlideShowPro class:

package com.slideshow
{
	import flash.display.Sprite;
	import net.slideshowpro.slideshowpro.*;

	public class MySlideShowPro extends Sprite
	{
		//http://wiki.slideshowpro.net/SSPplayer/API-API
		private var myssp:SlideShowPro;

		public function MySlideShowPro(w:int, h:int)
		{
			//make sure SlideShowPro is set for Export in your Library, or SWC/SWF asset files
			myssp = new SlideShowPro(this);

			myssp.setSize(w, h);

			myssp.xmlFilePath = "xml/slides.xml";
			myssp.xmlFileType = "Default";

			/*
			the commented out lines, like:
			//myssp.navButtonGlowAlpha = .25;
			give error "1119: access of possibly undefined property..."
			*/

			myssp.navAppearance = "Always Visible";
			myssp.navBackgroundAlpha = 1;
			myssp.navBackgroundColor = 0x121212;
			myssp.navButtonsAppearance = "All Visible";
			myssp.navGradientAlpha = .3;
			myssp.navGradientAppearance = "Glass Dark";
			myssp.navButtonColor = 0xEEEEEE;
			//myssp.navButtonGlowAlpha = .25; 				//error 1119
			//myssp.navButtonGradientAlpha = .6;			//error 1119
			myssp.navButtonInactiveAlpha = .4;
			//myssp.navButtonRolloverColor = 0xFFFFFF;		//error 1119...
			myssp.navButtonShadowAlpha = .6;
			//myssp.navButtonShadowStyle = "Under";
			//myssp.navLinkAnimate = "On";
			myssp.navLinkAppearance = "Numbers";
			//myssp.navLinkActiveColor = 0xEEEEEE;
			//myssp.navLinkInactiveColor = 0x999999;
			myssp.navLinkPreviewAppearance = "Visible";
			myssp.navLinkPreviewBackgroundAlpha = 1;
			myssp.navLinkPreviewBackgroundColor = 0xFFFFFF;
			myssp.navLinkPreviewScale = "Proportional";
			myssp.navLinkPreviewSize = [100,100];
			myssp.navLinkPreviewStrokeWeight = 1;
			myssp.navLinkRolloverColor = 0xFFFFFF;
			//myssp.navLinkShadowAlpha = .6;
			myssp.navLinksBackgroundAlpha = 1;
			myssp.navLinksBackgroundColor = 0x000000;
			//myssp.navLinksBackgroundShadowAlpha = .6;
			myssp.navLinkSpacing = 8;
			myssp.navNumberLinkSize = 9;
			myssp.navPosition = "Bottom";
			myssp.navThumbLinkInactiveAlpha = 1;
			myssp.navThumbLinkSize = [16,16];
			myssp.navThumbLinkStrokeWeight = 1;

			myssp.albumBackgroundAlpha = 1;
			myssp.albumBackgroundColor = 0x303030;
			myssp.albumDescColor = 0xCCCCCC;
			myssp.albumDescSize = 9;
			myssp.albumPadding = 8;
			myssp.albumPreviewScale = "Proportional";
			myssp.albumPreviewSize = [54,41];
			myssp.albumPreviewStrokeColor = 0xFFFFFF;
			myssp.albumPreviewStrokeWeight = 1;
			myssp.albumPreviewStyle = "Inline Left";
			myssp.albumRolloverColor = 0x262626;
			myssp.albumStrokeAppearance = "Visible";
			myssp.albumStrokeColor = 0x141414;
			myssp.albumTitleColor = 0xFFFFFF;
			myssp.albumTitleSize = 10;
			myssp.audioAutoStart = "On";
			myssp.audioLoop = "Off";
			myssp.audioPause = "Off";
			myssp.audioVolume = .8;
			myssp.autoFinishMode = "Switch";
			myssp.cacheContent = "None";
			myssp.captionAppearance = "Overlay on Rollover (if Available)";
			myssp.captionBackgroundAlpha = .6;
			myssp.captionBackgroundColor = 0xFFFFFF;
			myssp.captionElements = "Header and Caption";
			myssp.captionHeaderBackgroundAlpha = 0;
			//myssp.captionHeaderPadding = [6,6,2,6];
			myssp.captionHeaderText = "{imageTitle}";
			//myssp.captionHeaderTextColor = 0xEEEEEE;
			myssp.captionPadding = [2,6,6,6];
			myssp.captionPosition = "Top";
			myssp.captionTextAlignment = "Left";
			myssp.captionTextColor = 0xAAAAAA;
			//myssp.captionTextShadowAlpha = 0;
			myssp.captionTextSize = 9;
			myssp.contentAlign = "Center";
			myssp.contentAreaAction = "Launch Hyperlink";
			myssp.contentAreaBackgroundAlpha = 1;
			myssp.contentAreaBackgroundColor = 0x161616;
			myssp.contentAreaInteractivity = "Action Area Only";
			myssp.contentAreaStrokeAppearance = "Visible";
			myssp.contentAreaStrokeColor = 0x262626;
			myssp.contentFrameAlpha = 1;
			myssp.contentFrameColor = 0x262626;
			myssp.contentFramePadding = 0;
			myssp.contentFrameStrokeAppearance = "Hidden";
			myssp.contentFrameStrokeColor = 0x333333;
			myssp.contentOrder = "Sequential";
			myssp.contentScale = "Downscale Only";
			myssp.contentScalePercent = 1;
			myssp.contentWatermark = "";
			myssp.contentWatermarkAlign = "Bottom Right";
			myssp.directorLargePublishing = "On";
			myssp.directorLargeQuality = 80;
			myssp.directorLargeSharpening = 1;
			myssp.directorThumbQuality = 60;
			myssp.directorThumbSharpening = 1;

			myssp.displayMode = "Auto";
			myssp.feedbackBackgroundAlpha = .3;
			myssp.feedbackBackgroundColor = 0x000000;
			myssp.feedbackHighlightAlpha = .8;
			myssp.feedbackHighlightColor = 0xFFFFFF;
			myssp.feedbackPreloaderAlign = "Center";
			myssp.feedbackPreloaderAppearance = "Beam";
			myssp.feedbackPreloaderPosition = "Inside Content Area";
			myssp.feedbackPreloaderScale = 1;
			myssp.feedbackPreloaderTextSize = 12;
			myssp.feedbackTimerAlign = "Top Right";
			myssp.feedbackTimerAppearance = "Visible";
			myssp.feedbackTimerPosition = "Inside Content Area";
			myssp.feedbackTimerScale = 1;
			myssp.feedbackVideoButtonScale = 1;
			myssp.fullScreenReformat = "On";
			myssp.fullScreenTakeOver = "On";
			myssp.galleryAppearance = "Visible";
			myssp.galleryBackgroundAlpha = 1;
			myssp.galleryBackgroundColor = 0x1C1C1C;
			myssp.galleryColumns = 2;
			//myssp.galleryContentShadowAlpha = 0;
			myssp.galleryOrder = "Left to Right";
			myssp.galleryPadding = 10;
			myssp.galleryRows = 4;
			myssp.galleryNavActiveColor = 0x303030;
			myssp.galleryNavAppearance = "Visible";
			myssp.galleryNavInactiveColor = 0x000000;
			myssp.galleryNavRolloverColor = 0x262626;
			myssp.galleryNavStrokeAppearance = "Visible";
			myssp.galleryNavStrokeColor = 0x141414;
			myssp.galleryNavTextColor = 0xCCCCCC;
			myssp.galleryNavTextSize = 9;
			myssp.keyboardControl = "On";
			//myssp.loop = "Off";
			myssp.mediaPlayerAppearance = "Visible on Rollover";
			myssp.mediaPlayerBackgroundAlpha = .25;
			myssp.mediaPlayerBackgroundColor = 0x000000;
			myssp.mediaPlayerBufferColor = 0x000000;
			myssp.mediaPlayerButtonColor = 0xFFFFFF;
			myssp.mediaPlayerElapsedBackgroundColor = 0xFFFFFF;
			myssp.mediaPlayerElapsedTextColor = 0x000000;
			myssp.mediaPlayerPosition = "Bottom";
			myssp.mediaPlayerProgressColor = 0xCCCCCC;
			myssp.mediaPlayerScale = .8;
			myssp.mediaPlayerTextColor = 0x999999;
			myssp.mediaPlayerTextSize = 9;
			myssp.mediaPlayerVolumeBackgroundColor = 0x000000;
			myssp.mediaPlayerVolumeHighlightColor = 0xCCCCCC;
			myssp.panZoom = "Off";
			myssp.panZoomDirection = "Random";
			myssp.panZoomFinish = "Off";
			myssp.panZoomScale = [1,1.2];
			myssp.permalinks = "Off";
			myssp.smoothing = "On";
			//myssp.soundEffects = "";
			//myssp.soundEffectsVolume = .4;
			myssp.textStrings = ["Previous Screen","Next Screen","Screen","of","No caption","No title","Playing","Paused","Click play to start audio"];
			myssp.toolAppearanceContentArea = "Hidden";
			myssp.toolAppearanceNav = "Visible";
			myssp.toolColor = 0x222222;
			myssp.toolDelayContentArea = 0;
			myssp.toolDelayNav = .5;
			myssp.toolLabels = ["Gallery","Previous Group","Previous","Next","Next Group","Pause","Play","Full Screen","Normal Screen","Open Link"];
			myssp.toolTimeoutContentArea = 0;
			myssp.transitionLength = 2;
			myssp.transitionPause = 4;
			myssp.transitionDirection = "Left to Right";
			myssp.transitionStyle = "Cross Fade";
			myssp.typeface = "Lucida Grande,Lucida Sans Unicode,Verdana,Arial,_sans";
			//myssp.typefaceAntiAlias = "Advanced";
			myssp.typefaceEmbed = "Off";
			myssp.videoAutoStart = "On";
			myssp.videoBufferTime = 0.1;
		}
	}
}

“Error #1088” despite a well-formed XML file

The 1 line of code below in my XML processor class caused this error: “Error #1088: The markup in the document following the root element must be well-formed,” despite the fact that my source xml file passed multiple validation tests from multiple sources.

fEvent = XML(xmlData.fevnt);		

As soon as I got rid of the casting operation XML (…) and changed the fEvent datatype to String or Array ( a cheap trick to access XML element attributes), the error went away.

When I googled “Error #1088” most posts were about XML that was dynamically generated via a server-side script. In this instance, this was a static, well-formed XML file that suddenly started throwing this error, so I had to go through the code, commenting it out line by line to find the culprit. Who knew — google doesn’t have the answers to everything all the time! =)

Some context for the problem code, as it existed in the XML processor class:

//...

private function loadData(xmlFilePath:String):void {
			loader = new URLLoader();
			reqst=new URLRequest(xmlFilePath);
			loader.load(reqst);
			loader.addEventListener(Event.COMPLETE, onLdrComplete);
}

private function onLdrComplete(e:Event):void {
			var ldr:URLLoader=e.target as URLLoader;
			xmlData=new XML(ldr.data); //defined as xmlData:XML above
			//...
            finalEvent = XML(xmlData.finalevnt);				
}

AS2 to AS3.0 ports are fun

A quick AS3.0 port of Lee’s AS2 scrolling thumbnail panel.

//stroke = instance name of mc on stage
var b:Rectangle = new Rectangle(stroke.x, stroke.y, stroke.width, stroke.height);

//panel = instance name of mc on stage
panel.addEventListener(MouseEvent.MOUSE_OVER, panelOver, false, 0, true); 

function panelOver(e:MouseEvent):void 
{	
	panel.addEventListener(Event.ENTER_FRAME, scrollPanel, false, 0, true); 
	panel.removeEventListener(MouseEvent.MOUSE_OVER, panelOver);
}

function scrollPanel(e:Event):void 
{
	//if mouse is outisde bounding box, b, then stop all scroll action		
	if(mouseX<b.left || mouseX>b.right || mouseY<b.top || mouseY>b.bottom) 	
	{
		panel.addEventListener(MouseEvent.MOUSE_OVER, panelOver, false, 0, true);		
		panel.removeEventListener(Event.ENTER_FRAME, scrollPanel);		
	}
	
	if(panel.x >= 89) panel.x = 89; //left bound	
	if(panel.x <= -751) panel.x = -751; //right bound 			
	
	var xdist:Number = mouseX - 250; //250 == stage.stageWidth/2 (if panel is centered on stage)  
	
	panel.x += Math.round(-xdist / 7);
}

Implementing tracking pixels in AS3.0: Mediaplex

Embedding tracking pixels in a Flash app sounds like it should be simple. Just make a Request to the server from your .swf that calls up the 1×1 .gif, right? Somehow or other it ends up being a confusing process nonetheless.

In my humble experience, the oversight is usually on the side of the vendor whose technology a Developer is asked to implement. Simple requests for instructions on how to implement a 3rd party technology into an Actionscript 3.0 application are met with confused email responses by folks who don’t seem to understand that there’s more than one version of the Actionscript programming language and the occasional emailed PDF that describes things like “How to Add a clickTag” using screen shots from Flash 5 and Asctionscript 1.0. Since more often than not vendors can’t or won’t send clear instructions on how to implement their tags in the current version of Actionscript / Flash / Flex, what ends up happening is the Developer is asked to test and debug the vendor’s product for them, for free.

Going forward, it’d be nice if a company that sells technology which they say can be implemented in Flash could actually have someone in that company:

  1. create a modern Flash application
  2. implement the technology
  3. have the source files ready for clients to use for reference.

OK, enough venting.

Here’s one way to implement Mediaplex tracking pixels in AS3.0 (Flash / Flex)

Make sure you receive the Standard pixel path, i.e. one that starts with “<img” (not one that starts with “<iframe”). Here’s a basic test class that calls a Mediaplex tracking pixel:

package
{
	import flash.net.URLRequest;
	import flash.net.URLVariables;
	import flash.net.URLLoader;
	import flash.net.URLRequestMethod;
	import flash.display.Sprite;

	[SWF (width="500", height="750", backgroundColor="#000000", frameRate="31")]
	public class Main extends Sprite
	{
		private var yourMediaPlexURL:Array = ["http://sd.mediaplex.com/somepath/"];

		public function Main():void
		{
			Security.loadPolicyFile("http://www.your.com/crossdomain.xml");
			this.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
		}

		public function  onAddedToStage(e:Event):void
		{
			//call the tracking code
			trackMediaPlex(yourMediaPlexURL[0]);
		}

		public function trackMediaPlex(yourURL:String):void
		{
			var myRequest:URLRequest = new URLRequest(yourURL);
			myRequest.method = URLRequestMethod.POST;

			var myLoader:URLLoader = new URLLoader();
			try{
				myLoader.load(myRequest);
				trace("\t trackMediaPlex(): myRequest.url = " + myRequest.url);
			} catch(e:Error) {
				trace(e.getStackTrace());
			}
		}
	}
}

Before activating the pixel, it’s a good idea to quickly test it in Firefox using Firebug. Under the Net tab[1] in in Firebug you should see three server hits:

  1. your original request
  2. a redirect
  3. a request for the 1×1 pixel file itself.

Once you see these firing in Firebug, activate the pixel and you should be good to go. For more detailed testing use Charles (Mac) and Fiddler (PC).

A basic crossdomain.xml policy file should allow all the potential Mediaplex urls that might be used, such as this one: http://somedomain.mediaplex.com. Be careful about how you specify urls in crossdomain.xml, the minuscule difference between “http://somedomain.mediaplex.com&#8221; and “http://somedomain.mediaplex.com/&#8221; can break your code.

Notes:
1. Make sure you Enable the Net tab first