<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Derek J Entringer &#124; Interactive Media, Web Application, and Mobile App Developer &#187; Code Samples</title>
	<atom:link href="http://www.derekentringer.com/blog/category/code-samples/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.derekentringer.com/blog</link>
	<description>Interactive Media Development, Web Application Development, Mobile App Development, Flash, Flash Media Server, Flex, Flash Component Creation, Game Programming &#38; Design, Blog, CMS, eCommerce Setup &#38; Styling, Search Engine Optimization, Social Networking Strategies, Website Interface &#38; Template Creation, Windows Vista Gadget Development, Apple Widget Development, Email Marketing, Code Samples, Tutorials</description>
	<lastBuildDate>Tue, 13 Jul 2010 19:25:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Augmented Reality Using Flex, AS3, And A WebCam</title>
		<link>http://www.derekentringer.com/blog/augmented-reality-using-flex-as3-and-a-webcam/</link>
		<comments>http://www.derekentringer.com/blog/augmented-reality-using-flex-as3-and-a-webcam/#comments</comments>
		<pubDate>Thu, 05 Nov 2009 01:15:27 +0000</pubDate>
		<dc:creator>Derek J Entringer</dc:creator>
				<category><![CDATA[Code Samples]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[General Discussion]]></category>
		<category><![CDATA[New Developments]]></category>
		<category><![CDATA[as3]]></category>
		<category><![CDATA[augmented]]></category>
		<category><![CDATA[reality]]></category>
		<category><![CDATA[webcam]]></category>

		<guid isPermaLink="false">http://www.derekentringer.com/blog/?p=400</guid>
		<description><![CDATA[
			
				
			
		

Augmented reality (AR) on the Flash and Flex platform is really quite a new technology, but there are a large amount of developers and businesses that are embracing the use of AR online. Media companies such as Esquire, and technology companies such as GE are using the tech to engage their users both through print media as well as online media.
AR research explores the application of computer-generated imagery in live-video streams as a way to expand the real-world.
The possibilities of how you could use Augmented Reality (AR) are endless. Picture ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="clear:left; float:left; margin-top:10px; margin-bottom: 10px; margin-right:12px; margin-left:2px;">
			<a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2FwaS50d2VldG1lbWUuY29tL3NoYXJlP3VybD1odHRwJTNBJTJGJTJGd3d3LmRlcmVrZW50cmluZ2VyLmNvbSUyRmJsb2clMkZhdWdtZW50ZWQtcmVhbGl0eS11c2luZy1mbGV4LWFzMy1hbmQtYS13ZWJjYW0lMkY="><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.derekentringer.com%2Fblog%2Faugmented-reality-using-flex-as3-and-a-webcam%2F&amp;source=derekentringer&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p><!--PLAIN_TEXT--><br />
Augmented reality (AR) on the Flash and Flex platform is really quite a new technology, but there are a large amount of developers and businesses that are embracing the use of AR online. Media companies such as <a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL21hc2hhYmxlLmNvbS8yMDA5LzEwLzMwL2VzcXVpcmUtYXVnbWVudGVkLXJlYWxpdHkv">Esquire</a>, and technology companies such as <a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2dlLmVjb21hZ2luYXRpb24uY29tL3NtYXJ0Z3JpZC8/Y19pZD1nb29nYXVncmVhbCYjMDM4O2djbGlkPUNQei0wXzJJOHAwQ0ZjbU41d29kRkdSTXhRIy9hdWdtZW50ZWRfcmVhbGl0eQ==">GE</a> are using the tech to engage their users both through print media as well as online media.</p>
<p>AR research explores the application of computer-generated imagery in live-video streams as a way to expand the real-world.</p>
<p>The possibilities of how you could use Augmented Reality (AR) are endless. Picture yourself walking or driving down the street. With augmented-reality displays, which will eventually look much like a normal pair of glasses, and informative graphics appearing in your field of view, and audio that coincides with whatever you see.</p>
<p>Now, this article doesn&#8217;t go as far as how to create your own AR glasses, but rather a &#8220;first step&#8221; into what is capable when using AR.</p>
<p>I&#8217;ve created a quick example of an AR environment below. Using your webcam, and the provided PDF, you can experience what AR is all about. Make sure to take a look at some more advanced examples in the links above also.</p>
<p>First, print <a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vZG93bmxvYWRzL2FyL2RlcmVrZW50cmluZ2VyLnBkZg==" target=\"_blank\">this PDF</a>.</p>
<p>Next, activate the Flash movie below to allow access to your webcam, and hold up the piece of paper to the camera to activate the AR environment. Make sure the large square is fully visible within the camera, and you&#8217;ll see how the AR loads and animates with how you position the paper.</p>
<p><script language="JavaScript" type="text/javascript">
	AC_FL_RunContent(
		'codebase', 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,0,0',
		'width', '570',
		'height', '400',
		'src', 'http://www.derekentringer.com/downloads/ar/FLARdemo',
		'quality', 'high',
		'pluginspage', 'http://www.adobe.com/go/getflashplayer',
		'align', 'middle',
		'play', 'true',
		'loop', 'true',
		'scale', 'showall',
		'wmode', 'window',
		'devicefont', 'false',
		'id', 'FLARdemo',
		'bgcolor', '#0F0F0F',
		'name', 'FLARdemo',
		'menu', 'false',
		'allowFullScreen', 'true',
		'allowScriptAccess','sameDomain',
		'movie', 'http://www.derekentringer.com/downloads/ar/FLARdemo',
		'salign', ''
		); //end AC code
</script><br />
<noscript><br />
	<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,0,0" width="570" height="400" id="FLARdemo" align="middle"><param name="allowScriptAccess" value="sameDomain" /><param name="allowFullScreen" value="false" /><param name="movie" value="http://www.derekentringer.com/downloads/ar/FLARdemo.swf" /><param name="quality" value="high" /><param name="bgcolor" value="#0F0F0F" /><embed src="http://www.derekentringer.com/downloads/ar/FLARdemo.swf" quality="high" bgcolor="#0F0F0F" width="570" height="400" name="FLARdemo" align="middle" allowScriptAccess="sameDomain" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer" /><br />
	</object><br />
</noscript></p>
<p>Like I said, this example is brief. The AR that you will see above when holding up the pattern you printed is quite simple. There will be three cubes that will be displayed within your streaming video. The AR environment reacts to wherever the pattern on the printed pdf goes. You can rotate or angle the pattern against the camera, the the AR will follow.</p>
<p>There are many ways that this small &#8220;first step&#8221; towards a more interactive AR environment can be upgraded, and it&#8217;s only a start.</p>
<p>Using this technology you can stream video, add animations, or animate entire environments. You could green-screen actors or musicians and place them in a music video that comes to life seemingly right in your own hands. There are thousands of ways to implement AR to engage your website visitors or publication readers. Artist labels could use AR in their branding or CD packaging, or anyone with a business card could use AR to allow for mini-presentations. Whether that be a video or information displayed to a potential client by simply holding your business card card up to their webcam, while visiting your own website.</p>
<p>The ways of incorporating Augmented Reality into online and print media are nearly endless.</p>
<p>If you do not have a web cam, here&#8217;s how this simple example looks.</p>
<p><script type="text/javascript" src="http://flvplayer.com/free-flv-player/flvplayer/swfobject/swfobject.js"></script></p>
<div id="embed_player">
<h1>Please Upgrade Your Flash Player</h1>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5hZG9iZS5jb20vZ28vZ2V0Zmxhc2hwbGF5ZXI="><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>
</div>
<p><script type="text/javascript">
var flashvars = {
flvpFolderLocation: "http://flvplayer.com/free-flv-player/flvplayer/", 
flvpVideoSource: "http://www.derekentringer.com/downloads/ar/ar_demo.mp4", 
flvpWidth: "568", 
flvpHeight: "400", 
flvpInitVolume: "50", 
flvpTurnOnCorners: "true", 
flvpBgColor: "0F0F0F"
};
var params = {
bgcolor: "0F0F0F", 
menu: "true", 
allowfullscreen: "true"
};
swfobject.embedSWF("http://flvplayer.com/free-flv-player/FlvPlayer.swf", "embed_player", "568", "400", "9.0.0", "http://flvplayer.com/free-flv-player/flvplayer/swfobject/expressInstall.swf", flashvars, params);
</script></p>
<p>Have you used AR in any of your projects yet?</p>
 <img src="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=400" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.derekentringer.com/blog/augmented-reality-using-flex-as3-and-a-webcam/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
<enclosure url="http://www.derekentringer.com/downloads/ar/ar_demo.mp4" length="2222555" type="audio/mp4" />
		</item>
		<item>
		<title>Boost Your Brand Awareness, Protect Your Link Data, and Get Your Own URL Trimming Service</title>
		<link>http://www.derekentringer.com/blog/boost-your-brand-awareness-protect-your-link-data-and-get-your-own-url-trimming-service/</link>
		<comments>http://www.derekentringer.com/blog/boost-your-brand-awareness-protect-your-link-data-and-get-your-own-url-trimming-service/#comments</comments>
		<pubDate>Fri, 04 Sep 2009 22:32:35 +0000</pubDate>
		<dc:creator>Derek J Entringer</dc:creator>
				<category><![CDATA[Code Samples]]></category>
		<category><![CDATA[General Discussion]]></category>
		<category><![CDATA[New Developments]]></category>
		<category><![CDATA[PHP/MySQL]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[analytics]]></category>
		<category><![CDATA[boost]]></category>
		<category><![CDATA[brand]]></category>
		<category><![CDATA[custom]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[htaccess]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[protect]]></category>
		<category><![CDATA[recognition]]></category>
		<category><![CDATA[service]]></category>
		<category><![CDATA[trimming]]></category>
		<category><![CDATA[url]]></category>

		<guid isPermaLink="false">http://www.derekentringer.com/blog/?p=356</guid>
		<description><![CDATA[
			
				
			
		

It seems that the larger url trimming services are gaining a lot of ground these days, and are churning over huge amounts of urls. This also feeds them a ton of data on what people are interested on the web, which will benefit these trimming services at some point in the future. We&#8217;re feeding their databases with enourmous amounts of information on what everyone on the web is talking about.
But, what about ourselves? How does keeping all of my trimmed url analytics on some other companies servers benefit me? How ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="clear:left; float:left; margin-top:10px; margin-bottom: 10px; margin-right:12px; margin-left:2px;">
			<a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2FwaS50d2VldG1lbWUuY29tL3NoYXJlP3VybD1odHRwJTNBJTJGJTJGd3d3LmRlcmVrZW50cmluZ2VyLmNvbSUyRmJsb2clMkZib29zdC15b3VyLWJyYW5kLWF3YXJlbmVzcy1wcm90ZWN0LXlvdXItbGluay1kYXRhLWFuZC1nZXQteW91ci1vd24tdXJsLXRyaW1taW5nLXNlcnZpY2UlMkY="><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.derekentringer.com%2Fblog%2Fboost-your-brand-awareness-protect-your-link-data-and-get-your-own-url-trimming-service%2F&amp;source=derekentringer&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p><!--PLAIN_TEXT--><br />
It seems that the larger url trimming services are gaining a lot of ground these days, and are churning over huge amounts of urls. This also feeds them a ton of data on what people are interested on the web, which will benefit these trimming services at some point in the future. We&#8217;re feeding their databases with enourmous amounts of information on what everyone on the web is talking about.</p>
<p>But, what about ourselves? How does keeping all of my trimmed url analytics on some other companies servers benefit me? How can I boost my own brand recognition if I were to create my own personal url trimming application?</p>
<p>Those were the exact goals in the creation of my own url trimming app: <a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2VudHIuaW4vZ2VyLw==">http://entr.in/ger/</a></p>
<p><img src="http://www.derekentringer.com/img/entringer_logo.jpg" /></p>
<p>I wanted to accomplish the same things that bit.ly or tr.im were doing, but to also keep my brand http://derekentringer.com intact with all of the Trimmed URL&#8217;s that I was pushing out onto the web. Why would I push another companies brand recognition with all of the interesting articles and videos that I was sharing when using a smaller url? Why wouldn&#8217;t any Twitter or Facebook user want their own trimmed url? I believe that using your own custom url trimming service can benefit both your brand recognition, as well your own internal link tracking and social media monitoring initiatives.</p>
<p>Now, I don&#8217;t think that using tr.im or bit.ly is a bad thing, but, if you remember very recently, tr.im almost went offline right along with all of its data.</p>
<p>Protect your own data, boost your brand awareness, and get your own url trimming service.</p>
<p>If you&#8217;re looking for you own url trimming application, hit me up in the <a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vY29udGFjdC8=">contact area</a>. I&#8217;m sure we can work something out to fit your needs.</p>
<p><em>Note: If you decide to trim a url with entr.in/ger/, it will work, but you will not be able to track the link analytics. This is my own personal url trimming application.</em></p>
 <img src="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=356" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.derekentringer.com/blog/boost-your-brand-awareness-protect-your-link-data-and-get-your-own-url-trimming-service/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Stream Your Videos Using FLV Player – FREE</title>
		<link>http://www.derekentringer.com/blog/stream-your-videos-using-flv-player-free/</link>
		<comments>http://www.derekentringer.com/blog/stream-your-videos-using-flv-player-free/#comments</comments>
		<pubDate>Fri, 28 Aug 2009 06:56:57 +0000</pubDate>
		<dc:creator>Derek J Entringer</dc:creator>
				<category><![CDATA[Code Samples]]></category>
		<category><![CDATA[FMS]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Flash Components]]></category>
		<category><![CDATA[New Developments]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[as3]]></category>
		<category><![CDATA[components]]></category>
		<category><![CDATA[embed code]]></category>
		<category><![CDATA[flashvars]]></category>
		<category><![CDATA[flv]]></category>
		<category><![CDATA[free]]></category>
		<category><![CDATA[media]]></category>
		<category><![CDATA[player]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[video]]></category>
		<category><![CDATA[vimeo]]></category>
		<category><![CDATA[youtube]]></category>

		<guid isPermaLink="false">http://www.derekentringer.com/blog/?p=346</guid>
		<description><![CDATA[
			
				
			
		

We&#8217;ve recently added some pretty significant new features to our FLV Player Flash Component. One really neat new offering is our Free FLV Player, which allows you to stream videos from Youtube!, Vimeo, or your own sources including Flash Media Server. All you need is a video source, your player width and height requirements, and you can get your embed code in 3 easy steps.
Take a look at FLV Player, and our new Free FLV Player at http://flvplayer.com.
If you ever wanted to add video to your projects or websites, there ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="clear:left; float:left; margin-top:10px; margin-bottom: 10px; margin-right:12px; margin-left:2px;">
			<a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2FwaS50d2VldG1lbWUuY29tL3NoYXJlP3VybD1odHRwJTNBJTJGJTJGd3d3LmRlcmVrZW50cmluZ2VyLmNvbSUyRmJsb2clMkZzdHJlYW0teW91ci12aWRlb3MtdXNpbmctZmx2LXBsYXllci1mcmVlJTJG"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.derekentringer.com%2Fblog%2Fstream-your-videos-using-flv-player-free%2F&amp;source=derekentringer&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p><!--PLAIN_TEXT--><br />
We&#8217;ve recently added some pretty significant new features to our FLV Player Flash Component. One really neat new offering is our Free FLV Player, which allows you to stream videos from Youtube!, Vimeo, or your own sources including Flash Media Server. All you need is a video source, your player width and height requirements, and you can get your embed code in 3 easy steps.</p>
<p>Take a look at <a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2ZsdnBsYXllci5jb20=">FLV Player</a>, and our new <a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2ZsdnBsYXllci5jb20vZnJlZS1mbHYtcGxheWVyLw==">Free FLV Player</a> at <a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2ZsdnBsYXllci5jb20=">http://flvplayer.com</a>.</p>
<p>If you ever wanted to add video to your projects or websites, there is no easier way than using pre-built Flash video components. Our player is one of the most feature loaded components on the market and it was specifically designed to suit developer and designers needs. It provides a fast and easy way to add video content in just few steps.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="570" height="316" id="FlvPlayer" align="middle"><param name="allowScriptAccess" value="sameDomain" /><param name="allowFullScreen" value="true" /><param name="movie" value="http://flvplayer.com/free-flv-player/FlvPlayer.swf" /><param name="quality" value="high" /><param name="bgcolor" value="0F0F0F" /><param name="FlashVars" value="flvpFolderLocation=http://flvplayer.com/free-flv-player/flvplayer/&#038;flvpVideoSource=http://flvplayer.com/media/Satutn_de_commercial.mp4&#038;flvpWidth=570&#038;flvpHeight=316&#038;flvpInitVolume=50&#038;flvpTurnOnCorners=true&#038;flvpBgColor=0F0F0F"<br />
<embed src="http://flvplayer.com/free-flv-player/FlvPlayer.swf" flashvars="flvpFolderLocation=http://flvplayer.com/free-flv-player/flvplayer/&#038;flvpVideoSource=http://flvplayer.com/media/Satutn_de_commercial.mp4&#038;flvpWidth=570&#038;flvpHeight=316&#038;flvpInitVolume=50&#038;flvpTurnOnCorners=true&#038;flvpBgColor=0F0F0F" quality="high" bgcolor="0F0F0F" width="570" height="316" name="FlvPlayer" align="middle" allowScriptAccess="sameDomain" allowFullScreen="true" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer" /></object></p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2ZsdnBsYXllci5jb20vZnJlZS1mbHYtcGxheWVy">Get your own Free FLV Player here</a></p>
<p>Here are some more new features that we recently added to FLV Player:</p>
<p><b>FlashVar Support</b><br />
FlvPlayer now fully supports FlashVars. This is another layer of interactivity that we&#8217;ve created that allows anyone who doesn&#8217;t have Flash to also benefit from the player. It provides access to all of the parameters of the player directly from the swf embed code.</p>
<p><b>Tooltips</b><br />
We&#8217;ve upgraded the interface to allow for individual tooltips on all of the FLV Player elements. You also have the ability to control the colors and transparencies.</p>
<p><b>Stream YouTube! Videos</b><br />
Stream all of your favorite YouTube! videos directly in your website or blog using our custom PHP streaming scripts.</p>
<p><b>Stream Vimeo Videos</b><br />
Stream all of your favorite Vimeo! videos by simply letting FLV Player know the Vimeo video id.</p>
<p>
More information is available at <a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2ZsdnBsYXllci5jb20=">FLVplayer.com</a></p>
 <img src="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=346" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.derekentringer.com/blog/stream-your-videos-using-flv-player-free/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FLV Player &#8211; Flash Video Component &#8211; Now Available at FLVplayer.com</title>
		<link>http://www.derekentringer.com/blog/flv-player-flash-video-component-now-available-at-flvplayercom/</link>
		<comments>http://www.derekentringer.com/blog/flv-player-flash-video-component-now-available-at-flvplayercom/#comments</comments>
		<pubDate>Fri, 24 Jul 2009 08:39:29 +0000</pubDate>
		<dc:creator>Derek J Entringer</dc:creator>
				<category><![CDATA[Code Samples]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Flash Components]]></category>
		<category><![CDATA[New Developments]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[component]]></category>
		<category><![CDATA[devbase.com]]></category>
		<category><![CDATA[flv]]></category>
		<category><![CDATA[flvplayer.com]]></category>
		<category><![CDATA[player]]></category>
		<category><![CDATA[progressive]]></category>
		<category><![CDATA[streaming]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://www.derekentringer.com/blog/?p=298</guid>
		<description><![CDATA[
			
				
			
		

After a recent partnership with FLVplayer.com, and a lot of work developing and tweaking our latest product, we&#8217;ve officially released our highly customizable FLV Player Flash Video Component. Have a look at flvplayer.com
FLVplayer supports all of the video formats available through the Adobe Flash platform including, but not limited to, MOV, MP4, F4V, and of course FLV.
Customize FLVplayer to match the look and feel of your current website or project. Modify the component to give it your own custom interface.
Our FLVplayer is loaded with features. If you&#8217;re a seasoned programmer, ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="clear:left; float:left; margin-top:10px; margin-bottom: 10px; margin-right:12px; margin-left:2px;">
			<a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2FwaS50d2VldG1lbWUuY29tL3NoYXJlP3VybD1odHRwJTNBJTJGJTJGd3d3LmRlcmVrZW50cmluZ2VyLmNvbSUyRmJsb2clMkZmbHYtcGxheWVyLWZsYXNoLXZpZGVvLWNvbXBvbmVudC1ub3ctYXZhaWxhYmxlLWF0LWZsdnBsYXllcmNvbSUyRg=="><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.derekentringer.com%2Fblog%2Fflv-player-flash-video-component-now-available-at-flvplayercom%2F&amp;source=derekentringer&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p><!--PLAIN_TEXT--><br />
After a recent partnership with FLVplayer.com, and a lot of work developing and tweaking our latest product, we&#8217;ve officially released our highly customizable FLV Player Flash Video Component. Have a look at flvplayer.com</p>
<p>FLVplayer supports all of the video formats available through the Adobe Flash platform including, but not limited to, MOV, MP4, F4V, and of course FLV.</p>
<p>Customize FLVplayer to match the look and feel of your current website or project. Modify the component to give it your own custom interface.</p>
<p>Our FLVplayer is loaded with features. If you&#8217;re a seasoned programmer, use our API to extend the options, and create engaging multimedia video.</p>
<p><center><br />
<script language="JavaScript" type="text/javascript">
	AC_FL_RunContent(
		'codebase', 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,0,0',
		'width', '570',
		'height', '316',
		'src', 'http://www.derekentringer.com/blog/flvplayer/FLVplayer',
		'quality', 'high',
		'pluginspage', 'http://www.adobe.com/go/getflashplayer',
		'align', 'middle',
		'play', 'true',
		'loop', 'true',
		'scale', 'showall',
		'wmode', 'window',
		'devicefont', 'false',
		'id', 'FLVplayer',
		'bgcolor', '#0F0F0F',
		'name', 'FLVplayer',
		'menu', 'false',
		'allowFullScreen', 'true',
		'allowScriptAccess','sameDomain',
		'movie', 'http://www.derekentringer.com/blog/flvplayer/FLVplayer',
		'salign', ''
		); //end AC code
</script><br />
<noscript><br />
	<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,0,0" width="570" height="316" id="FLVplayer" align="middle"><param name="allowScriptAccess" value="sameDomain" /><param name="allowFullScreen" value="false" /><param name="movie" value="http://www.derekentringer.com/blog/flvplayer/FLVplayer.swf" /><param name="menu" value="false" /><param name="quality" value="high" /><param name="bgcolor" value="#0F0F0F" /><embed src="http://www.derekentringer.com/blog/flvplayer/FLVplayer.swf" menu="false" quality="high" bgcolor="#0F0F0F" width="570" height="316" name="FLVplayer" align="middle" allowScriptAccess="sameDomain" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer" /><br />
	</object><br />
</noscript><br />
</center><br />
<br />
Some of the features include:</p>
<ul>
<li>Progressive or instant RTMP streaming using a Flash Media Server</li>
<li>Customizable XML menu system to load multiple video files, thumbnails, video titles and descriptions</li>
<li>Dynamic Interface Options allow for turning interface elements on or off</li>
<li>Live preview of component features within the Flash interface</li>
<li>Custom color options for all aspects of the FlvPlayer interface including background colors, font colors, rollover colors, and controls for transparencies</li>
<li>Fullscreen toggle</li>
<li>Closed captions</li>
<li>Advanced video display controls including Fit To Player, Original Size, Fit to Width, and Fit to Height</li>
<li>Dynamic Buffering</li>
<li>Interface Display options that include Overlay or Outside, and Autohide</li>
<li>Dynamically rounded corners settings</li>
<li>Full API supporting all major functions as public methods</li>
<p>
For more information, please visit <a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2ZsdnBsYXllci5jb20=">FLVplayer.com</a> and <a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2RldmJhc2UuY29t">DevBase.com</a></p>
 <img src="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=298" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.derekentringer.com/blog/flv-player-flash-video-component-now-available-at-flvplayercom/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Flash Media Server Streaming Speed Testing [Part 3] &#8211; Compare Multiple Server Resources, Port Connections, Detect Upload, Download, and Latency Speed</title>
		<link>http://www.derekentringer.com/blog/flash-media-server-streaming-speed-testing-part-3-compare-multiple-server-resources-port-connections-detect-upload-download-and-latency-speed/</link>
		<comments>http://www.derekentringer.com/blog/flash-media-server-streaming-speed-testing-part-3-compare-multiple-server-resources-port-connections-detect-upload-download-and-latency-speed/#comments</comments>
		<pubDate>Tue, 12 May 2009 20:21:58 +0000</pubDate>
		<dc:creator>Derek J Entringer</dc:creator>
				<category><![CDATA[Code Samples]]></category>
		<category><![CDATA[FMS]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[bandwidth]]></category>
		<category><![CDATA[detection]]></category>
		<category><![CDATA[download]]></category>
		<category><![CDATA[flash media server]]></category>
		<category><![CDATA[latency]]></category>
		<category><![CDATA[multiple]]></category>
		<category><![CDATA[port]]></category>
		<category><![CDATA[servers]]></category>
		<category><![CDATA[speed]]></category>
		<category><![CDATA[test]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[upload]]></category>

		<guid isPermaLink="false">http://www.derekentringer.com/blog/?p=218</guid>
		<description><![CDATA[
			
				
			
		

This tutorial is the final in a series of three. Part one of this tutorial outlined what is needed to detect a users upload, download, and latency between a Flash client and the Flash Media Server. Part two adds on the ability to detect which ports are available while connecting. In part three, we will be adding an external xml file that will allow you to compare connections to different Flash Media Servers in order to find which of them is the best connection for serving media. If you haven&#8217;t ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="clear:left; float:left; margin-top:10px; margin-bottom: 10px; margin-right:12px; margin-left:2px;">
			<a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2FwaS50d2VldG1lbWUuY29tL3NoYXJlP3VybD1odHRwJTNBJTJGJTJGd3d3LmRlcmVrZW50cmluZ2VyLmNvbSUyRmJsb2clMkZmbGFzaC1tZWRpYS1zZXJ2ZXItc3RyZWFtaW5nLXNwZWVkLXRlc3RpbmctcGFydC0zLWNvbXBhcmUtbXVsdGlwbGUtc2VydmVyLXJlc291cmNlcy1wb3J0LWNvbm5lY3Rpb25zLWRldGVjdC11cGxvYWQtZG93bmxvYWQtYW5kLWxhdGVuY3ktc3BlZWQlMkY="><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.derekentringer.com%2Fblog%2Fflash-media-server-streaming-speed-testing-part-3-compare-multiple-server-resources-port-connections-detect-upload-download-and-latency-speed%2F&amp;source=derekentringer&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p><!--PLAIN_TEXT--><br />
This tutorial is the final in a series of three. Part one of this tutorial outlined what is needed to detect a users upload, download, and latency between a Flash client and the Flash Media Server. Part two adds on the ability to detect which ports are available while connecting. In part three, we will be adding an external xml file that will allow you to compare connections to different Flash Media Servers in order to find which of them is the best connection for serving media. If you haven&#8217;t already read part one, you can find it <a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vYmxvZy9mbGFzaC1tZWRpYS1zZXJ2ZXItc3RyZWFtaW5nLXNwZWVkLXRlc3RpbmctcGFydC0xLWRldGVjdC11cGxvYWQtZG93bmxvYWQtYW5kLWxhdGVuY3ktc3BlZWRzLw==">here</a>, and part two is available <a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vYmxvZy9mbGFzaC1tZWRpYS1zZXJ2ZXItc3RyZWFtaW5nLXNwZWVkLXRlc3RpbmctcGFydC0yLWRldGVjdC11cGxvYWQtZG93bmxvYWQtYW5kLWxhdGVuY3ktc3BlZWRzLWFuZC1wb3J0LWNvbm5lY3Rpb24v">here</a>.</p>
<p>Again, Bandwidth detection is most important when connecting your users to the correctly compressed media to be streamed, recorded, or delivered via a Flash Media Server. This third example will walk you through the process of being able to detect a users download bandwidth, upload bandwidth, latency speeds, and the connected port between the client computer and the host server, along with iterating through multiple Flash Media Servers in an attempt to connect to the fastest and most available server. All of the code is Actionscript 2.0, and I&#8217;ve setup a Flash Media Server 3.5 to host the server side scripting. I use Influxis as my Flash Media Server host for all of these tutorials and smaller examples.</p>
<p>First, lets put together our Flash Actionscript. Here our goal is to setup our connection manager, and create a BandwidthInfo object that will call to our main.asc file (this is explained next) for sending packets to the Flash Media server to the client, and vice versa. We also will be creating an instance of our NetConnManager.as (also explained further down) which will allow the flash client to detect which port is best to connect to the Flash Server.</p>
<pre class="brush: as3;">
import NetConnManager;

var bestConn:Number;
var bestBandwidth:Number;
var connectBestConn:Number;
var whichServer:String;
var hasConnected:Boolean;
var currentlyChecking:Boolean;
var nextCheck:Number;
var upstreamsAvailable:Array = new Array();
var downstreamsAvailable:Array = new Array();
var theServers:Array;
var startTime:Number = getTimer();
var ncm:NetConnManager = new NetConnManager();
var ncmListener:Object = new Object();
var theServersXML:XML = new XML();
theServersXML.ignoreWhite = true;

ncmListener.ncConnected = function(evt:Object) {
	trace(&quot;[&quot;+Math.round(getTimer()-startTime)+&quot;ms] successfully connected using &quot;+evt.protocol+&quot;:&quot;+evt.port);
	conn_stat.text += &quot;[&quot;+Math.round(getTimer()-startTime)+&quot;ms] successfully connected using &quot;+evt.protocol+&quot;:&quot;+evt.port+newline;
};
ncmListener.ncFailedToConnect = function(evt:Object) {
	trace(&quot;failed to connect after &quot;+evt.timeout+&quot; ms&quot;);
	conn_stat.text += &quot;failed to connect after &quot;+evt.timeout+&quot; ms&quot;+newline;
};
ncm.addEventListener(&quot;ncConnected&quot;, ncmListener);
ncm.addEventListener(&quot;ncFailedToConnect&quot;, ncmListener);
ncm.connect(&quot;your.rtmphost.com&quot;, &quot;application_name&quot;);

theServersXML.load(&quot;xml/server_config.xml&quot;);
theServersXML.onLoad = function(success) {
	var index:Number = 0;
	theServers = new Array(this.firstChild.firstChild.childNodes.length);
	for (var aNode:XMLNode = this.firstChild.firstChild.firstChild; aNode != null; aNode=aNode.nextSibling) {
		theServers[index] = new Array(aNode.firstChild.childNodes.length);
		for (var subNode:XMLNode = aNode.firstChild; subNode != null; subNode=subNode.nextSibling) {
			theServers[index][subNode.nodeName] = subNode.firstChild.nodeValue;
		}
		index++;
	}
	//setup first connection
	checkConnection(theServers[0][&quot;host&quot;], theServers[0][&quot;app&quot;], 0);
};

function checkConnection(host, app, which) {

	currentlyChecking = true;

	rec_nc = new NetConnection();
	rec_nc.onStatus = function(info) {
		trace(&quot;Level: &quot;+info.level+&quot; Code: &quot;+info.code);
		if (info.code == &quot;NetConnection.Connect.Success&quot;) {
			trace(&quot;connected to: &quot;+this.uri);
			conn_stat.text += &quot;connected to: &quot;+this.uri+newline;
			startTest(rec_nc);
		} else if (info.code == &quot;NetConnection.Connect.Failed&quot; || info.code == &quot;NetConnection.Connect.Closed&quot;) {
			trace(&quot;no connection to app&quot;);
			conn_stat.text += &quot;error connection failed&quot;+newline;
		}
	};
	rec_nc.connect(&quot;rtmp://&quot;+host+&quot;/&quot;+app+&quot;/&quot;);

	function startTest(nc) {
		_global.bwInfo = new BandwidthInfo(nc);
		_global.bwInfo.start();
	}
	for (i=0; i&lt;1000; i++) {
		data += &quot;C-&gt;S&quot;;
	}
	function BandwidthInfo(nc) {
		this.nc = nc;
		this.maxLength = 10;
		this.bwInHistory = new Array(this.maxLength);
		this.bwInCtr = 0;
		this.bwOutHistory = new Array(this.maxLength);
		this.bwOutCtr = 0;
		this.pingHistory = new Array(this.maxLength);
		this.headIn = 0;
		this.headOut = 0;
		this.headPing = 0;
		this.bBWOutStop = false;
		this.bBWInStop = false;
		this.onBWInTimeout = function() {
			clearInterval(this.bwInfoTimeout);
			this.bwInfoTimeout = null;
			delete this.bwInfoTimeout;
			this.bBWInStop = true;

			if (this.bwInCtr == 0) {
				conn_stat.text += &quot;unable to receive data from server.&quot;+newline;
				this.abort(&quot;unable to receive data from server.&quot;);
				return;
			}
			this.stop();
		};
		this.onBWOutTimeout = function() {
			clearInterval(this.bwInfoTimeout);
			this.bwInfoTimeout = null;
			delete this.bwInfoTimeout;
			this.bBWOutStop = true;

			if (this.bwOutCtr == 0) {
				conn_stat.text += &quot;unable to receive data from server\n&quot;;
				this.abort(&quot;unable to send data to server\n----------\n&quot;);
				return;
			}
			trace(&quot;testing bandwidth from server&quot;);
			conn_stat.text += &quot;testing bandwidth from server&quot;+newline;
			this.bwInfoTimeout = setInterval(this, &quot;onBWInTimeout&quot;, 5*1000);
			this.serverToClient();
		};
		this.clientToServer = function() {
			this.time = getTimer();
			size = 0;
			bwinfo = this;
			this.nc.ack = function(pingVal) {
				if (!bwinfo.bBWOutStop) {
					bwinfo.bwOutHistory[bwinfo.headOut++%bwinfo.maxLength] = Math.floor(size/(getTimer()-bwinfo.time)*1000);
					bwinfo.pingHistory[bwinfo.headPing++%bwinfo.maxLength] = pingVal;
					bwinfo.nc.call(&quot;recData&quot;,0,data);
					size += 4000;
					bwinfo.bwOutCtr++;
				}
			};
			this.nc.call(&quot;recData&quot;,0,data);
			this.nc.call(&quot;recData&quot;,0,data);
		};
		this.serverToClient = function() {
			this.time = getTimer();
			size = 0;
			bwinfo = this;
			nc.onEcho = function() {
				if (!bwinfo.bBWInStop) {
					bwinfo.bwInHistory[bwinfo.headIn++%bwinfo.maxLength] = Math.floor(size/(getTimer()-bwinfo.time)*1000);
					this.call(&quot;echoData&quot;,0,0);
					size += 4000;
					bwinfo.bwInCtr++;
				}
			};
			nc.call(&quot;echoData&quot;,0,0);
			nc.call(&quot;echoData&quot;,0,0);
		};
		this.start = function() {
			conn_stat.text += &quot;testing upload speed&quot;+newline;
			trace(&quot;testing upload speed&quot;);
			clearInterval(this.bwInfoTimeout);
			this.bwInfoTimeout = null;
			delete this.bwInfoTimeout;
			this.bwInfoTimeout = setInterval(this, &quot;onBWOutTimeout&quot;, 5*1000);
			this.clientToServer();
		};
		this.stop = function() {
			this.nc = null;
			var ping_rtt = 0;
			var bw_out = 0;
			var bw_in = 0;
			for (var i = 0; i&lt;this.maxLength &amp;&amp; i&lt;this.bwOutCtr; i++) {
				ping_rtt = Math.max(ping_rtt, this.pingHistory[i]);
			}
			for (var i = 0; i&lt;this.maxLength &amp;&amp; i&lt;this.bwOutCtr; i++) {
				bw_out += this.bwOutHistory[i];
			}
			bw_out /= Math.min(this.maxLength, this.bwOutCtr);
			bw_out = Math.round((bw_out/1024)*8);
			for (var i = 0; i&lt;this.maxLength &amp;&amp; i&lt;this.bwInCtr; i++) {
				bw_in += this.bwInHistory[i];
			}
			bw_in /= Math.min(this.maxLength, this.bwInCtr);
			bw_in = Math.round((bw_in/1024)*8);

			//record
			upstreamsAvailable.push(bw_out);
			downstreamsAvailable.push(bw_in);

			var s;
			s = &quot;bandwidth results:\n&quot;;
			s += &quot;   upstream: &quot;+bw_out+&quot; kbps\n&quot;;
			s += &quot;   downstream: &quot;+bw_in+&quot; kbps\n&quot;;
			s += &quot;   latency: &quot;+ping_rtt+&quot; ms\n&quot;;
			if (ping_rtt&gt;1000) {
				s += &quot;network appears to have a very high delay\n&quot;;
			}
			if ((bw_in&gt;500) &amp;&amp; (bw_out&gt;200)) {
				s += &quot;connection supports high quality speed\n----------\n&quot;;
			} else if ((bw_in&gt;=200) &amp;&amp; (bw_out&gt;=100)) {
				s += &quot;connection supports good quality speed\n----------\n&quot;;
			} else if ((bw_in&gt;100) &amp;&amp; (bw_out&gt;80)) {
				s += &quot;connection supports mid quality speed\n----------\n&quot;;
			} else if ((bw_in&gt;20) &amp;&amp; (bw_out&gt;15)) {
				s += &quot;connection supports slow quality speed\n----------\n&quot;;
			} else {
				s += &quot;connection supports very slow quality speed\n----------\n&quot;;
			}
			trace(s);
			conn_stat.text += s+newline;
			currentlyChecking = false;
			nextCheck = which+1;
		};
		this.abort = function(reason) {
			conn_stat.text += &quot;failed &quot;+reason+newline;
			trace(&quot;failed &quot;+reason);
			currentlyChecking = false;
			nextCheck = which+1;
		};
	}

}

checkIfRunning = setInterval(this, &quot;checkConnBusy&quot;, 1000);

function checkConnBusy() {
	if (currentlyChecking == false) {
		if (nextCheck&lt;theServers.length) {
			checkConnection(theServers[nextCheck][&quot;host&quot;], theServers[nextCheck][&quot;app&quot;], nextCheck);
		} else {
			clearInterval(checkIfRunning);
			conn_stat.text += &quot;comparing connection&quot;+newline;
			compareConnections();
		}
	}
}

maxValueIndex = function (array) {
	mxm = array[0];
	for (i=0; i&lt;array.length; i++) {
		if (array[i]&gt;mxm) {
			mxm = array.index;
		}
	}
	return mxm;
};

Array.prototype.indexOf = function(value) {
	var i = 0;
	var l = this.length;
	var res = -1;
	for (i; i&lt;l; i++) {
		if (this[i] == value) {
			res = i;
			break;
		}
	}
	return res;
};

function compareConnections() {
	bestConn = maxValueIndex(upstreamsAvailable);
	bestBandwidth = maxValueIndex(upstreamsAvailable);
	connectBestConn = upstreamsAvailable.indexOf(bestConn);
	setConnectionsInterval = setInterval(this, &quot;setConnections&quot;, 500);
}
function setConnections(){
	if(theServers[connectBestConn][&quot;host&quot;] != undefined &amp;&amp; theServers[connectBestConn][&quot;app&quot;] != undefined){
		clearInterval(setConnectionsInterval);
		conn_stat.text += &quot;choosing server: rtmp://&quot;+theServers[connectBestConn][&quot;host&quot;]+&quot;/&quot;+theServers[connectBestConn][&quot;app&quot;]+newline;
	}else{
		clearInterval(setConnectionsInterval);
		conn_stat.text += &quot;connection to the server(s) has failed&quot;+newline;
	}
}
</pre>
<p>
In order to get the above to work correctly with your own Flash Media Server, you simply need to edit the following line. </p>
<pre class="brush: as3;">
ncm.connect(&quot;your.rtmphost.com&quot;, &quot;application_name&quot;);
</pre>
<p>
This is the path to the application which will hold our Main.asc file. You will also need to edit the xml/server_config.xml file in order to test against several different Flash Media Servers. This file serves as the que by which the flash client will verify and test each of the different connections, and finally pick the fastest one.</p>
<pre class="brush: xml;">
&lt;servers version=&quot;1&quot; xmlns=&quot;http://xspf.org/ns/0/&quot;&gt;
  &lt;serverList&gt;
    &lt;server&gt;
      &lt;host&gt;first_host&lt;/host&gt;
      &lt;app&gt;first_app&lt;/app&gt;
    &lt;/server&gt;
	&lt;server&gt;
      &lt;host&gt;second_host&lt;/host&gt;
      &lt;app&gt;second_app&lt;/app&gt;
    &lt;/server&gt;
  &lt;/serverList&gt;
&lt;/servers&gt;
</pre>
<p>
We now have our Flash file ready, and our servers setup within the server_config.xml.</p>
<p>Next, we want to create the server side code that will allow our final swf to call server side functions in order to return the correct upload, download, and latency values.</p>
<pre class="brush: as3;">
application.onAppStart = function (info){
	for ( i = 0; i &lt; 500; i++ ) {
		data += &quot;S-&gt;C&quot;;
	}
	Client.prototype.recData = function(data) {
		this.ping();
		var v = this.getStats();
		this.call(&quot;ack&quot;, 0, v.ping_rtt);
	}
	Client.prototype.echoData = function() {
		this.call(&quot;onEcho&quot;, 0, data);
	};
	Client.prototype.getBWInfo = function() {
		return this.getStats();
	};
	Client.prototype.onConnTimeout = function(){
		clearInterval( this.connTimeout );
		this.connTimeout = null;
		application.disconnect(this);
	}
}
application.onConnect = function(client_obj, id) {
	application.acceptConnection(client_obj);
}
</pre>
<p>
We also need our NetConnManager.as file which allows for multiple port detections.</p>
<pre class="brush: as3;">
import mx.events.EventDispatcher;
class NetConnManager extends Object {
	//EventDispatcher needs these
	var addEventListener:Function;
	var removeEventListener:Function;
	var dispatchEvent:Function;
	var dispatchQueue:Function;
	//Constants
	private var k_DEFAULTCONNLIST = [{protocol:&quot;rtmp&quot;, port:1935}, {protocol:&quot;rtmp&quot;, port:443}, {protocol:&quot;rtmpt&quot;, port:80}, {protocol:&quot;rtmps&quot;, port:443}];
	private var k_TIMEOUT:Number = 60000;
	//Variables
	private var m_connList:Array;
	private var m_serverName:String;
	private var m_appName:String;
	private var m_streamName:String;
	private var m_connListCounter:Number;
	private var m_flashComConnectTimeOut:Number;
	private var m_validNetConnection:NetConnection;
	//Constructor
	function NetConnManager() {
		EventDispatcher.initialize(this);
	}
	//Public
	//Initiates all the connection attempts.
	//Note: If no connection list is passed, the default list is used
	function connect(p_serverName:String, p_appName:String, p_connList:Array) {
		m_serverName = p_serverName;
		m_appName = p_appName;
		m_connList = (p_connList != undefined) ? p_connList : k_DEFAULTCONNLIST;
		//Set a timeout function, just in case we never connect successfully
		clearInterval(m_flashComConnectTimeOut);
		m_flashComConnectTimeOut = setInterval(this, &quot;onFlashComConnectTimeOut&quot;, k_TIMEOUT, k_TIMEOUT);
		//Creates a NetConnection for each of the protocols/ports listed in the m_connList list.
		//Connection attempts occur at intervals of 1.5 seconds. The first connection to succeed
		//will be used, all the others will be closed.
		for (var i = 0; i&lt;m_connList.length; i++) {
			this[&quot;nc&quot;+i] = new NetConnection();
			this[&quot;nc&quot;+i].owner = this;
			this[&quot;nc&quot;+i].connIndex = i;
			this[&quot;nc&quot;+i].onStatus = function(info) {
				this.pending = false;
				this.owner.m_validNetConnection = this.owner[&quot;nc&quot;+this.connIndex];
				if (info.code == &quot;NetConnection.Connect.Success&quot;) {
					clearInterval(this.owner.m_flashComConnectTimeOut);
					this.owner.dispatchEvent({type:&quot;ncConnected&quot;, nc:this.owner.m_validNetConnection, protocol:this.owner.m_connList[this.connIndex].protocol, port:this.owner.m_connList[this.connIndex].port});
					for (var i = 0; i&lt;this.owner.m_connList.length; i++) {
						if (i == this.connIndex) {
							continue;
						}
						if (this.owner[&quot;nc&quot;+i].pending) {
							clearInterval(this.owner[&quot;ncInt&quot;+i]);
							this.owner[&quot;nc&quot;+i].onStatus = null;
							this.owner[&quot;nc&quot;+i].close();
							this.owner[&quot;nc&quot;+i] = null;
							delete this.owner[&quot;nc&quot;+i];
						}
					}
				} else {
					trace(this.owner.m_connList[this.connIndex].protocol+&quot;: &quot;+this.owner.m_connList[this.connIndex].port+&quot;, onStatus: &quot;+info.code+&quot; : &quot;+info.description);
				}
			};
			this[&quot;nc&quot;+i].pending = true;
		}
		m_connListCounter = 0;
		nextConnect();
	}
	//Public
	//Returns the active connection or null if it does not exist.
	function getActiveConnection(Void):NetConnection {
		return m_validNetConnection == undefined ? null : m_validNetConnection;
	}
	function closeConnections() {
		m_validNetConnection.close();
	}
	//Private
	//Walks through the connection list to try every protocol.
	private function nextConnect(Void):Void {
		clearInterval(this[&quot;ncInt&quot;+m_connListCounter]);
		this[&quot;nc&quot;+m_connListCounter].connect(m_connList[m_connListCounter].protocol+&quot;://&quot;+m_serverName+&quot;:&quot;+m_connList[m_connListCounter].port+&quot;/&quot;+m_appName);
		if (m_connListCounter&lt;(m_connList.length-1)) {
			m_connListCounter++;
			this[&quot;ncInt&quot;+m_connListCounter] = setInterval(this, &quot;nextConnect&quot;, 1500);
		}
	}
	//Private
	//Cleans up all conenctions if none have succeeded by the timeout interval
	private function onFlashComConnectTimeOut(timeout:Number):Void {
		clearInterval(m_flashComConnectTimeOut);
		this.dispatchEvent({type:&quot;ncFailedToConnect&quot;, timeout:timeout});
		for (var i = 0; i&lt;m_connList.length; i++) {
			if (this[&quot;nc&quot;+i].pending) {
				clearInterval(this[&quot;ncInt&quot;+i]);
				this[&quot;nc&quot;+i].onStatus = null;
				this[&quot;nc&quot;+i].close();
				this[&quot;nc&quot;+i] = null;
				delete this[&quot;nc&quot;+i];
			}
		}
	}
}
</pre>
<p>
<a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vYmFuZHdpZHRoX2V4YW1wbGVfdGhyZWUv" target=\"_blank\">Click here to see your bandwidth results</a></p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vZG93bmxvYWRzL2JhbmR3aWR0aF9wYXJ0X3RocmVlLnppcA==">Download the source</a></p>
<p>This completes the tutorial series of the various methods to detect and stream media to flash clients. All three of these tutorials have built upon each other in order to provide solid methods for dynamically streaming any type of media via Flash Media Server.</p>
<p>Here are the links for this tutorial in its entirety:</p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vYmxvZy9mbGFzaC1tZWRpYS1zZXJ2ZXItc3RyZWFtaW5nLXNwZWVkLXRlc3RpbmctcGFydC0xLWRldGVjdC11cGxvYWQtZG93bmxvYWQtYW5kLWxhdGVuY3ktc3BlZWRzLw==">Flash Media Server Streaming Speed Testing [Part 1] &#8211; Detect Upload, Download, and Latency Speeds</a></p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vYmxvZy9mbGFzaC1tZWRpYS1zZXJ2ZXItc3RyZWFtaW5nLXNwZWVkLXRlc3RpbmctcGFydC0yLWRldGVjdC11cGxvYWQtZG93bmxvYWQtYW5kLWxhdGVuY3ktc3BlZWRzLWFuZC1wb3J0LWNvbm5lY3Rpb24v">Flash Media Server Streaming Speed Testing [Part 2] &#8211; Detect Upload, Download, and Latency Speeds, and Port Connection</a></p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vYmxvZy9mbGFzaC1tZWRpYS1zZXJ2ZXItc3RyZWFtaW5nLXNwZWVkLXRlc3RpbmctcGFydC0zLWNvbXBhcmUtbXVsdGlwbGUtc2VydmVyLXJlc291cmNlcy1wb3J0LWNvbm5lY3Rpb25zLWRldGVjdC11cGxvYWQtZG93bmxvYWQtYW5kLWxhdGVuY3ktc3BlZWQv">Flash Media Server Streaming Speed Testing [Part 3] &#8211; Compare Multiple Server Resources, Port Connections, Detect Upload, Download, and Latency Speed</a></p>
 <img src="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=218" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.derekentringer.com/blog/flash-media-server-streaming-speed-testing-part-3-compare-multiple-server-resources-port-connections-detect-upload-download-and-latency-speed/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Flash Media Server Streaming Speed Testing [Part 2] &#8211; Detect Upload, Download, and Latency Speeds, and Port Connection</title>
		<link>http://www.derekentringer.com/blog/flash-media-server-streaming-speed-testing-part-2-detect-upload-download-and-latency-speeds-and-port-connection/</link>
		<comments>http://www.derekentringer.com/blog/flash-media-server-streaming-speed-testing-part-2-detect-upload-download-and-latency-speeds-and-port-connection/#comments</comments>
		<pubDate>Tue, 12 May 2009 20:20:18 +0000</pubDate>
		<dc:creator>Derek J Entringer</dc:creator>
				<category><![CDATA[Code Samples]]></category>
		<category><![CDATA[FMS]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[bandwidth]]></category>
		<category><![CDATA[detection]]></category>
		<category><![CDATA[download]]></category>
		<category><![CDATA[flash media server]]></category>
		<category><![CDATA[latency]]></category>
		<category><![CDATA[port]]></category>
		<category><![CDATA[speed]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[upload]]></category>

		<guid isPermaLink="false">http://www.derekentringer.com/blog/?p=216</guid>
		<description><![CDATA[
			
				
			
		

This tutorial is the second in a series of three. Part one of this tutorial outlined what is needed to detect a users upload, download, and latency between a Flash client and the Flash Media Server. Part 2 adds on the ability to detect which ports are available while connecting.
Again, Bandwidth detection is most important when connecting your users to the correctly compressed media to be streamed, recorded, or delivered via a Flash Media Server. This second example will walk you through the process of being able to detect a ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="clear:left; float:left; margin-top:10px; margin-bottom: 10px; margin-right:12px; margin-left:2px;">
			<a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2FwaS50d2VldG1lbWUuY29tL3NoYXJlP3VybD1odHRwJTNBJTJGJTJGd3d3LmRlcmVrZW50cmluZ2VyLmNvbSUyRmJsb2clMkZmbGFzaC1tZWRpYS1zZXJ2ZXItc3RyZWFtaW5nLXNwZWVkLXRlc3RpbmctcGFydC0yLWRldGVjdC11cGxvYWQtZG93bmxvYWQtYW5kLWxhdGVuY3ktc3BlZWRzLWFuZC1wb3J0LWNvbm5lY3Rpb24lMkY="><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.derekentringer.com%2Fblog%2Fflash-media-server-streaming-speed-testing-part-2-detect-upload-download-and-latency-speeds-and-port-connection%2F&amp;source=derekentringer&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p><!--PLAIN_TEXT--><br />
This tutorial is the second in a series of three. Part one of this tutorial outlined what is needed to detect a users upload, download, and latency between a Flash client and the Flash Media Server. Part 2 adds on the ability to detect which ports are available while connecting.</p>
<p>Again, Bandwidth detection is most important when connecting your users to the correctly compressed media to be streamed, recorded, or delivered via a Flash Media Server. This second example will walk you through the process of being able to detect a users download bandwidth, upload bandwidth, and the latency between the client computer and the host server, along with iterating through all of the available ports that allow you to connect to the Flash Media Server. All of the code is Actionscript 2.0, and I&#8217;ve setup a Flash Media Server 3.5 to host the server side scripting. I use Influxis as my Flash Media Server host for all of these tutorials and smaller examples.</p>
<p>First, we will add our NetConnManager object which will use the NetConnManager.as exteranal Actionscript file. This is the first part of our Flash Actionscript code.</p>
<pre class="brush: as3;">
import NetConnManager;

var startTime:Number = getTimer();
var ncm:NetConnManager = new NetConnManager();
var ncmListener:Object = new Object();

ncmListener.ncConnected = function(evt:Object) {
	trace(&quot;[&quot;+Math.round(getTimer()-startTime)+&quot;ms] successfully connected using &quot;+evt.protocol+&quot;:&quot;+evt.port);
	conn_stat.text += &quot;[&quot;+Math.round(getTimer()-startTime)+&quot;ms] successfully connected using &quot;+evt.protocol+&quot;:&quot;+evt.port+newline;
};
ncmListener.ncFailedToConnect = function(evt:Object) {
	trace(&quot;failed to connect after &quot;+evt.timeout+&quot; ms&quot;);
	conn_stat.text += &quot;failed to connect after &quot;+evt.timeout+&quot; ms&quot;+newline;
};
ncm.addEventListener(&quot;ncConnected&quot;, ncmListener);
ncm.addEventListener(&quot;ncFailedToConnect&quot;, ncmListener);

ncm.connect(&quot;your.rtmphost.com&quot;, &quot;your_application_name&quot;);
</pre>
<p>In order to get the above to work correctly with your own Flash Media Server, you simply need to edit the following line.</p>
<pre class="brush: as3;">
ncm.connect(&quot;your.rtmphost.com&quot;, &quot;your_application_name&quot;);
</pre>
<p>The following code is the same as part one of this series of tutorials. If you have not read part one, you can find it <a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vYmxvZy9mbGFzaC1tZWRpYS1zZXJ2ZXItc3RyZWFtaW5nLXNwZWVkLXRlc3RpbmctcGFydC0xLWRldGVjdC11cGxvYWQtZG93bmxvYWQtYW5kLWxhdGVuY3ktc3BlZWRzLw==">here</a>.</p>
<pre class="brush: as3;">
function connectMe() {
	rec_nc = new NetConnection();
	rec_nc.onStatus = function(info) {
		trace(&quot;Level: &quot; + info.level + &quot; Code: &quot; + info.code);
		if (info.code == &quot;NetConnection.Connect.Success&quot;) {
			trace(&quot;connected to: &quot;+this.uri);
			conn_stat.text += &quot;connected to: &quot;+this.uri+newline;
			startTest(rec_nc);
		} else if (info.code == &quot;NetConnection.Connect.Failed&quot; || info.code == &quot;NetConnection.Connect.Closed&quot;) {
			trace(&quot;no connection to app&quot;);
			conn_stat.text += &quot;error connection failed&quot;+newline;
		}
	};
	rec_nc.connect(&quot;rtmp://y9cq49zks4.rtmphost.com/bwcheck/&quot;);
}

function startTest(nc) {
	_global.bwInfo = new BandwidthInfo(nc);
	_global.bwInfo.start();
}

for (i=0; i&lt;1000; i++) {
	data += &quot;C-&gt;S&quot;;
}
function BandwidthInfo(nc) {
	this.nc = nc;
	this.maxLength = 10;
	this.bwInHistory = new Array(this.maxLength);
	this.bwInCtr = 0;
	this.bwOutHistory = new Array(this.maxLength);
	this.bwOutCtr = 0;
	this.pingHistory = new Array(this.maxLength);
	this.headIn = 0;
	this.headOut = 0;
	this.headPing = 0;
	this.bBWOutStop = false;
	this.bBWInStop = false;
	this.onBWInTimeout = function() {
		clearInterval(this.bwInfoTimeout);
		this.bwInfoTimeout = null;
		delete this.bwInfoTimeout;
		this.bBWInStop = true;

		if (this.bwInCtr == 0) {
			conn_stat.text += &quot;unable to receive data from server.&quot;+newline;
			this.abort(&quot;unable to receive data from server.&quot;);
			return;
		}

		this.stop();
	};
	this.onBWOutTimeout = function() {
		clearInterval(this.bwInfoTimeout);
		this.bwInfoTimeout = null;
		delete this.bwInfoTimeout;
		this.bBWOutStop = true;

		if (this.bwOutCtr == 0) {
			conn_stat.text += &quot;unable to receive data from server&quot;+newline;
			this.abort(&quot;unable to send data to server&quot;);
			return;
		}

		trace(&quot;testing bandwidth from server&quot;);
		conn_stat.text += &quot;testing bandwidth from server&quot;+newline;
		this.bwInfoTimeout = setInterval(this, &quot;onBWInTimeout&quot;, 5*1000);
		this.serverToClient();
	};
	this.clientToServer = function() {
		this.time = getTimer();
		size = 0;
		bwinfo = this;
		this.nc.ack = function(pingVal) {
			if (!bwinfo.bBWOutStop) {
				bwinfo.bwOutHistory[bwinfo.headOut++%bwinfo.maxLength] = Math.floor(size/(getTimer()-bwinfo.time)*1000);
				bwinfo.pingHistory[bwinfo.headPing++%bwinfo.maxLength] = pingVal;
				bwinfo.nc.call(&quot;recData&quot;, 0, data);
				size += 4000;
				bwinfo.bwOutCtr++;
			}
		};
		this.nc.call(&quot;recData&quot;, 0, data);
		this.nc.call(&quot;recData&quot;, 0, data);
	};
	this.serverToClient = function() {
		this.time = getTimer();
		size = 0;
		bwinfo = this;
		nc.onEcho = function() {
			if (!bwinfo.bBWInStop) {
				bwinfo.bwInHistory[bwinfo.headIn++%bwinfo.maxLength] = Math.floor(size/(getTimer()-bwinfo.time)*1000);
				this.call(&quot;echoData&quot;, 0, 0);
				size += 4000;
				bwinfo.bwInCtr++;
			}
		};
		nc.call(&quot;echoData&quot;, 0, 0);
		nc.call(&quot;echoData&quot;, 0, 0);
	};
	this.start = function() {
		conn_stat.text += &quot;testing upload speed&quot;+newline;
		trace(&quot;testing upload speed&quot;);
		clearInterval(this.bwInfoTimeout);
		this.bwInfoTimeout = null;
		delete this.bwInfoTimeout;
		this.bwInfoTimeout = setInterval(this, &quot;onBWOutTimeout&quot;, 5*1000);
		this.clientToServer();
	};
	this.stop = function() {
		this.nc = null;
		var ping_rtt = 0;
		var bw_out = 0;
		var bw_in = 0;
		for (var i = 0; i&lt;this.maxLength &amp;&amp; i&lt;this.bwOutCtr; i++) {
			ping_rtt = Math.max(ping_rtt, this.pingHistory[i]);
		}
		for (var i = 0; i&lt;this.maxLength &amp;&amp; i&lt;this.bwOutCtr; i++) {
			bw_out += this.bwOutHistory[i];
		}
		bw_out /= Math.min(this.maxLength, this.bwOutCtr);
		bw_out = Math.round((bw_out/1024)*8);
		for (var i = 0; i&lt;this.maxLength &amp;&amp; i&lt;this.bwInCtr; i++) {
			bw_in += this.bwInHistory[i];
		}
		bw_in /= Math.min(this.maxLength, this.bwInCtr);
		bw_in = Math.round((bw_in/1024)*8);
		var s;
		s = &quot;bandwidth results:\n&quot;;
		s += &quot;   upstream: &quot;+bw_out+&quot; kbps\n&quot;;
		s += &quot;   downstream: &quot;+bw_in+&quot; kbps\n&quot;;
		s += &quot;   latency: &quot;+ping_rtt+&quot; ms\n&quot;;
		if (ping_rtt&gt;1000) {
			s += &quot;network appears to have a very high delay\n\n&quot;;
		}
		if ((bw_in&gt;500) &amp;&amp; (bw_out&gt;200)) {
			s += &quot;connection supports high quality speed\n\n&quot;;
		} else if ((bw_in&gt;=200) &amp;&amp; (bw_out&gt;=100)) {
			s += &quot;connection supports good quality speed\n\n&quot;;
		} else if ((bw_in&gt;100) &amp;&amp; (bw_out&gt;80)) {//(bw_in&lt;250) &amp;&amp; (bw_out&lt;80) &amp;&amp;
			s += &quot;connection supports mid quality speed\n\n&quot;;
		} else if ((bw_in&gt;20) &amp;&amp; (bw_out&gt;15)) {
			s += &quot;connection supports slow quality speed\n\n&quot;;
		} else {
			s += &quot;connection supports very slow quality speed\n\n&quot;;
		}
		trace(s);
		conn_stat.text += s+newline;
	};
	this.abort = function(reason) {
		conn_stat.text += &quot;failed &quot;+reason+newline;
		trace(&quot;failed &quot;+reason);
	};
}

connectMe();
</pre>
<p>
Next, lets setup our NetConnManager.as file. This external Actionscript class allows the ncm object to iterate through all of the available ports on the Flash Media Server, and lets you know which port it has connected successfully on the server. This is useful if you are dealing with a firewall that has blocked the default port of 1935.</p>
<pre class="brush: as3;">
import mx.events.EventDispatcher;
class NetConnManager extends Object {
	//EventDispatcher needs these
	var addEventListener:Function;
	var removeEventListener:Function;
	var dispatchEvent:Function;
	var dispatchQueue:Function;
	//Constants
	private var k_DEFAULTCONNLIST = [{protocol:&quot;rtmp&quot;, port:1935}, {protocol:&quot;rtmp&quot;, port:443}, {protocol:&quot;rtmpt&quot;, port:80}, {protocol:&quot;rtmps&quot;, port:443}];
	private var k_TIMEOUT:Number = 60000;
	//Variables
	private var m_connList:Array;
	private var m_serverName:String;
	private var m_appName:String;
	private var m_streamName:String;
	private var m_connListCounter:Number;
	private var m_flashComConnectTimeOut:Number;
	private var m_validNetConnection:NetConnection;
	//Constructor
	function NetConnManager() {
		EventDispatcher.initialize(this);
	}
	//Public
	//Initiates all the connection attempts.
	//Note: If no connection list is passed, the default list is used
	function connect(p_serverName:String, p_appName:String, p_connList:Array) {
		m_serverName = p_serverName;
		m_appName = p_appName;
		m_connList = (p_connList != undefined) ? p_connList : k_DEFAULTCONNLIST;
		//Set a timeout function, just in case we never connect successfully
		clearInterval(m_flashComConnectTimeOut);
		m_flashComConnectTimeOut = setInterval(this, &quot;onFlashComConnectTimeOut&quot;, k_TIMEOUT, k_TIMEOUT);
		//Creates a NetConnection for each of the protocols/ports listed in the m_connList list.
		//Connection attempts occur at intervals of 1.5 seconds. The first connection to succeed
		//will be used, all the others will be closed.
		for (var i = 0; i&lt;m_connList.length; i++) {
			this[&quot;nc&quot;+i] = new NetConnection();
			this[&quot;nc&quot;+i].owner = this;
			this[&quot;nc&quot;+i].connIndex = i;
			this[&quot;nc&quot;+i].onStatus = function(info) {
				this.pending = false;
				this.owner.m_validNetConnection = this.owner[&quot;nc&quot;+this.connIndex];
				if (info.code == &quot;NetConnection.Connect.Success&quot;) {
					clearInterval(this.owner.m_flashComConnectTimeOut);
					this.owner.dispatchEvent({type:&quot;ncConnected&quot;, nc:this.owner.m_validNetConnection, protocol:this.owner.m_connList[this.connIndex].protocol, port:this.owner.m_connList[this.connIndex].port});
					for (var i = 0; i&lt;this.owner.m_connList.length; i++) {
						if (i == this.connIndex) {
							continue;
						}
						if (this.owner[&quot;nc&quot;+i].pending) {
							clearInterval(this.owner[&quot;ncInt&quot;+i]);
							this.owner[&quot;nc&quot;+i].onStatus = null;
							this.owner[&quot;nc&quot;+i].close();
							this.owner[&quot;nc&quot;+i] = null;
							delete this.owner[&quot;nc&quot;+i];
						}
					}
				} else {
					trace(this.owner.m_connList[this.connIndex].protocol+&quot;: &quot;+this.owner.m_connList[this.connIndex].port+&quot;, onStatus: &quot;+info.code+&quot; : &quot;+info.description);
				}
			};
			this[&quot;nc&quot;+i].pending = true;
		}
		m_connListCounter = 0;
		nextConnect();
	}
	//Public
	//Returns the active connection or null if it does not exist.
	function getActiveConnection(Void):NetConnection {
		return m_validNetConnection == undefined ? null : m_validNetConnection;
	}
	function closeConnections() {
		m_validNetConnection.close();
	}
	//Private
	//Walks through the connection list to try every protocol.
	private function nextConnect(Void):Void {
		clearInterval(this[&quot;ncInt&quot;+m_connListCounter]);
		this[&quot;nc&quot;+m_connListCounter].connect(m_connList[m_connListCounter].protocol+&quot;://&quot;+m_serverName+&quot;:&quot;+m_connList[m_connListCounter].port+&quot;/&quot;+m_appName);
		if (m_connListCounter&lt;(m_connList.length-1)) {
			m_connListCounter++;
			this[&quot;ncInt&quot;+m_connListCounter] = setInterval(this, &quot;nextConnect&quot;, 1500);
		}
	}
	//Private
	//Cleans up all conenctions if none have succeeded by the timeout interval
	private function onFlashComConnectTimeOut(timeout:Number):Void {
		clearInterval(m_flashComConnectTimeOut);
		this.dispatchEvent({type:&quot;ncFailedToConnect&quot;, timeout:timeout});
		for (var i = 0; i&lt;m_connList.length; i++) {
			if (this[&quot;nc&quot;+i].pending) {
				clearInterval(this[&quot;ncInt&quot;+i]);
				this[&quot;nc&quot;+i].onStatus = null;
				this[&quot;nc&quot;+i].close();
				this[&quot;nc&quot;+i] = null;
				delete this[&quot;nc&quot;+i];
			}
		}
	}
}
</pre>
<p>
We now have our Flash file ready, but we still need our application setup on the Flash Server. Create a new application on your Flash Media Server, and name it however you want. That application name then goes into the connect function above, along with the url for the server.</p>
<p>Next, we want to create the server side code that will allow our final swf to call server side functions in order to return the correct upload, download, and latency values.</p>
<pre class="brush: as3;">
application.onAppStart = function (info){
	for ( i = 0; i &lt; 500; i++ ) {
		data += &quot;S-&gt;C&quot;;
	}
	Client.prototype.recData = function(data) {
		this.ping();
		var v = this.getStats();
		this.call(&quot;ack&quot;, 0, v.ping_rtt);
	}
	Client.prototype.echoData = function() {
		this.call(&quot;onEcho&quot;, 0, data);
	};
	Client.prototype.getBWInfo = function() {
		return this.getStats();
	};
	Client.prototype.onConnTimeout = function(){
		clearInterval( this.connTimeout );
		this.connTimeout = null;
		application.disconnect(this);
	}
}
application.onConnect = function(client_obj, id) {
	application.acceptConnection(client_obj);
}
</pre>
<p>
And, there you have it. These scripts allow you to check the users upload and download bandwidth capabilities, check how slow the server is allowing you to connect using latency detection, and provides you with the correct port that may be available from within your current network.</p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vYmFuZHdpZHRoX2V4YW1wbGVfdHdvLw==" target=\"_blank\">Click here to see your bandwidth results</a></p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vZG93bmxvYWRzL2JhbmR3aWR0aF9wYXJ0X3R3by56aXA=">Download the source</a></p>
<p>Finally, be sure to have a look at my next tutorial using these same techniques. In part three, I will be adding the functionality to check multiple servers using this same code.</p>
<p>Here are the links for this tutorial in its entirety:</p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vYmxvZy9mbGFzaC1tZWRpYS1zZXJ2ZXItc3RyZWFtaW5nLXNwZWVkLXRlc3RpbmctcGFydC0xLWRldGVjdC11cGxvYWQtZG93bmxvYWQtYW5kLWxhdGVuY3ktc3BlZWRzLw==">Flash Media Server Streaming Speed Testing [Part 1] &#8211; Detect Upload, Download, and Latency Speeds</a></p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vYmxvZy9mbGFzaC1tZWRpYS1zZXJ2ZXItc3RyZWFtaW5nLXNwZWVkLXRlc3RpbmctcGFydC0yLWRldGVjdC11cGxvYWQtZG93bmxvYWQtYW5kLWxhdGVuY3ktc3BlZWRzLWFuZC1wb3J0LWNvbm5lY3Rpb24v">Flash Media Server Streaming Speed Testing [Part 2] &#8211; Detect Upload, Download, and Latency Speeds, and Port Connection</a></p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vYmxvZy9mbGFzaC1tZWRpYS1zZXJ2ZXItc3RyZWFtaW5nLXNwZWVkLXRlc3RpbmctcGFydC0zLWNvbXBhcmUtbXVsdGlwbGUtc2VydmVyLXJlc291cmNlcy1wb3J0LWNvbm5lY3Rpb25zLWRldGVjdC11cGxvYWQtZG93bmxvYWQtYW5kLWxhdGVuY3ktc3BlZWQv">Flash Media Server Streaming Speed Testing [Part 3] &#8211; Compare Multiple Server Resources, Port Connections, Detect Upload, Download, and Latency Speed</a></p>
 <img src="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=216" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.derekentringer.com/blog/flash-media-server-streaming-speed-testing-part-2-detect-upload-download-and-latency-speeds-and-port-connection/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Flash Media Server Streaming Speed Testing [Part 1] &#8211; Detect Upload, Download, and Latency Speeds</title>
		<link>http://www.derekentringer.com/blog/flash-media-server-streaming-speed-testing-part-1-detect-upload-download-and-latency-speeds/</link>
		<comments>http://www.derekentringer.com/blog/flash-media-server-streaming-speed-testing-part-1-detect-upload-download-and-latency-speeds/#comments</comments>
		<pubDate>Tue, 12 May 2009 20:18:19 +0000</pubDate>
		<dc:creator>Derek J Entringer</dc:creator>
				<category><![CDATA[Code Samples]]></category>
		<category><![CDATA[FMS]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[bandwidth]]></category>
		<category><![CDATA[detection]]></category>
		<category><![CDATA[download]]></category>
		<category><![CDATA[flash media server]]></category>
		<category><![CDATA[Influxis]]></category>
		<category><![CDATA[latency]]></category>
		<category><![CDATA[speed]]></category>
		<category><![CDATA[streaming media]]></category>
		<category><![CDATA[upload]]></category>

		<guid isPermaLink="false">http://www.derekentringer.com/blog/?p=214</guid>
		<description><![CDATA[
			
				
			
		

This tutorial is the first in a series of three that builds upon the first Flash Bandwidth &#038; Port Detection tutorial I created a while back. These three articles look to make it even easier than the original post, and go more in depth on some of the streaming options, and have better structured server side code.
If you are interested in the original article, you can find it here.
Bandwidth detection is most important when connecting your users to the correctly compressed media to be streamed, recorded, or delivered via a ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="clear:left; float:left; margin-top:10px; margin-bottom: 10px; margin-right:12px; margin-left:2px;">
			<a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2FwaS50d2VldG1lbWUuY29tL3NoYXJlP3VybD1odHRwJTNBJTJGJTJGd3d3LmRlcmVrZW50cmluZ2VyLmNvbSUyRmJsb2clMkZmbGFzaC1tZWRpYS1zZXJ2ZXItc3RyZWFtaW5nLXNwZWVkLXRlc3RpbmctcGFydC0xLWRldGVjdC11cGxvYWQtZG93bmxvYWQtYW5kLWxhdGVuY3ktc3BlZWRzJTJG"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.derekentringer.com%2Fblog%2Fflash-media-server-streaming-speed-testing-part-1-detect-upload-download-and-latency-speeds%2F&amp;source=derekentringer&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p><!--PLAIN_TEXT--><br />
This tutorial is the first in a series of three that builds upon the first Flash Bandwidth &#038; Port Detection tutorial I created a while back. These three articles look to make it even easier than the original post, and go more in depth on some of the streaming options, and have better structured server side code.</p>
<p>If you are interested in the original article, you can find it <a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vYmxvZy9mbGFzaC1iYW5kd2lkdGgtcG9ydC1kZXRlY3Rpb24v">here</a>.</p>
<p>Bandwidth detection is most important when connecting your users to the correctly compressed media to be streamed, recorded, or delivered via a Flash Media Server. This example will walk you through the process of being able to detect a users download bandwidth, upload bandwidth, and the latency between the client computer and the host server. All of the code is Actionscript 2.0, and I&#8217;ve setup a Flash Media Server 3.5 to host the server side scripting. I use Influxis as my Flash Media Server host for all of these tutorials and smaller examples.</p>
<p>Now, onto the code.</p>
<p>First, lets put together our Flash Actionscript. Here our goal is to setup our connection manager, and create a BandwidthInfo object that will call to our main.asc file (this is explained next) for sending packets to the Flash Media server to the client, and vice versa.</p>
<pre class="brush: as3;">
function connectMe() {
	rec_nc = new NetConnection();
	rec_nc.onStatus = function(info) {
		trace(&quot;Level: &quot; + info.level + &quot; Code: &quot; + info.code);
		if (info.code == &quot;NetConnection.Connect.Success&quot;) {
			trace(&quot;connected to: &quot;+this.uri);
			conn_stat.text += &quot;connected to: &quot;+this.uri+newline;
			startTest(rec_nc);
		} else if (info.code == &quot;NetConnection.Connect.Failed&quot; || info.code == &quot;NetConnection.Connect.Closed&quot;) {
			trace(&quot;no connection to app&quot;);
			conn_stat.text += &quot;error connection failed&quot;+newline;
		}
	};
	rec_nc.connect(&quot;rtmp://your.host.com/application_name/&quot;);
}

function startTest(nc) {
	_global.bwInfo = new BandwidthInfo(nc);
	_global.bwInfo.start();
}

for (i=0; i&lt;1000; i++) {
	data += &quot;C-&gt;S&quot;;
}
function BandwidthInfo(nc) {
	this.nc = nc;
	this.maxLength = 10;
	this.bwInHistory = new Array(this.maxLength);
	this.bwInCtr = 0;
	this.bwOutHistory = new Array(this.maxLength);
	this.bwOutCtr = 0;
	this.pingHistory = new Array(this.maxLength);
	this.headIn = 0;
	this.headOut = 0;
	this.headPing = 0;
	this.bBWOutStop = false;
	this.bBWInStop = false;
	this.onBWInTimeout = function() {
		clearInterval(this.bwInfoTimeout);
		this.bwInfoTimeout = null;
		delete this.bwInfoTimeout;
		this.bBWInStop = true;

		if (this.bwInCtr == 0) {
			conn_stat.text += &quot;unable to receive data from server.&quot;+newline;
			this.abort(&quot;unable to receive data from server.&quot;);
			return;
		}

		this.stop();
	};
	this.onBWOutTimeout = function() {
		clearInterval(this.bwInfoTimeout);
		this.bwInfoTimeout = null;
		delete this.bwInfoTimeout;
		this.bBWOutStop = true;

		if (this.bwOutCtr == 0) {
			conn_stat.text += &quot;unable to receive data from server&quot;+newline;
			this.abort(&quot;unable to send data to server&quot;);
			return;
		}

		trace(&quot;testing bandwidth from server&quot;);
		conn_stat.text += &quot;testing bandwidth from server&quot;+newline;
		this.bwInfoTimeout = setInterval(this, &quot;onBWInTimeout&quot;, 5*1000);
		this.serverToClient();
	};
	this.clientToServer = function() {
		this.time = getTimer();
		size = 0;
		bwinfo = this;
		this.nc.ack = function(pingVal) {
			if (!bwinfo.bBWOutStop) {
				bwinfo.bwOutHistory[bwinfo.headOut++%bwinfo.maxLength] = Math.floor(size/(getTimer()-bwinfo.time)*1000);
				bwinfo.pingHistory[bwinfo.headPing++%bwinfo.maxLength] = pingVal;
				bwinfo.nc.call(&quot;recData&quot;, 0, data);
				size += 4000;
				bwinfo.bwOutCtr++;
			}
		};
		this.nc.call(&quot;recData&quot;, 0, data);
		this.nc.call(&quot;recData&quot;, 0, data);
	};
	this.serverToClient = function() {
		this.time = getTimer();
		size = 0;
		bwinfo = this;
		nc.onEcho = function() {
			if (!bwinfo.bBWInStop) {
				bwinfo.bwInHistory[bwinfo.headIn++%bwinfo.maxLength] = Math.floor(size/(getTimer()-bwinfo.time)*1000);
				this.call(&quot;echoData&quot;, 0, 0);
				size += 4000;
				bwinfo.bwInCtr++;
			}
		};
		nc.call(&quot;echoData&quot;, 0, 0);
		nc.call(&quot;echoData&quot;, 0, 0);
	};
	this.start = function() {
		conn_stat.text += &quot;testing upload speed&quot;+newline;
		trace(&quot;testing upload speed&quot;);
		clearInterval(this.bwInfoTimeout);
		this.bwInfoTimeout = null;
		delete this.bwInfoTimeout;
		this.bwInfoTimeout = setInterval(this, &quot;onBWOutTimeout&quot;, 5*1000);
		this.clientToServer();
	};
	this.stop = function() {
		this.nc = null;
		var ping_rtt = 0;
		var bw_out = 0;
		var bw_in = 0;
		for (var i = 0; i&lt;this.maxLength &amp;&amp; i&lt;this.bwOutCtr; i++) {
			ping_rtt = Math.max(ping_rtt, this.pingHistory[i]);
		}
		for (var i = 0; i&lt;this.maxLength &amp;&amp; i&lt;this.bwOutCtr; i++) {
			bw_out += this.bwOutHistory[i];
		}
		bw_out /= Math.min(this.maxLength, this.bwOutCtr);
		bw_out = Math.round((bw_out/1024)*8);
		for (var i = 0; i&lt;this.maxLength &amp;&amp; i&lt;this.bwInCtr; i++) {
			bw_in += this.bwInHistory[i];
		}
		bw_in /= Math.min(this.maxLength, this.bwInCtr);
		bw_in = Math.round((bw_in/1024)*8);
		var s;
		s += &quot;bandwidth\n&quot;;
		s += &quot;   upstream: &quot;+bw_out+&quot; kbps\n&quot;;
		s += &quot;   downstream: &quot;+bw_in+&quot; kbps\n&quot;;
		s += &quot;   latency: &quot;+ping_rtt+&quot; ms\n&quot;;
		if (ping_rtt&gt;1000) {
			s += &quot;network appears to have a very high delay\n\n&quot;;
		}
		if ((bw_in&gt;500) &amp;&amp; (bw_out&gt;200)) {
			s += &quot;connection supports high quality speed\n\n&quot;;
		} else if ((bw_in&gt;=200) &amp;&amp; (bw_out&gt;=100)) {
			s += &quot;connection supports good quality speed\n\n&quot;;
		} else if ((bw_in&gt;100) &amp;&amp; (bw_out&gt;80)) {//(bw_in&lt;250) &amp;&amp; (bw_out&lt;80) &amp;&amp;
			s += &quot;connection supports mid quality speed\n\n&quot;;
		} else if ((bw_in&gt;20) &amp;&amp; (bw_out&gt;15)) {
			s += &quot;connection supports slow quality speed\n\n&quot;;
		} else {
			s += &quot;connection supports very slow quality speed\n\n&quot;;
		}
		trace(s);
		conn_stat.text += s+newline;
	};
	this.abort = function(reason) {
		conn_stat.text += &quot;failed &quot;+reason+newline;
		trace(&quot;failed &quot;+reason);
	};
}

connectMe();
</pre>
<p>
In order to get the above to work correctly with your own Flash Media Server, you simply need to edit the following line.</p>
<pre class="brush: as3;">
rec_nc.connect(&quot;rtmp://your.host.com/application_name/&quot;);
</pre>
<p>
We now have our Flash file ready, but we still need our application setup on the Flash Server. Create a new application on your Flash Media Server, and name it however you want. That application name then goes into the connect function above, along with the url for the server.</p>
<p>Next, we want to create the server side code that will allow our final swf to call server side functions in order to return the correct upload, download, and latency values.</p>
<pre class="brush: as3;">
application.onAppStart = function (info){
	for ( i = 0; i &lt; 500; i++ ) {
		data += &quot;S-&gt;C&quot;;
	}
	Client.prototype.recData = function(data) {
		this.ping();
		var v = this.getStats();
		this.call(&quot;ack&quot;, 0, v.ping_rtt);
	}
	Client.prototype.echoData = function() {
		this.call(&quot;onEcho&quot;, 0, data);
	};
	Client.prototype.getBWInfo = function() {
		return this.getStats();
	};
	Client.prototype.onConnTimeout = function(){
		clearInterval( this.connTimeout );
		this.connTimeout = null;
		application.disconnect(this);
	}
}
application.onConnect = function(client_obj, id) {
	application.acceptConnection(client_obj);
}
</pre>
<p>
<a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vYmFuZHdpZHRoX2V4YW1wbGVfb25lLw==" target=\"_blank\">Click here to see your bandwidth results</a></p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vZG93bmxvYWRzL2JhbmR3aWR0aF9wYXJ0X29uZS56aXA=">Download the source</a></p>
<p>Next, take a look at how you can use the above code along with Port Detection to be sure that your users can connect to your Flash Media Server applications from behind certain firewall setting in the <a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vYmxvZy9iYW5kd2lkdGgtdXBsb2FkLWRvd25sb2FkLWxhdGVuY3ktc3BlZWQtYW5kLXBvcnQtZGV0ZWN0aW9uLXBhcnQtMg==">part two</a> of this three part tutorial series.</p>
<p>Here are the links for this tutorial in its entirety:</p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vYmxvZy9mbGFzaC1tZWRpYS1zZXJ2ZXItc3RyZWFtaW5nLXNwZWVkLXRlc3RpbmctcGFydC0xLWRldGVjdC11cGxvYWQtZG93bmxvYWQtYW5kLWxhdGVuY3ktc3BlZWRzLw==">Flash Media Server Streaming Speed Testing [Part 1] &#8211; Detect Upload, Download, and Latency Speeds</a></p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vYmxvZy9mbGFzaC1tZWRpYS1zZXJ2ZXItc3RyZWFtaW5nLXNwZWVkLXRlc3RpbmctcGFydC0yLWRldGVjdC11cGxvYWQtZG93bmxvYWQtYW5kLWxhdGVuY3ktc3BlZWRzLWFuZC1wb3J0LWNvbm5lY3Rpb24v">Flash Media Server Streaming Speed Testing [Part 2] &#8211; Detect Upload, Download, and Latency Speeds, and Port Connection</a></p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vYmxvZy9mbGFzaC1tZWRpYS1zZXJ2ZXItc3RyZWFtaW5nLXNwZWVkLXRlc3RpbmctcGFydC0zLWNvbXBhcmUtbXVsdGlwbGUtc2VydmVyLXJlc291cmNlcy1wb3J0LWNvbm5lY3Rpb25zLWRldGVjdC11cGxvYWQtZG93bmxvYWQtYW5kLWxhdGVuY3ktc3BlZWQv">Flash Media Server Streaming Speed Testing [Part 3] &#8211; Compare Multiple Server Resources, Port Connections, Detect Upload, Download, and Latency Speed</a></p>
 <img src="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=214" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.derekentringer.com/blog/flash-media-server-streaming-speed-testing-part-1-detect-upload-download-and-latency-speeds/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Streaming A Live Event Using Mogulus</title>
		<link>http://www.derekentringer.com/blog/streaming-a-live-event-using-mogulus/</link>
		<comments>http://www.derekentringer.com/blog/streaming-a-live-event-using-mogulus/#comments</comments>
		<pubDate>Tue, 21 Apr 2009 22:42:23 +0000</pubDate>
		<dc:creator>Derek J Entringer</dc:creator>
				<category><![CDATA[Code Samples]]></category>
		<category><![CDATA[FMS]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[General Discussion]]></category>
		<category><![CDATA[chat]]></category>
		<category><![CDATA[contact]]></category>
		<category><![CDATA[derek]]></category>
		<category><![CDATA[derekentringer.com]]></category>
		<category><![CDATA[entringer]]></category>
		<category><![CDATA[event]]></category>
		<category><![CDATA[live]]></category>
		<category><![CDATA[mogulus]]></category>
		<category><![CDATA[streaming]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://www.derekentringer.com/blog/?p=187</guid>
		<description><![CDATA[
			
				
			
		

One of my clients (borrispowell.com) has an upcoming fashion show, and we thought it would be pretty useful to promote the show as a streaming live production from his website the night of the unveiling of his latest creations. With this being one of his larger shows, we thought we would allow fans around the world to be able to watch the performance online, and for free.

Mogulus live broadcast tool seemed to be able to pull off the task of streaming the show for a pretty decent cost, and with ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="clear:left; float:left; margin-top:10px; margin-bottom: 10px; margin-right:12px; margin-left:2px;">
			<a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2FwaS50d2VldG1lbWUuY29tL3NoYXJlP3VybD1odHRwJTNBJTJGJTJGd3d3LmRlcmVrZW50cmluZ2VyLmNvbSUyRmJsb2clMkZzdHJlYW1pbmctYS1saXZlLWV2ZW50LXVzaW5nLW1vZ3VsdXMlMkY="><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.derekentringer.com%2Fblog%2Fstreaming-a-live-event-using-mogulus%2F&amp;source=derekentringer&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p><!--PLAIN_TEXT--><br />
One of my clients (borrispowell.com) has an upcoming fashion show, and we thought it would be pretty useful to promote the show as a streaming live production from his website the night of the unveiling of his latest creations. With this being one of his larger shows, we thought we would allow fans around the world to be able to watch the performance online, and for free.</p>
<p><img src="http://derekentringer.com/img/mogulus_logo_black.jpg" /></p>
<p>Mogulus live broadcast tool seemed to be able to pull off the task of streaming the show for a pretty decent cost, and with only about 15 minutes of setup time. Their free streaming service only allows for 50 concurrent connected viewers, and for a streaming data rate of around 700kbps, but it may do the trick. We still have to get a feel for how the online streaming shows popularity is going to play out. If you shell out the $350 per month, you can have HD quality streaming, remove all of the ads, have access to a white label player, be provided deep analytics for your page viewers, and more importantly&#8230;have unlimited amounts of viewers.</p>
<p>So, with all of that said, I decided to set up my own account, get it streaming on my own site with chat enabled and some color customizations, and I was quite pleased with the results.</p>
<p>Feel free to check if I&#8217;m online, and to chat if you like <img src='http://www.derekentringer.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2RlcmVrZW50cmluZ2VyLmNvbS9saXZlLw==">Click Here To Video Chat With Me Online</a></p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2RlcmVrZW50cmluZ2VyLmNvbS9saXZlLw=="><img src="http://derekentringer.com/img/mogulus_screenshot.jpg" /></a></p>
 <img src="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=187" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.derekentringer.com/blog/streaming-a-live-event-using-mogulus/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flash Bandwidth &amp; Port Detection</title>
		<link>http://www.derekentringer.com/blog/flash-bandwidth-port-detection/</link>
		<comments>http://www.derekentringer.com/blog/flash-bandwidth-port-detection/#comments</comments>
		<pubDate>Wed, 29 Oct 2008 18:42:16 +0000</pubDate>
		<dc:creator>Derek J Entringer</dc:creator>
				<category><![CDATA[Code Samples]]></category>
		<category><![CDATA[FMS]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[1935]]></category>
		<category><![CDATA[443]]></category>
		<category><![CDATA[80]]></category>
		<category><![CDATA[actionscript]]></category>
		<category><![CDATA[bandwidth]]></category>
		<category><![CDATA[calculate]]></category>
		<category><![CDATA[check]]></category>
		<category><![CDATA[detection]]></category>
		<category><![CDATA[flash media server]]></category>
		<category><![CDATA[netConnection]]></category>
		<category><![CDATA[port]]></category>
		<category><![CDATA[RTMP]]></category>
		<category><![CDATA[rtmps]]></category>
		<category><![CDATA[rtmpt]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://derekentringer.com/blog/?p=118</guid>
		<description><![CDATA[
			
				
			
		

Being able to detect a users bandwidth can be an important part of serving them streaming video. Using their bandwidth you can stream a video that will play well using their connection speeds.
The first step is to create our NetConnection.as file. This is used by our bandwidth checking script to connect to our Flash Media Server via RTMP, select an available port, and talk with our bw_check.asc to report the users available bandwidth.

import mx.events.EventDispatcher;
class NCManager extends Object {
	// EventDispatcher needs these
	var addEventListener:Function;
	var removeEventListener:Function;
	var dispatchEvent:Function;
	var dispatchQueue:Function;
	// Constants
	private var k_DEFAULTCONNLIST = [{protocol:&#34;rtmp&#34;, ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="clear:left; float:left; margin-top:10px; margin-bottom: 10px; margin-right:12px; margin-left:2px;">
			<a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2FwaS50d2VldG1lbWUuY29tL3NoYXJlP3VybD1odHRwJTNBJTJGJTJGd3d3LmRlcmVrZW50cmluZ2VyLmNvbSUyRmJsb2clMkZmbGFzaC1iYW5kd2lkdGgtcG9ydC1kZXRlY3Rpb24lMkY="><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.derekentringer.com%2Fblog%2Fflash-bandwidth-port-detection%2F&amp;source=derekentringer&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p><!--PLAIN_TEXT--><br />
Being able to detect a users bandwidth can be an important part of serving them streaming video. Using their bandwidth you can stream a video that will play well using their connection speeds.</p>
<p>The first step is to create our NetConnection.as file. This is used by our bandwidth checking script to connect to our Flash Media Server via RTMP, select an available port, and talk with our bw_check.asc to report the users available bandwidth.</p>
<pre class="brush: as3;">
import mx.events.EventDispatcher;
class NCManager extends Object {
	// EventDispatcher needs these
	var addEventListener:Function;
	var removeEventListener:Function;
	var dispatchEvent:Function;
	var dispatchQueue:Function;
	// Constants
	private var k_DEFAULTCONNLIST = [{protocol:&quot;rtmp&quot;, port:1935}, {protocol:&quot;rtmp&quot;, port:443}, {protocol:&quot;rtmpt&quot;, port:80}, {protocol:&quot;rtmps&quot;, port:443}];
	private var k_TIMEOUT:Number = 60000;
	// Variables
	private var m_connList:Array;
	private var m_serverName:String;
	private var m_appName:String;
	private var m_streamName:String;
	private var m_connListCounter:Number;
	private var m_flashComConnectTimeOut:Number;
	private var m_validNetConnection:NetConnection;
	// Constructor
	function NCManager() {
		trace(&quot;NCManager initialized&quot;);
		EventDispatcher.initialize(this);
	}
	// Public
	// Initiates all the connection attempts.
	// Note: If no connection list is passed, the default list is used
	function connect(p_serverName:String, p_appName:String, p_connList:Array) {
		m_serverName = p_serverName;
		m_appName = p_appName;
		m_connList = (p_connList != undefined) ? p_connList : k_DEFAULTCONNLIST;
		// Set a timeout function, just in case we never connect successfully
		clearInterval(m_flashComConnectTimeOut);
		m_flashComConnectTimeOut = setInterval(this, &quot;onFlashComConnectTimeOut&quot;, k_TIMEOUT, k_TIMEOUT);
		// Creates a NetConnection for each of the protocols/ports listed in the m_connList list.
		// Connection attempts occur at intervals of 1.5 seconds. The first connection to succeed
		// will be used, all the others will be closed.
		for (var i = 0; i&lt;m_connList.length; i++) {
			this[&quot;nc&quot;+i] = new NetConnection();
			this[&quot;nc&quot;+i].owner = this;
			this[&quot;nc&quot;+i].connIndex = i;
			this[&quot;nc&quot;+i].onBWDone = function(p_bw) {
				this.owner.dispatchEvent({type:&quot;ncBandWidth&quot;, kbps:p_bw});
			};
			this[&quot;nc&quot;+i].onBWCheck = function(counter) {
				return ++counter;
			};
			this[&quot;nc&quot;+i].onStatus = function(info) {
				this.pending = false;
				this.owner.m_validNetConnection = this.owner[&quot;nc&quot;+this.connIndex];
				if (info.code == &quot;NetConnection.Connect.Success&quot;) {
					// We have a successfull connection
					clearInterval(this.owner.m_flashComConnectTimeOut);
					this.owner.dispatchEvent({type:&quot;ncConnected&quot;, nc:this.owner.m_validNetConnection, protocol:this.owner.m_connList[this.connIndex].protocol, port:this.owner.m_connList[this.connIndex].port});
					for (var i = 0; i&lt;this.owner.m_connList.length; i++) {
						if (i == this.connIndex) {
							continue;
						}
						if (this.owner[&quot;nc&quot;+i].pending) {
							clearInterval(this.owner[&quot;ncInt&quot;+i]);
							this.owner[&quot;nc&quot;+i].onStatus = null;
							this.owner[&quot;nc&quot;+i].close();
							this.owner[&quot;nc&quot;+i] = null;
							delete this.owner[&quot;nc&quot;+i];
						}
					}
				} else {
					trace(this.owner.m_connList[this.connIndex].protocol+&quot;: &quot;+this.owner.m_connList[this.connIndex].port+&quot;, onStatus: &quot;+info.code+&quot; : &quot;+info.description);
				}
			};
			this[&quot;nc&quot;+i].pending = true;
		}
		m_connListCounter = 0;
		nextConnect();
	}
	// Public
	// Returns the stream length for a given stream name.
	// Note: requires matching server function to be present on the server.
	function getStreamLength(streamName:String) {
		var res = new Object();
		res.owner = this;
		res.name = streamName;
		res.onResult = function(p_length) {
			this.owner.dispatchEvent({type:&quot;ncStreamLength&quot;, length:p_length, name:res.name});
		};
		m_validNetConnection.call(&quot;getStreamLength&quot;,res,streamName);
	}
	// Public
	// Calls a server-side function to initiate a bandwdith check.
	// Note: requires matching server function to be present on the server.
	function getBandWidth(Void):Void {
		m_validNetConnection.call(&quot;checkBandwidth&quot;,null);
	}
	// Public
	// Returns the active connection or null if it does not exist.
	function getActiveConnection(Void):NetConnection {
		trace(m_validNetConnection == undefined ? null : m_validNetConnection);
		return m_validNetConnection == undefined ? null : m_validNetConnection;
	}
	function closeConnections() {
		trace(&quot;CLOSING= &quot;+m_validNetConnection);
		m_validNetConnection.close();
	}
	// Private
	// Walks through the connection list to try every protocol.
	private function nextConnect(Void):Void {
		clearInterval(this[&quot;ncInt&quot;+m_connListCounter]);
		this[&quot;nc&quot;+m_connListCounter].connect(m_connList[m_connListCounter].protocol+&quot;://&quot;+m_serverName+&quot;:&quot;+m_connList[m_connListCounter].port+&quot;/&quot;+m_appName);
		if (m_connListCounter&lt;(m_connList.length-1)) {
			m_connListCounter++;
			this[&quot;ncInt&quot;+m_connListCounter] = setInterval(this, &quot;nextConnect&quot;, 1500);
		}
	}
	// Private
	// Cleans up all conenctions if none have succeeded by the timeout interval
	private function onFlashComConnectTimeOut(timeout:Number):Void {
		clearInterval(m_flashComConnectTimeOut);
		this.dispatchEvent({type:&quot;ncFailedToConnect&quot;, timeout:timeout});
		for (var i = 0; i&lt;m_connList.length; i++) {
			if (this[&quot;nc&quot;+i].pending) {
				clearInterval(this[&quot;ncInt&quot;+i]);
				this[&quot;nc&quot;+i].onStatus = null;
				this[&quot;nc&quot;+i].close();
				this[&quot;nc&quot;+i] = null;
				delete this[&quot;nc&quot;+i];
			}
		}
	}
}
</pre>
<p>The second step is to create our FMS server side code. The bwcheck.asc file sends packets at a size of about 16Kb from the FMS and calculates the response latency over the users network.</p>
<pre class="brush: as3;">
application.onConnect = function(p_client, p_autoSenseBW) {
	this.acceptConnection(p_client);
	if (p_autoSenseBW)
		this.calculateClientBw(p_client);
	else
		p_client.call(&quot;onBWDone&quot;);
}
Client.prototype.getStreamLength = function(p_streamName) {
	return Stream.length(p_streamName);
}
Client.prototype.checkBandwidth = function() {
	application.calculateClientBw(this);
}
application.calculateClientBw = function(p_client) {
	p_client.payload = new Array();
	for (var i=0; i&lt;1200; i++){
		p_client.payload[i] = Math.random();//16K approx
	}
	var res = new Object();
	res.latency = 0;
	res.cumLatency = 1;
	res.bwTime = 0;
	res.count = 0;
	res.sent = 0;
	res.client = p_client;
	var stats = p_client.getStats();
	var now = (new Date()).getTime()/1;
	res.pakSent = new Array();
	res.pakRecv = new Array();
	res.beginningValues = {b_down:stats.bytes_out, b_up:stats.bytes_in, time:now};
	res.onResult = function(p_val) {
		var now = (new Date()).getTime()/1;
		this.pakRecv[this.count] = now;
		this.count++;
		var timePassed = (now - this.beginningValues.time);
		if (this.count == 1) {
			this.latency = Math.min(timePassed, 800);
			this.latency = Math.max(this.latency, 10);
		}
		if ( this.count == 2 &amp;&amp; (timePassed&lt;2000)) {
			this.pakSent[res.sent++] = now;
			this.cumLatency++;
			this.client.call(&quot;onBWCheck&quot;, res, this.client.payload);
		} else if ( this.sent == this.count ) {
			//see if we need to normalize latency
			if ( this.latency &gt;= 100 ) {
				if (  this.pakRecv[1] - this.pakRecv[0] &gt; 1000 ) {
					this.latency = 100;
				}
			}
			delete this.client.payload;
			//got back responses for all the packets compute the bandwidth
			var stats = this.client.getStats();
			var deltaDown = (stats.bytes_out - this.beginningValues.b_down)*8/1000;
			var deltaTime = ((now - this.beginningValues.time) - (this.latency * this.cumLatency) )/1000;
			if ( deltaTime &lt;= 0 )
				deltaTime = (now - this.beginningValues.time)/1000;

			var kbitDown = Math.round(deltaDown/deltaTime);
			trace(&quot;onBWDone: kbitDown = &quot; + kbitDown + &quot;, deltaDown= &quot; + deltaDown + &quot;, deltaTime = &quot; + deltaTime + &quot;, latency = &quot; + this.latency + &quot;KBytes &quot; + (stats.bytes_out - this.beginningValues.b_down)/1024) ;
			this.client.call(&quot;onBWDone&quot;, null, kbitDown,  deltaDown, deltaTime, this.latency );
		}
	}
	res.pakSent[res.sent++] = now;
	p_client.call(&quot;onBWCheck&quot;, res, &quot;&quot;);
	res.pakSent[res.sent++] = now;
	p_client.call(&quot;onBWCheck&quot;, res, p_client.payload);
}
</pre>
<p>Third step. Bring everything together within our flash file, and print our results to text fields on the stage.</p>
<pre class="brush: as3;">
stop();

import NCManager;

var ns:NetStream;
var fileName:String;
var k_STARTTIME:Number = getTimer();

//server info
var k_SERVERNAME:String = &quot;server_name&quot;;
var k_APPNAME:String = &quot;application_folder_name&quot;;
var k_ASC_PATH:String = &quot;rtmp://&quot;+k_SERVERNAME+&quot;/&quot;+k_APPNAME+&quot;/bwcheck.asc&quot;;

nc = new NetConnection();
nc.connect(k_ASC_PATH,true);
nc.onStatus = function(info) {
	trace(&quot;Level: &quot;+info.level+&quot; Code: &quot;+info.code);
	if (info.code == &quot;NetConnection.Connect.Success&quot;) {
		trace(&quot;loaded: &quot;+this.uri);
	}
};

//the variable p_bw returned by bwcheck.asc holds a value equal to the detected download speed in kilobits per second
//for best results we should serve video that is encoded at a rate less than or equal to kbitsDown
NetConnection.prototype.onBWDone = function(p_bw) {
	trace(&quot;BANDWIDTH= &quot;+p_bw);
	bandwidth.text = &quot;Bandwidth= &quot;+p_bw
	//close the Netconnection to bwcheck
	this.close();
};

NetConnection.prototype.onBWCheck = function() {
	return ++counter;
};

var ncm:NCManager = new NCManager();
var ncmListener:Object = new Object();

//fires when it has found a successfull connection
ncmListener.ncConnected = function(evt:Object) {
	trace(&quot;[&quot;+Math.round(getTimer()-k_STARTTIME)+&quot;ms] Successfully connected using &quot;+evt.protocol+&quot;:&quot;+evt.port);
	port.text = &quot;connected using &quot;+evt.protocol+&quot;:&quot;+evt.port
};

//fires when it has timed-out trying to find a good connection
ncmListener.ncFailedToConnect = function(evt:Object) {
	trace(&quot;Failed to connect after &quot;+evt.timeout+&quot; milliseconds.&quot;);
};

//fires when streamlength has been detected
ncmListener.ncStreamLength = function(evt:Object) {
	trace(&quot;[&quot;+Math.round(getTimer()-k_STARTTIME)+&quot;ms] Streamlength of &quot;+evt.name+&quot; is &quot;+evt.length+&quot; seconds.&quot;);
};

//set listeners on the NCM instance
ncm.addEventListener(&quot;ncConnected&quot;,ncmListener);
ncm.addEventListener(&quot;ncFailedToConnect&quot;,ncmListener);
ncm.addEventListener(&quot;ncBandWidth&quot;,ncmListener);
ncm.addEventListener(&quot;ncStreamLength&quot;,ncmListener);

//call the connect method on NCM instance
ncm.connect(k_SERVERNAME,k_APPNAME);
</pre>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vZmxhc2hfYmFuZHdpZHRoX2FuZF9wb3J0X2RldGVjdGlvbi8=" target=\"_blank\">Click here to see your bandwidth results.</a></p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vZG93bmxvYWRzL2ZsYXNoX2JhbmR3aWR0aF9hbmRfcG9ydF9kZXRlY3Rpb24uemlw">Download the source</a></p>
<p>This tutorial has been updated, and is available in the following 3-part series:</p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vYmxvZy9mbGFzaC1tZWRpYS1zZXJ2ZXItc3RyZWFtaW5nLXNwZWVkLXRlc3RpbmctcGFydC0xLWRldGVjdC11cGxvYWQtZG93bmxvYWQtYW5kLWxhdGVuY3ktc3BlZWRzLw==">Flash Media Server Streaming Speed Testing [Part 1] &#8211; Detect Upload, Download, and Latency Speeds</a></p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vYmxvZy9mbGFzaC1tZWRpYS1zZXJ2ZXItc3RyZWFtaW5nLXNwZWVkLXRlc3RpbmctcGFydC0yLWRldGVjdC11cGxvYWQtZG93bmxvYWQtYW5kLWxhdGVuY3ktc3BlZWRzLWFuZC1wb3J0LWNvbm5lY3Rpb24v">Flash Media Server Streaming Speed Testing [Part 2] &#8211; Detect Upload, Download, and Latency Speeds, and Port Connection</a></p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vYmxvZy9mbGFzaC1tZWRpYS1zZXJ2ZXItc3RyZWFtaW5nLXNwZWVkLXRlc3RpbmctcGFydC0zLWNvbXBhcmUtbXVsdGlwbGUtc2VydmVyLXJlc291cmNlcy1wb3J0LWNvbm5lY3Rpb25zLWRldGVjdC11cGxvYWQtZG93bmxvYWQtYW5kLWxhdGVuY3ktc3BlZWQv">Flash Media Server Streaming Speed Testing [Part 3] &#8211; Compare Multiple Server Resources, Port Connections, Detect Upload, Download, and Latency Speed</a></p>
 <img src="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=118" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.derekentringer.com/blog/flash-bandwidth-port-detection/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>AS3 MP3 Player</title>
		<link>http://www.derekentringer.com/blog/as3-mp3-player/</link>
		<comments>http://www.derekentringer.com/blog/as3-mp3-player/#comments</comments>
		<pubDate>Fri, 05 Sep 2008 16:22:33 +0000</pubDate>
		<dc:creator>Derek J Entringer</dc:creator>
				<category><![CDATA[Code Samples]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[as3]]></category>
		<category><![CDATA[download]]></category>
		<category><![CDATA[mp3]]></category>
		<category><![CDATA[player]]></category>

		<guid isPermaLink="false">http://derekentringer.com/blog/?p=70</guid>
		<description><![CDATA[
			
				
			
		

I have an upcoming project that will require an mp3 player that can load multiple songs, and let users choose which track they would like to listen to. I created this as a test, and will be developing it further for use on the site itself.
The player loads in mp3&#8242;s from an external file based on xml settings.
Here&#8217;s the actionscript 3 that is involved:

var getMusic:URLRequest;
var music:Sound = new Sound();
var soundChannel:SoundChannel;
var currentSound:Sound = music;
var pos:Number;
var currentIndex:Number = 0;
var songPlaying:Boolean = false;
var xml:XML;
var songlist:XMLList;
//preloader
function loadProgress(event:ProgressEvent):void {
    var percentLoaded:Number = ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="clear:left; float:left; margin-top:10px; margin-bottom: 10px; margin-right:12px; margin-left:2px;">
			<a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2FwaS50d2VldG1lbWUuY29tL3NoYXJlP3VybD1odHRwJTNBJTJGJTJGd3d3LmRlcmVrZW50cmluZ2VyLmNvbSUyRmJsb2clMkZhczMtbXAzLXBsYXllciUyRg=="><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.derekentringer.com%2Fblog%2Fas3-mp3-player%2F&amp;source=derekentringer&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p><!--PLAIN_TEXT--><br />
I have an upcoming project that will require an mp3 player that can load multiple songs, and let users choose which track they would like to listen to. I created this as a test, and will be developing it further for use on the site itself.</p>
<p>The player loads in mp3&#8242;s from an external file based on xml settings.</p>
<p>Here&#8217;s the actionscript 3 that is involved:</p>
<pre class="brush: as3;">
var getMusic:URLRequest;
var music:Sound = new Sound();
var soundChannel:SoundChannel;
var currentSound:Sound = music;
var pos:Number;
var currentIndex:Number = 0;
var songPlaying:Boolean = false;
var xml:XML;
var songlist:XMLList;
//preloader
function loadProgress(event:ProgressEvent):void {
    var percentLoaded:Number = event.bytesLoaded/event.bytesTotal;
    percentLoaded = Math.round(percentLoaded * 100);
	if(percentLoaded &lt; 20){
		trace(&quot;loading&quot;);
	} else{
	}
}
function completeHandler(event):void {
    trace(&quot;DONE&quot;);
}
//load the xml
var loader:URLLoader = new URLLoader(); //create a new URLLoader Object
loader.addEventListener(Event.COMPLETE, whenLoaded); //add an event listener to that object
loader.load(new URLRequest(&quot;songs.xml&quot;)); //Requests our xml file that contains our song data
function whenLoaded(e:Event):void //WhenLoaded function(see line 50) runs when line 50 is complete
{
	xml = new XML(e.target.data);
	songlist = xml.song; //accesses our song tag in our xml file
	getMusic = new URLRequest(songlist[0].url);//get music from songlist
	music.load(getMusic);//load music
	soundChannel = music.play();//plays the music
	songTXT.text = songlist[0].title; //gets song name from xml
	artistTXT.text = songlist[0].artist; //gets artist name
	albumTXT.text = songlist[0].album;  //gets album name
	soundChannel.addEventListener(Event.SOUND_COMPLETE, nextSong);//runs the next song function when a song completes
}
//add mouse events
next_btn.addEventListener(MouseEvent.CLICK, nextSong);
prev_btn.addEventListener(MouseEvent.CLICK, prevSong);
pause_btn.addEventListener(MouseEvent.CLICK,pauseSong);
/*--------Skips Songs----------------------------------------*/
function nextSong(e:Event):void
{
	if (currentIndex &gt; (songlist.length() - 1))
	{
		currentIndex++;
	}
	else
	{
		currentIndex = 0;
	}
	var nextReq:URLRequest = new URLRequest(songlist[currentIndex].url);
	var nextTitle:Sound = new Sound(nextReq);
	soundChannel.stop();
	songTXT.text = songlist[currentIndex].title;
	artistTXT.text = songlist[currentIndex].artist;
	albumTXT.text = songlist[currentIndex].album;
	soundChannel = nextTitle.play();
	songPlaying = true;
	currentSound = nextTitle;
	soundChannel.addEventListener(Event.SOUND_COMPLETE, nextSong);
}
//manage songs, and load their info
function prevSong(e:Event):void
{
	if (currentIndex &lt; 0)
	{
		currentIndex--;
	}
	else
	{
		currentIndex = songlist.length() - 1;
	}
	var nextReq:URLRequest = new URLRequest(songlist[currentIndex].url);
	var prevTitle:Sound = new Sound(nextReq);
	soundChannel.stop();
	songTXT.text = songlist[currentIndex].title;
	artistTXT.text = songlist[currentIndex].artist;
	albumTXT.text = songlist[currentIndex].album;
	soundChannel = prevTitle.play();
	songPlaying = true;
	currentSound = prevTitle;
	soundChannel.addEventListener(Event.SOUND_COMPLETE, nextSong);
}
function pauseSong(e:Event):void
{
	pos = soundChannel.position; //pause song at current position
	soundChannel.stop(); //stop sound
	songPlaying = false; // songPlaying is now equal to false
	play_btn.addEventListener(MouseEvent.CLICK,playSong);
}
function playSong(e:Event):void
{
	if(songPlaying == false) //if songplaying is equal to false run function below
	{
		soundChannel = currentSound.play(pos); //play from current position(used if it was paused)
		soundChannel.addEventListener(Event.SOUND_COMPLETE, nextSong);//run nextSong function if current song is complete
		songPlaying = true; //songPlaying is now true
		play_btn.removeEventListener(MouseEvent.CLICK,playSong);
	}
}
</pre>
<p>
Here is the xml:</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;ISO-8859-1&quot;?&gt;
&lt;ipod&gt;
	&lt;song&gt;
		&lt;title&gt;My Hero&lt;/title&gt;
		&lt;artist&gt;Foo Fighters&lt;/artist&gt;
		&lt;album&gt;The Colour And The Shape&lt;/album&gt;
		&lt;url&gt;songs/Hero.mp3&lt;/url&gt;
	&lt;/song&gt;
	&lt;song&gt;
		&lt;title&gt;Learn To Fly&lt;/title&gt;
		&lt;artist&gt;Foo Fighters&lt;/artist&gt;
		&lt;album&gt;Theres Nothing Left To Lose&lt;/album&gt;
		&lt;url&gt;songs/Fly.mp3&lt;/url&gt;
	&lt;/song&gt;
&lt;/ipod&gt;
</pre>
<p>
<a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vZG93bmxvYWRzL21wM19wbGF5ZXIuemlw">Download the source</a> (Note: The mp3&#8242;s used are not included in the download)</p>
 <img src="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=70" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.derekentringer.com/blog/as3-mp3-player/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Myspace Flash AS2 RSS Feed Reader</title>
		<link>http://www.derekentringer.com/blog/myspace-flash-as2-rss-feed-reader/</link>
		<comments>http://www.derekentringer.com/blog/myspace-flash-as2-rss-feed-reader/#comments</comments>
		<pubDate>Fri, 22 Aug 2008 18:14:53 +0000</pubDate>
		<dc:creator>Derek J Entringer</dc:creator>
				<category><![CDATA[Code Samples]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[as2]]></category>
		<category><![CDATA[feed]]></category>
		<category><![CDATA[Myspace]]></category>
		<category><![CDATA[reader]]></category>
		<category><![CDATA[rss]]></category>

		<guid isPermaLink="false">http://derekentringer.com/blog/?p=68</guid>
		<description><![CDATA[
			
				
			
		

A very simple RSS feed reader that displays links off to your blog created using Actionscript 2.

stop();
//create the xml object
xmlLoad = new XML();
xmlLoad.load(_root.feed);
xmlLoad.ignoreWhite = true;
xmlLoad.onLoad = function(success){
	//if successful
	if(success &#38;&#38; xmlLoad.status == 0){
		//reset the text
		xml_text=&#34;&#34;;
		//list of items
		var xmlItems:XML = xmlLoad.firstChild.firstChild;
		for (var m = 0; m&#38;lt;xmlItems.childNodes.length; m++) {
			//grab each item
			if (xmlItems.childNodes[m].nodeName == &#34;item&#34;) {
				for (var n = 0; n&#38;lt;xmlItems.childNodes[m].childNodes.length; n++) {
					if (xmlItems.childNodes[m].childNodes[n].nodeName == &#34;link&#34;) {
						//grab the link of the item
						itemlink=xmlItems.childNodes[m].childNodes[n].firstChild.toString();
					}
					if (xmlItems.childNodes[m].childNodes[n].nodeName == &#34;title&#34;) {
						//grab the title of the item
						itemtitle=xmlItems.childNodes[m].childNodes[n].firstChild.toString();
					}
				}
				//add the current item
				xml_text+= &#34;&#38;lt;a href=\&#34;&#34;+itemlink+&#34;\&#34;&#38;gt;&#34;+itemtitle+&#34;&#38;lt;/a&#38;gt;&#38;lt;br&#38;gt;&#38;lt;br&#38;gt;&#34;;
			}
		}
	}
	//set the text
	xml_holder.text = xml_text;
}

The only library item needed ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="clear:left; float:left; margin-top:10px; margin-bottom: 10px; margin-right:12px; margin-left:2px;">
			<a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2FwaS50d2VldG1lbWUuY29tL3NoYXJlP3VybD1odHRwJTNBJTJGJTJGd3d3LmRlcmVrZW50cmluZ2VyLmNvbSUyRmJsb2clMkZteXNwYWNlLWZsYXNoLWFzMi1yc3MtZmVlZC1yZWFkZXIlMkY="><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.derekentringer.com%2Fblog%2Fmyspace-flash-as2-rss-feed-reader%2F&amp;source=derekentringer&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p><!--PLAIN_TEXT--><br />
A very simple RSS feed reader that displays links off to your blog created using Actionscript 2.</p>
<pre class="brush: as3;">
stop();
//create the xml object
xmlLoad = new XML();
xmlLoad.load(_root.feed);
xmlLoad.ignoreWhite = true;
xmlLoad.onLoad = function(success){
	//if successful
	if(success &amp;&amp; xmlLoad.status == 0){
		//reset the text
		xml_text=&quot;&quot;;
		//list of items
		var xmlItems:XML = xmlLoad.firstChild.firstChild;
		for (var m = 0; m&amp;lt;xmlItems.childNodes.length; m++) {
			//grab each item
			if (xmlItems.childNodes[m].nodeName == &quot;item&quot;) {
				for (var n = 0; n&amp;lt;xmlItems.childNodes[m].childNodes.length; n++) {
					if (xmlItems.childNodes[m].childNodes[n].nodeName == &quot;link&quot;) {
						//grab the link of the item
						itemlink=xmlItems.childNodes[m].childNodes[n].firstChild.toString();
					}
					if (xmlItems.childNodes[m].childNodes[n].nodeName == &quot;title&quot;) {
						//grab the title of the item
						itemtitle=xmlItems.childNodes[m].childNodes[n].firstChild.toString();
					}
				}
				//add the current item
				xml_text+= &quot;&amp;lt;a href=\&quot;&quot;+itemlink+&quot;\&quot;&amp;gt;&quot;+itemtitle+&quot;&amp;lt;/a&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&quot;;
			}
		}
	}
	//set the text
	xml_holder.text = xml_text;
}
</pre>
<p>The only library item needed is a TextArea component, placed on the stage with an instance name of &#8220;xml_holder&#8221;.</p>
<p>In order to embed and display this on your Myspace page (or anywhere really) you only need the following code:</p>
<pre class="brush: xml;">
&amp;lt;object data=&quot;http://www.derekentringer.com/downloads/xml_reader/xml_reader.swf?feed=http://www.derekentringer.com/blog/feed/&quot; type=&quot;application/x-shockwave-flash&quot; width=&quot;300&quot; height=&quot;450&quot;&amp;gt;&amp;lt;param name=&quot;movie&quot; value=&quot;http://www.derekentringer.com/downloads/xml_reader/xml_reader.swf?feed=http://www.derekentringer.com/blog/feed/&quot;/&amp;gt;&amp;lt;/object&amp;gt;&lt;br /&gt;
</pre>
<p>Be sure to change the &#8220;?feed&#8221; variable to the url of your own RSS feed.</p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vZG93bmxvYWRzL3htbF9yZWFkZXIveG1sX3JlYWRlci5odG1s" target=\"_blank\">Click here for a preview</a></p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vZG93bmxvYWRzL3htbF9yZWFkZXIuemlw" target=\"_blank\">Download the source</a></p>
 <img src="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=68" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.derekentringer.com/blog/myspace-flash-as2-rss-feed-reader/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>.htaccess and SEO</title>
		<link>http://www.derekentringer.com/blog/htaccess-and-seo/</link>
		<comments>http://www.derekentringer.com/blog/htaccess-and-seo/#comments</comments>
		<pubDate>Thu, 21 Aug 2008 21:52:53 +0000</pubDate>
		<dc:creator>Derek J Entringer</dc:creator>
				<category><![CDATA[Code Samples]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[301]]></category>
		<category><![CDATA[htaccess]]></category>
		<category><![CDATA[links]]></category>
		<category><![CDATA[redirect]]></category>

		<guid isPermaLink="false">http://derekentringer.com/blog/?p=59</guid>
		<description><![CDATA[
			
				
			
		
Inbound Links
A .htaccess file can be an SEO&#8217;s vital friend. When visitors hit your site with either www.yourdomain.com or yourdomain.com, it splits your inbound links into two separate pages. This can have effects on your Google Page Rank. By correctly creating and implementing a .htaccess file at your server root, you can improve your website ranking.
To change the url in the browser before the page loads you can use two different methods.
Here, the url will always contain the www. before the domain name:
RewriteCond %{HTTP_HOST} .
RewriteCond %{HTTP_HOST} !^www\.derekentringer\.com [NC]
RewriteRule (.*) http://www.derekentringer.com/$1 ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="clear:left; float:left; margin-top:10px; margin-bottom: 10px; margin-right:12px; margin-left:2px;">
			<a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2FwaS50d2VldG1lbWUuY29tL3NoYXJlP3VybD1odHRwJTNBJTJGJTJGd3d3LmRlcmVrZW50cmluZ2VyLmNvbSUyRmJsb2clMkZodGFjY2Vzcy1hbmQtc2VvJTJG"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.derekentringer.com%2Fblog%2Fhtaccess-and-seo%2F&amp;source=derekentringer&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p><b>Inbound Links</b></p>
<p>A .htaccess file can be an SEO&#8217;s vital friend. When visitors hit your site with either www.yourdomain.com or yourdomain.com, it splits your inbound links into two separate pages. This can have effects on your Google Page Rank. By correctly creating and implementing a .htaccess file at your server root, you can improve your website ranking.</p>
<p>To change the url in the browser before the page loads you can use two different methods.</p>
<p>Here, the url will always contain the www. before the domain name:</p>
<p>RewriteCond %{HTTP_HOST} .<br />
RewriteCond %{HTTP_HOST} !^www\.derekentringer\.com [NC]<br />
RewriteRule (.*) http://www.derekentringer.com/$1 [R=301,L]</p>
<p>Here, you can take the www. away:</p>
<p>RewriteCond %{HTTP_HOST} .<br />
RewriteCond %{HTTP_HOST} !^www\.derekentringer\.com [NC]<br />
RewriteRule (.*) http://derekentringer.com/$1 [R=301,L]</p>
<p>By deciding which of these ways of keeping your inbound links will work best, you can improve your search engine results.</p>
<p>
<b>301 Redirects</b></p>
<p>Redirect 301 / http://www.yournewdomain.com/</p>
<p>The above code is to be used when pointing multiple domain names to one domain (the main site) . This is often done by businesses wishing to protect their trademark by purchasing similar names and various top level domain names (TLD) for their company. This is also good for companies wishing to capture type in traffic of users who type keywords straight into the toolbars or their url area of the browser.</p>
<p>By using both of these methods, you can keep a tight seal around all of your inbound links, improve your SEO and Google Page Rank, and keep the files on your server more organized.</p>
<p>
<b>Keep Directory Index File Name Out of Your URL</b></p>
<p>Sometimes it just looks nicer to not have a url such as http://www.derekentringer.com/index.php. All we want is http://www.derekentringer.com.<br />
Using your .htaccess you can eliminate it easily. You can also specify any directories that you might not want it to parse out the index file.</p>
<p># Main Index exclude<br />
DirectoryIndex index.php<br />
RewriteCond $1 !^(index\.php|robots\.txt)<br />
RewriteCond %{REQUEST_URI} !^/DirectoryYouDoNotWantChangedHere<br />
RewriteCond %{REQUEST_FILENAME} !-f<br />
RewriteCond %{REQUEST_FILENAME} !-d<br />
RewriteRule ^(.*)$ index.php/$1 [L,QSA]</p>
<p>Now, there will never be an index file listed in the url, except for the directory &#8220;DirectoryYouDoNotWantChangedHere&#8221;.</p>
<p>
<b>Error Document Redirects</b></p>
<p>Instead of using a Control Panel to process redirects, you can use your .htaccess file. These links can either be redirected to your home page, or you can setup an error document.</p>
<p># Handle Errors<br />
ErrorDocument 100 http://www.derekentringer.com<br />
ErrorDocument 101 http://www.derekentringer.com<br />
ErrorDocument 102 http://www.derekentringer.com<br />
# 2xx<br />
ErrorDocument 200 http://www.derekentringer.com<br />
ErrorDocument 201 http://www.derekentringer.com<br />
ErrorDocument 202 http://www.derekentringer.com<br />
ErrorDocument 203 http://www.derekentringer.com<br />
ErrorDocument 204 http://www.derekentringer.com<br />
ErrorDocument 205 http://www.derekentringer.com<br />
ErrorDocument 206 http://www.derekentringer.com<br />
ErrorDocument 207 http://www.derekentringer.com<br />
# 4xx<br />
ErrorDocument 400 http://www.derekentringer.com<br />
ErrorDocument 401 http://www.derekentringer.com<br />
ErrorDocument 402 http://www.derekentringer.com<br />
ErrorDocument 403 http://www.derekentringer.com<br />
ErrorDocument 404 http://www.derekentringer.com<br />
ErrorDocument 405 http://www.derekentringer.com<br />
ErrorDocument 406 http://www.derekentringer.com<br />
ErrorDocument 407 http://www.derekentringer.com<br />
ErrorDocument 408 http://www.derekentringer.com<br />
ErrorDocument 409 http://www.derekentringer.com<br />
ErrorDocument 410 http://www.derekentringer.com<br />
ErrorDocument 411 http://www.derekentringer.com<br />
ErrorDocument 412 http://www.derekentringer.com<br />
ErrorDocument 413 http://www.derekentringer.com<br />
ErrorDocument 414 http://www.derekentringer.com<br />
ErrorDocument 415 http://www.derekentringer.com<br />
ErrorDocument 416 http://www.derekentringer.com<br />
ErrorDocument 417 http://www.derekentringer.com<br />
ErrorDocument 418 http://www.derekentringer.com<br />
ErrorDocument 419 http://www.derekentringer.com<br />
ErrorDocument 420 http://www.derekentringer.com<br />
ErrorDocument 421 http://www.derekentringer.com<br />
ErrorDocument 422 http://www.derekentringer.com<br />
ErrorDocument 423 http://www.derekentringer.com<br />
ErrorDocument 424 http://www.derekentringer.com<br />
ErrorDocument 425 http://www.derekentringer.com<br />
ErrorDocument 426 http://www.derekentringer.com<br />
# 5xx<br />
ErrorDocument 500 http://www.derekentringer.com<br />
ErrorDocument 501 http://www.derekentringer.com<br />
ErrorDocument 502 http://www.derekentringer.com<br />
ErrorDocument 503 http://www.derekentringer.com<br />
ErrorDocument 504 http://www.derekentringer.com<br />
ErrorDocument 505 http://www.derekentringer.com<br />
ErrorDocument 506 http://www.derekentringer.com<br />
ErrorDocument 507 http://www.derekentringer.com<br />
ErrorDocument 508 http://www.derekentringer.com<br />
ErrorDocument 509 http://www.derekentringer.com<br />
ErrorDocument 510 http://www.derekentringer.com</p>
<p>
<b>Alternate to ErrorDocument</b></p>
<p>Instead of listing out all of the error types, you can also use the much shorter version:</p>
<p>### ALTERNATIVE TO USING ERRORDOCUMENT ###<br />
RewriteCond %{REQUEST_FILENAME} !-f<br />
RewriteCond %{REQUEST_FILENAME} !-d<br />
RewriteRule ^.*$ /error.php [L]</p>
<p>This will push all of your errors to a single page.</p>
<p>
That&#8217;s really just the beginning of what the .htaccess file is capable of, as it has an extensive set of capabilities.</p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2h0dHBkLmFwYWNoZS5vcmcvZG9jcy8xLjMvaG93dG8vaHRhY2Nlc3MuaHRtbA==" target=\"_blank\">Read more about them here.</a></p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vZG93bmxvYWRzL2h0YWNjZXNzLnppcA==">Download a sample .htaccess file</a></p>
 <img src="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=59" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.derekentringer.com/blog/htaccess-and-seo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flex File Browser &#8211; PDF, Images, and Video Player</title>
		<link>http://www.derekentringer.com/blog/flex-file-browser/</link>
		<comments>http://www.derekentringer.com/blog/flex-file-browser/#comments</comments>
		<pubDate>Thu, 21 Aug 2008 18:09:07 +0000</pubDate>
		<dc:creator>Derek J Entringer</dc:creator>
				<category><![CDATA[Code Samples]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[file]]></category>
		<category><![CDATA[mxml]]></category>

		<guid isPermaLink="false">http://derekentringer.com/blog/?p=53</guid>
		<description><![CDATA[
			
				
			
		

Flex has a lot to offer when it comes to file manipulation and viewing/interaction. The AIR environment is perfect for an &#8220;explorer&#8221; type application.
Here&#8217;s a quick file browser in Flex:


&#60;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34;?&#62;
&#60;mx:WindowedApplication xmlns:mx=&#34;http://www.adobe.com/2006/mxml&#34; layout=&#34;absolute&#34; width=&#34;1044&#34; height=&#34;800&#34; currentState=&#34;videoState&#34; creationComplete=&#34;init()&#34;&#62;
	&#60;mx:Style source=&#34;assets/css/styles.css&#34; /&#62;
	&#60;mx:Script&#62;
		&#60;![CDATA[
			import mx.core.UIComponent;
			import mx.controls.Alert;
			import flash.html.HTMLLoader;
			import flash.net.URLRequest;
			import mx.events.MenuEvent;
            import mx.collections.*;
			[Bindable]
            public var menuBarCollection:XMLListCollection;
            private var menubarXML:XMLList =
    ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="clear:left; float:left; margin-top:10px; margin-bottom: 10px; margin-right:12px; margin-left:2px;">
			<a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2FwaS50d2VldG1lbWUuY29tL3NoYXJlP3VybD1odHRwJTNBJTJGJTJGd3d3LmRlcmVrZW50cmluZ2VyLmNvbSUyRmJsb2clMkZmbGV4LWZpbGUtYnJvd3NlciUyRg=="><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.derekentringer.com%2Fblog%2Fflex-file-browser%2F&amp;source=derekentringer&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p><!--PLAIN_TEXT--><br />
Flex has a lot to offer when it comes to file manipulation and viewing/interaction. The AIR environment is perfect for an &#8220;explorer&#8221; type application.</p>
<p>Here&#8217;s a quick file browser in Flex:</p>
<p></p>
<pre class="brush: as3;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;mx:WindowedApplication xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot; layout=&quot;absolute&quot; width=&quot;1044&quot; height=&quot;800&quot; currentState=&quot;videoState&quot; creationComplete=&quot;init()&quot;&gt;
	&lt;mx:Style source=&quot;assets/css/styles.css&quot; /&gt;
	&lt;mx:Script&gt;
		&lt;![CDATA[
			import mx.core.UIComponent;
			import mx.controls.Alert;
			import flash.html.HTMLLoader;
			import flash.net.URLRequest;
			import mx.events.MenuEvent;
            import mx.collections.*;
			[Bindable]
            public var menuBarCollection:XMLListCollection;
            private var menubarXML:XMLList =
                &lt;&gt;
                    &lt;menuitem label=&quot;File&quot; data=&quot;top&quot;&gt;
                        &lt;menuitem label=&quot;Browse&quot; data=&quot;browse_files&quot;/&gt;
                    &lt;/menuitem&gt;
                &lt;/&gt;;
            private function menuHandler(event:MenuEvent):void  {
                if (event.item.@data != &quot;top&quot;) {
                    if(event.item.@data == &quot;browse_files&quot;){
                    	browseDir(event);
                    }
                }
            }
			if(HTMLLoader.pdfCapability == HTMLPDFCapability.STATUS_OK) {
				trace(&quot;PDF content can be displayed&quot;);
			}else {
				trace(&quot;PDF cannot be displayed. Error code:&quot;, HTMLLoader.pdfCapability);
			}
			private function init():void{
				fileSystemTree.directory = File.desktopDirectory;
            	menuBarCollection = new XMLListCollection(menubarXML);
			}
			private function browseDir(e:Event):void{
				var dir:File = new File();
				dir.browseForDirectory(&quot;Select directory&quot;);
				dir.addEventListener(Event.SELECT, onDirSelect);
			}
			private function onDirSelect(event:Event):void{
				fileSystemTree.directory = event.currentTarget as File;
			}
			private function onChange(e:Event):void{
				var file:File = e.currentTarget.selectedItem as File;
				if(!file.isDirectory){
					var viewer:Object;
					switch(file.extension.toLowerCase()){
						case &quot;flv&quot;:
							currentState = &quot;videoState&quot;;
							viewer = videoDisplay;
							viewer.source = file.url;
						break;
						case &quot;png&quot;:
						case &quot;jpg&quot;:
							currentState = &quot;imageState&quot;;
							viewer = image;
							viewer.source = file.url;
						break;
						case &quot;pdf&quot;:
							currentState = &quot;pdfState&quot;;
							var htmlLoader:HTMLLoader = new HTMLLoader();
							var urlReq:URLRequest = new URLRequest(file.url);
							htmlLoader.width = 814;
							htmlLoader.height = 705;
							htmlLoader.load(urlReq);
							var myComponent:UIComponent  = new UIComponent();
							myComponent.addChild(htmlLoader);
							pdf_content.addChild(myComponent);
						break;
						default:
							Alert.show(&quot;Unsupported file &quot; + file.nativePath, &quot;Error&quot;);
						return;
					}
				}
			}
		]]&gt;
	&lt;/mx:Script&gt;
	&lt;mx:HDividedBox width=&quot;100%&quot; height=&quot;725&quot; paddingLeft=&quot;10&quot; paddingRight=&quot;10&quot; paddingBottom=&quot;10&quot; paddingTop=&quot;10&quot; y=&quot;41&quot;&gt;
		&lt;mx:VBox width=&quot;200&quot; height=&quot;100%&quot;&gt;
			&lt;mx:FileSystemTree id=&quot;fileSystemTree&quot; width=&quot;100%&quot; height=&quot;100%&quot; change=&quot;onChange(event)&quot; /&gt;
		&lt;/mx:VBox&gt;
		&lt;mx:Canvas width=&quot;100%&quot; height=&quot;100%&quot; id=&quot;content&quot; &gt;&lt;/mx:Canvas&gt;
	&lt;/mx:HDividedBox&gt;
	&lt;mx:ApplicationControlBar x=&quot;0&quot; y=&quot;0&quot; width=&quot;100%&quot;&gt;
		&lt;mx:MenuBar labelField=&quot;@label&quot; itemClick=&quot;menuHandler(event);&quot; dataProvider=&quot;{menuBarCollection}&quot; /&gt;
	&lt;/mx:ApplicationControlBar&gt;
	&lt;mx:states&gt;
		&lt;mx:State name=&quot;videoState&quot;&gt;
			&lt;mx:AddChild relativeTo=&quot;{content}&quot;&gt;
				&lt;mx:VideoDisplay id=&quot;videoDisplay&quot; width=&quot;100%&quot; height=&quot;100%&quot; /&gt;
			&lt;/mx:AddChild&gt;
		&lt;/mx:State&gt;
		&lt;mx:State name=&quot;imageState&quot;&gt;
			&lt;mx:AddChild relativeTo=&quot;{content}&quot;&gt;
				&lt;mx:Image id=&quot;image&quot; width=&quot;100%&quot; height=&quot;100%&quot; /&gt;
			&lt;/mx:AddChild&gt;
		&lt;/mx:State&gt;
		&lt;mx:State name=&quot;pdfState&quot;&gt;
			&lt;mx:AddChild relativeTo=&quot;{content}&quot;&gt;
				&lt;mx:Canvas width=&quot;100%&quot; height=&quot;100%&quot; id=&quot;pdf_content&quot; &gt;&lt;/mx:Canvas&gt;
			&lt;/mx:AddChild&gt;
		&lt;/mx:State&gt;
	&lt;/mx:states&gt;
&lt;/mx:WindowedApplication&gt;
</pre>
<p>The result:</p>
<p><img src="http://www.derekentringer.com/img/flex_file_browser.jpg"></p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vZG93bmxvYWRzL2ZsZXhfZmlsZV9leHBsb3Jlci56aXA=">Download the source</a></p>
 <img src="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=53" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.derekentringer.com/blog/flex-file-browser/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>FLV Player (Streaming) using Dynamic Buffering, Port Detection, and Bandwidth Checks</title>
		<link>http://www.derekentringer.com/blog/flv-player-streaming-using-dynamic-buffering-port-detection-and-bandwidth-checks/</link>
		<comments>http://www.derekentringer.com/blog/flv-player-streaming-using-dynamic-buffering-port-detection-and-bandwidth-checks/#comments</comments>
		<pubDate>Thu, 21 Aug 2008 16:41:56 +0000</pubDate>
		<dc:creator>Derek J Entringer</dc:creator>
				<category><![CDATA[Code Samples]]></category>
		<category><![CDATA[FMS]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[bandwidth]]></category>
		<category><![CDATA[bandwidth checks]]></category>
		<category><![CDATA[checking]]></category>
		<category><![CDATA[detection]]></category>
		<category><![CDATA[dynamic buffering]]></category>
		<category><![CDATA[flv]]></category>
		<category><![CDATA[media]]></category>
		<category><![CDATA[port]]></category>
		<category><![CDATA[port detection]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[streaming]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://derekentringer.com/blog/?p=49</guid>
		<description><![CDATA[
			
				
			
		

This FLV player has quite a few advanced options included. The video is streamed from a Flash Media server, dynamically buffered, and playable. The server side scripts allow for dynamic port detection, and you can setup the player to serve differently encoded flv files based on the users bandwidth.
First let&#8217;s start with our external classes.


stop();

/*--------------------------------------------------------------------------------*/
//external classes
/*--------------------------------------------------------------------------------*/
import NCManager;
import mx.transitions.Tween;


We&#8217;re using the NCManager.as file as provided by Adobe. This external class allows us to manage our port connection list as well as detect a users bandwidth when they load our swf. I ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="clear:left; float:left; margin-top:10px; margin-bottom: 10px; margin-right:12px; margin-left:2px;">
			<a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2FwaS50d2VldG1lbWUuY29tL3NoYXJlP3VybD1odHRwJTNBJTJGJTJGd3d3LmRlcmVrZW50cmluZ2VyLmNvbSUyRmJsb2clMkZmbHYtcGxheWVyLXN0cmVhbWluZy11c2luZy1keW5hbWljLWJ1ZmZlcmluZy1wb3J0LWRldGVjdGlvbi1hbmQtYmFuZHdpZHRoLWNoZWNrcyUyRg=="><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.derekentringer.com%2Fblog%2Fflv-player-streaming-using-dynamic-buffering-port-detection-and-bandwidth-checks%2F&amp;source=derekentringer&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p><!--PLAIN_TEXT--></p>
<p>This FLV player has quite a few advanced options included. The video is streamed from a Flash Media server, dynamically buffered, and playable. The server side scripts allow for dynamic port detection, and you can setup the player to serve differently encoded flv files based on the users bandwidth.</p>
<p>First let&#8217;s start with our external classes.</p>
<pre class="brush: as3;">

stop();

/*--------------------------------------------------------------------------------*/
//external classes
/*--------------------------------------------------------------------------------*/
import NCManager;
import mx.transitions.Tween;
</pre>
<p>
We&#8217;re using the NCManager.as file as provided by Adobe. This external class allows us to manage our port connection list as well as detect a users bandwidth when they load our swf. I have included this file in the downloadable source, but we won&#8217;t be going over it in detail here.</p>
<p>Next we have our dynamic buffer animation. This function is used whenever the user may have caught up to the buffer available for the streaming video. There is a timer object that monitors the buffer level, and uses this animation as needed.<br />
</p>
<pre class="brush: as3;">

/*--------------------------------------------------------------------------------*/
//dynamic buffering
/*--------------------------------------------------------------------------------*/

function startBufferAnimation() {
	if (ns.time&gt;&quot;0&quot;) {
		//hide animation
		clearInterval(startBufferAnimation_interval);
		buffer_graphic._alpha = 0;
		buffer_graphic._x = 5000;
	} else {
		//show animation
		buffer_graphic._alpha = 100;
		//display the buffer progress
		totalBuffer = ns.bufferTime;
		currentBuffer = ns.bufferLength;
		loadingText = Math.round((currentBuffer/totalBuffer)*100);
		if (loadingText&lt;=100) {
			buffer_graphic.loading_txt.text = loadingText+&quot;%&quot;;
		} else {
			buffer_graphic.loading_txt.text = &quot;100%&quot;;
			clearInterval(startBufferAnimation_interval);
		}
	}
}
</pre>
<p>
Let&#8217;s load the video from the Flash Media Server. Here we will be connecting to our server using the NCManager class, looking for the bandwidth available for our current user, and recording some information about the video to be used in our controls such as scrubbing. Something that is available to us within this next bit is the ability to use the bandwidth returned by the bwcheck.as on the FMS. You could setup different variables for the k_FILENAME to be loaded based on the returned bandwidth checks. Different data rates for the same video can be served to your site visitors to make sure they have the best viewing experience possible.</p>
<pre class="brush: as3;">

/*--------------------------------------------------------------------------------*/
//video loading/controls
/*--------------------------------------------------------------------------------*/

//variables
var firstFramePending:Boolean = true;
var firstPlayPending:Boolean = true;
var ns:NetStream;
var fileName:String;

//constants
var k_STARTTIME:Number = getTimer();

//server info
var k_SERVERNAME:String = &quot;your-server-ip&quot;;
var k_APPNAME:String = &quot;app-name&quot;;
var k_FILENAME:String = &quot;flv-file-name&quot;;
var k_ASC_PATH:String = &quot;rtmp://your-fms-server-ip/app-name/bwcheck.asc&quot;;

//connect to the bwcheck.asc
nc = new NetConnection();
//connect to the bwcheck.asc
nc.connect(k_ASC_PATH,true);
//let us know that the connection was successful
nc.onStatus = function(info) {
	trace(&quot;Level: &quot;+info.level+&quot; Code: &quot;+info.code);
	if (info.code == &quot;NetConnection.Connect.Success&quot;) {
		trace(&quot;loaded: &quot;+this.uri);
	}
};

//the variable p_bw returned by bwcheck.asc holds a value equal to the detected download speed in kilobits per second
//for best results we should serve video that is encoded at a rate less than or equal to kbitsDown
NetConnection.prototype.onBWDone = function(p_bw) {
	trace(&quot;BANDWIDTH= &quot;+p_bw);
	//save the detected bandwidth
	detected_bw = p_bw;
	//close the Netconnection to bwcheck
	this.close();
};

//calling the serverside script
NetConnection.prototype.onBWCheck = function() {
	return ++counter;
};

//define an instance of our NCManager class
var ncm:NCManager = new NCManager();

//create the listener object
var ncmListener:Object = new Object();

//fires when it has found a successfull connection
ncmListener.ncConnected = function(evt:Object) {
	trace(&quot;[&quot;+Math.round(getTimer()-k_STARTTIME)+&quot;ms] Successfully connected using &quot;+evt.protocol+&quot;:&quot;+evt.port);
	//as soon as we have a good connection, play the first frame
	playFirstFrame(evt.nc);
};
//fires when it has timed-out trying to find a good connection
ncmListener.ncFailedToConnect = function(evt:Object) {
	trace(&quot;Failed to connect after &quot;+evt.timeout+&quot; milliseconds.&quot;);
};
//fires when bandwdith has been detected
ncmListener.ncBandWidth = function(evt:Object) {
	//--not working--&gt; //trace(&quot;[&quot;+Math.round(getTimer()-k_STARTTIME)+&quot;ms] Measured bandwidth at &quot;+evt.kbps+&quot; kbps.&quot;);
	fileName = k_FILENAME;
	ncm.getStreamLength(fileName);
	trace(&quot;LOADED FILE= &quot;+fileName);
};
//fires when streamlength has been detected
ncmListener.ncStreamLength = function(evt:Object) {
	trace(&quot;[&quot;+Math.round(getTimer()-k_STARTTIME)+&quot;ms] Streamlength of &quot;+evt.name+&quot; is &quot;+evt.length+&quot; seconds.&quot;);
	//save stream length info
	//vid_length = evt.length;
};
//set listeners on the NCM instance
ncm.addEventListener(&quot;ncConnected&quot;,ncmListener);
ncm.addEventListener(&quot;ncFailedToConnect&quot;,ncmListener);
ncm.addEventListener(&quot;ncBandWidth&quot;,ncmListener);
ncm.addEventListener(&quot;ncStreamLength&quot;,ncmListener);

//call the connect method on NCM instance
ncm.connect(k_SERVERNAME,k_APPNAME);
//set up the NetStream and plays the first frame of the stream
function playFirstFrame(nc:NetConnection):Void {
	ns = new NetStream(nc);
	ns.onStatus = function(info) {
		if (info.code == &quot;NetStream.Play.Stop&quot; &amp;&amp; firstFramePending) {
			firstFramePending = false;
			trace(&quot;[&quot;+Math.round(getTimer()-k_STARTTIME)+&quot;ms] First frame loaded&quot;);
			//once the first frame has loaded, measure the bandwidth
			nc.call(&quot;checkBandwidth&quot;,null);
		}
	};
	//vid length
	ns.onMetaData = function(infoObject:Object) {
		my_duration = infoObject[&quot;duration&quot;];
		//trace(my_duration);
		timing(my_duration);
	};
	//display the first frame of the best quality flv
	video.attachVideo(ns);
	//buffer the video
	//set buffer parameters
	startBufferLength = 10;
	expandedBufferLength = 20;
	//attach onStatus function
	ns.onStatus = function(infoObject:Object) {
		if (infoObject[&quot;code&quot;] == &quot;NetStream.Buffer.Full&quot;) {
			ns.setBufferTime(expandedBufferLength);
			trace(&quot;SET EXPANDED BUFFER&quot;);
			buffer_graphic._alpha = 0;
		}
		if (infoObject[&quot;code&quot;] == &quot;NetStream.Buffer.Empty&quot;) {
			ns.setBufferTime(startBufferLength);
			trace(&quot;SET START BUFFER&quot;);
			buffer_graphic._alpha = 100;
		}
	};
	//start the buffer
	ns.setBufferTime(startBufferLength);
	//display buffer graphic
	startBufferAnimation_interval = setInterval(startBufferAnimation, 150);
	ns.play(k_FILENAME);

}
</pre>
<p>
Now that we have our video loaded, we can use some simple controls. Below I have setup a scrub bar, volume, play/pause, rewind, and download buttons.<br />
</p>
<pre class="brush: as3;">

/*--------------------------------------------------------------------------------*/
//scrubber functions
/*--------------------------------------------------------------------------------*/

function timing(fTime:Number) {
	//the length of the movie
	var finalTime:Number = fTime;
	var time_interval:Number = setInterval(checkTime, 10, ns);
	//function for the interval
	function checkTime(ns:NetStream) {
		//movie time
		var ns_seconds:Number = ns.time;
		//parameters for the scrubber
		var finalWidth:Number = timer_bar.slider._width-timer_bar.scrubber._width;
		var movVar:Number = finalWidth/finalTime;
		timer_bar.scrubber._x = movVar*ns_seconds;
		//values for the scrubber position
		var pTop:Number = timer_bar.scrubber._y;
		var pLeft:Number = 0;
		var pBottom:Number = timer_bar.scrubber._y;
		var pRight:Number = timer_bar.slider._width-timer_bar.scrubber._width;
		//scrubber is pressed
		timer_bar.scrubber.onPress = function() {
			clearInterval(time_interval);
			//dragging
			startDrag(&quot;timer_bar.scrubber&quot;, false, pLeft, pTop, pRight, pBottom);
			dragging = true;
			//seek as scrubber is moved
			this.onEnterFrame = function() {
				ns_seconds = this._x/movVar;
				ns.seek(ns_seconds);
			};
		};
		timer_bar.scrubber.onRelease = function() {
			dragging = false;
			stopDrag();
			delete this.onEnterFrame;
			time_interval = setInterval(checkTime, 10, ns);
		};
		timer_bar.scrubber.onReleaseOutside = function() {
			dragging = false;
			stopDrag();
			delete this.onEnterFrame;
			time_interval = setInterval(checkTime, 10, ns);
		};
		timer_bar.scrubber.onRollOver = function(){
			timer_bar.scrubber.gotoAndStop(2);
		};
		timer_bar.scrubber.onRollOut = function(){
			timer_bar.scrubber.gotoAndStop(1);
		};
	}
}

/*--------------------------------------------------------------------------------*/
//sound settings/controls
/*--------------------------------------------------------------------------------*/

globalsound = new Sound();
globalsound.setVolume(100);
volume_slide.volume_slider._x = volume_slide.volume_bar._width-volume_slide.volume_slider._width;

b_volume.onRelease = function() {
	if (globalsound.getVolume() == 100) {
		b_volume.gotoAndStop(2);
		globalsound.setVolume(0);
	} else if (globalsound.getVolume() == 0) {
		b_volume.gotoAndStop(1);
		globalsound.setVolume(100);
	}
};
b_volume.onRollOver = function() {
	b_volume.b_sound_a.gotoAndStop(2);
	b_volume.b_sound_b.gotoAndStop(2);
}
b_volume.onRollOut = function() {
	b_volume.b_sound_a.gotoAndStop(1);
	b_volume.b_sound_b.gotoAndStop(1);
}

/*--------------------------------------------------------------------------------*/
//play/pause controls
/*--------------------------------------------------------------------------------*/

b_play.onRelease = function() {
	if (b_play._currentframe == 1) {
		ns.pause();
		b_play.gotoAndStop(2);
	} else {
		ns.pause();
		b_play.gotoAndStop(1);
	}
};
b_play.onRollOver = function(){
	b_play.b_play_a.gotoAndStop(2);
	b_play.b_play_b.gotoAndStop(2);
};
b_play.onRollOut = function(){
	b_play.b_play_a.gotoAndStop(1);
	b_play.b_play_b.gotoAndStop(1);
};
b_rewind.onRelease = function() {
	ns.seek(0);
};
b_rewind.onRollOver = function(){
	b_rewind.gotoAndStop(2);
}
b_rewind.onRollOut = function(){
	b_rewind.gotoAndStop(1);
};
download.onRelease = function() {
	getURL(&quot;http://path/to/downloadable/movie&quot;, &quot;_blank&quot;);
};
download.onRollOver = function(){
	download.gotoAndStop(2);
}
download.onRollOut = function(){
	download.gotoAndStop(1);
}
</pre>
<p>
Here&#8217;s a screenshot of the end result:</p>
<p><img src="http://www.derekentringer.com/img/flv_player_streaming.jpg" border="0" /></p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vZG93bmxvYWRzL2Zsdl9wbGF5ZXJfc3RyZWFtaW5nLnppcA==">Download the source</a></p>
 <img src="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=49" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.derekentringer.com/blog/flv-player-streaming-using-dynamic-buffering-port-detection-and-bandwidth-checks/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>FLV Player (Progressive Download) with Preloader</title>
		<link>http://www.derekentringer.com/blog/flv-player-progressive-download-with-preloader/</link>
		<comments>http://www.derekentringer.com/blog/flv-player-progressive-download-with-preloader/#comments</comments>
		<pubDate>Thu, 21 Aug 2008 16:41:02 +0000</pubDate>
		<dc:creator>Derek J Entringer</dc:creator>
				<category><![CDATA[Code Samples]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[as2]]></category>
		<category><![CDATA[controls]]></category>
		<category><![CDATA[download]]></category>
		<category><![CDATA[flv]]></category>
		<category><![CDATA[pause]]></category>
		<category><![CDATA[play]]></category>
		<category><![CDATA[player]]></category>
		<category><![CDATA[progressive]]></category>
		<category><![CDATA[rewind]]></category>
		<category><![CDATA[scrubbing]]></category>
		<category><![CDATA[simple]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[volume]]></category>

		<guid isPermaLink="false">http://derekentringer.com/blog/?p=47</guid>
		<description><![CDATA[
			
				
			
		

Here I have all of the code necessary to setup a simple AS2 flv player using progressive download. All of this script is in the first frame of the movie with the appropriate movie clips available on the stage.
First, We setup all of our controls including our Play/Pause button, Rewind, Scrubbing, and volume controls.


stop();

/*--------------------------------------------------------------------------------*/
//sound settings/controls
/*--------------------------------------------------------------------------------*/

globalsound = new Sound();
globalsound.setVolume(100);
volume_slide.volume_slider._x = volume_slide.volume_bar._width-volume_slide.volume_slider._width;

b_volume.onRelease = function() {
	if(globalsound.getVolume() == 100){
		b_volume.gotoAndStop(2);
		globalsound.setVolume(0);
	}else if(globalsound.getVolume() == 0){
		b_volume.gotoAndStop(1);
		globalsound.setVolume(100);
	}
}

//volume scrubbing
var pTop_volume:Number = volume_slide.volume_slider._y;
var pLeft_volume:Number = 0;
var pBottom_volume:Number = volume_slide.volume_slider._y;
var pRight_volume:Number = volume_slide.volume_bar._width-volume_slide.volume_slider._width;

volume_slide.volume_slider.onPress = function() {
	startDrag(&#34;volume_slide.volume_slider&#34;, false, pLeft_volume, pTop_volume, pRight_volume, pBottom_volume);
	dragging = ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="clear:left; float:left; margin-top:10px; margin-bottom: 10px; margin-right:12px; margin-left:2px;">
			<a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2FwaS50d2VldG1lbWUuY29tL3NoYXJlP3VybD1odHRwJTNBJTJGJTJGd3d3LmRlcmVrZW50cmluZ2VyLmNvbSUyRmJsb2clMkZmbHYtcGxheWVyLXByb2dyZXNzaXZlLWRvd25sb2FkLXdpdGgtcHJlbG9hZGVyJTJG"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.derekentringer.com%2Fblog%2Fflv-player-progressive-download-with-preloader%2F&amp;source=derekentringer&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p><!--PLAIN_TEXT--></p>
<p>Here I have all of the code necessary to setup a simple AS2 flv player using progressive download. All of this script is in the first frame of the movie with the appropriate movie clips available on the stage.</p>
<p>First, We setup all of our controls including our Play/Pause button, Rewind, Scrubbing, and volume controls.</p>
<pre class="brush: as3;">

stop();

/*--------------------------------------------------------------------------------*/
//sound settings/controls
/*--------------------------------------------------------------------------------*/

globalsound = new Sound();
globalsound.setVolume(100);
volume_slide.volume_slider._x = volume_slide.volume_bar._width-volume_slide.volume_slider._width;

b_volume.onRelease = function() {
	if(globalsound.getVolume() == 100){
		b_volume.gotoAndStop(2);
		globalsound.setVolume(0);
	}else if(globalsound.getVolume() == 0){
		b_volume.gotoAndStop(1);
		globalsound.setVolume(100);
	}
}

//volume scrubbing
var pTop_volume:Number = volume_slide.volume_slider._y;
var pLeft_volume:Number = 0;
var pBottom_volume:Number = volume_slide.volume_slider._y;
var pRight_volume:Number = volume_slide.volume_bar._width-volume_slide.volume_slider._width;

volume_slide.volume_slider.onPress = function() {
	startDrag(&quot;volume_slide.volume_slider&quot;, false, pLeft_volume, pTop_volume, pRight_volume, pBottom_volume);
	dragging = true;
	this.onEnterFrame = function() {
		globalsound.setVolume((volume_slide.volume_slider._x)*(volume_slide.volume_bar._width/25));
		trace((volume_slide.volume_slider._x)*(volume_slide.volume_bar._width/25));
	};
};
volume_slide.volume_slider.onRelease = function() {
	dragging = false;
	stopDrag();
	delete this.onEnterFrame;
};
volume_slide.volume_slider.onReleaseOutside = function() {
	dragging = false;
	stopDrag();
	delete this.onEnterFrame;
};

/*--------------------------------------------------------------------------------*/
//play/pause controls
/*--------------------------------------------------------------------------------*/

b_play.onRelease = function() {
	if (b_play._currentframe == 1) {
		ns.pause();
		b_play.gotoAndStop(2);
	} else {
		ns.pause();
		b_play.gotoAndStop(1);
	}
};
b_rewind.onRelease = function() {
	ns.seek(0);
}
</pre>
<p>Next, we tell flash where to find our flv file. I have not included any automatic Meta Data Handlers, so we also have to specify the length of the video in order to properly setup the scrub bar. Again, this is just to keep it simple.</p>
<pre class="brush: as3;">

/*--------------------------------------------------------------------------------*/
//video loading/controls
/*--------------------------------------------------------------------------------*/

//main video directory
var dir = &quot;path/to/your/flv&quot;;

//video properties
var vid = &quot;name of your flv&quot;;
var vid_length = &quot;length of your flv in seconds&quot;;
</pre>
<p>Here we have our NetConnection setup with our bufferTime, and I am also calling two custom functions: drawLoader, and timing. The drawLoader function is the preloader, and the timing will setup our scrub bar.</p>
<pre class="brush: as3;">

var nc:NetConnection = new NetConnection();
nc.connect(null);
var ns:NetStream = new NetStream(nc);
video.attachVideo(ns);
ns.setBufferTime(15);
ns.play(dir+vid);
ns.pause();
drawLoader();
timing(vid_length);

/*--------------------------------------------------------------------------------*/
//scrubber functions
/*--------------------------------------------------------------------------------*/

function timing(fTime:Number) {
	//the length of the movie
	var finalTime:Number = fTime;
	var time_interval:Number = setInterval(checkTime, 10, ns);
	//function for the interval
	function checkTime(ns:NetStream) {
	   //movie time
	   var ns_seconds:Number = ns.time;
	   //parameters for the scrubber
	   var finalWidth:Number = timer_bar.slider._width-timer_bar.scrubber._width;
	   var movVar:Number = finalWidth/finalTime;
	   timer_bar.scrubber._x = movVar*ns_seconds;
	   //values for the scrubber position
	   var pTop:Number = timer_bar.scrubber._y;
	   var pLeft:Number = 0;
	   var pBottom:Number = timer_bar.scrubber._y;
	   var pRight:Number = timer_bar.slider._width-timer_bar.scrubber._width;
	   //scrubber is pressed
	   timer_bar.scrubber.onPress = function() {
	       clearInterval(time_interval);
	       //dragging
	       startDrag(&quot;timer_bar.scrubber&quot;, false, pLeft, pTop, pRight, pBottom);
	       dragging = true;
	       //seek as scrubber is moved
	       this.onEnterFrame = function() {
	           ns_seconds = this._x/movVar;
	           ns.seek(ns_seconds);
	       };
	   };
	   timer_bar.scrubber.onRelease = function() {
	       dragging = false;
	       stopDrag();
	       delete this.onEnterFrame;
	       time_interval = setInterval(checkTime, 10, ns);
	   };
	   timer_bar.scrubber.onReleaseOutside = function() {
	       dragging = false;
	       stopDrag();
	       delete this.onEnterFrame;
	       time_interval = setInterval(checkTime, 10, ns);
	   };
	}
}

/*--------------------------------------------------------------------------------*/
//preloading functions
/*--------------------------------------------------------------------------------*/

function drawLoader() {

	video.clear();

	loading._visible = true;
	progressBar_mc._visible = true;
	createEmptyMovieClip(&quot;progressBar_mc&quot;,getNextHighestDepth());
	progressBar_mc.createEmptyMovieClip(&quot;bar_mc&quot;,progressBar_mc.getNextHighestDepth());

	with (progressBar_mc.bar_mc) {
		beginFill(0xD7D7D9);
		moveTo(0,0);
		lineTo(100,0);
		lineTo(100,10);
		lineTo(0,10);
		lineTo(0,0);
		endFill();
		_xscale = 0;
		_alpha = 90;
	}
	progressBar_mc.createEmptyMovieClip(&quot;stroke_mc&quot;,progressBar_mc.getNextHighestDepth());

	with (progressBar_mc.stroke_mc) {
		lineStyle(0,0xD7D7D9);
		moveTo(0,0);
		lineTo(100,0);
		lineTo(100,10);
		lineTo(0,10);
		lineTo(0,0);
		_alpha = 90;
	}
	progressBar_mc._x = 140;
	progressBar_mc._y = 115;

	var loaded_interval:Number = setInterval(checkBytesLoaded, 150);

	function checkBytesLoaded() {

		var pctLoaded_1:Number = Math.round(ns.bytesLoaded/ns.bytesTotal*100);
		pctLoaded_total = pctLoaded_1;
		trace(&quot;total loaded= &quot;+pctLoaded_total);
		progressBar_mc.bar_mc._xscale = pctLoaded_total*2;

		if (pctLoaded_total&gt;=50) {

			ns.seek(0);
			ns.pause();

			clearInterval(loaded_interval);
			progressBar_mc._visible = false;
			loading._visible = false;
			unloadMovie(progressBar_mc.stroke_mc);
			unloadMovie(progressBar_mc.bar_mc);
			unloadMovie(progressBar_mc);

		}
	}
}
</pre>
<p>The result:</p>
<p><img src="http://www.derekentringer.com/img/flv_player_example.jpg" border="0" /></p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vZG93bmxvYWRzL2Zsdl9wbGF5ZXIuemlw">Download the source</a></p>
 <img src="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=47" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.derekentringer.com/blog/flv-player-progressive-download-with-preloader/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FMS (Flash Media Server) Video Chat</title>
		<link>http://www.derekentringer.com/blog/fms-video-chat/</link>
		<comments>http://www.derekentringer.com/blog/fms-video-chat/#comments</comments>
		<pubDate>Thu, 21 Aug 2008 16:40:24 +0000</pubDate>
		<dc:creator>Derek J Entringer</dc:creator>
				<category><![CDATA[Code Samples]]></category>
		<category><![CDATA[FMS]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Application]]></category>
		<category><![CDATA[chat]]></category>
		<category><![CDATA[media]]></category>
		<category><![CDATA[server]]></category>

		<guid isPermaLink="false">http://derekentringer.com/blog/?p=45</guid>
		<description><![CDATA[
			
				
			
		

Here&#8217;s a quick way to setup a Flash Media Server chat room. This process only allows for two users to video chat over Flash Media Server, and was the start of a larger project that I was involved with.
Setting Up the Flash Media Server Application
It really doesn&#8217;t matter what you use in terms of either a FMS hosting company, or your own. Most of the FMS hosting companies use the same techniques when setting up their servers for users, but that might not always be true. In general, you simply ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="clear:left; float:left; margin-top:10px; margin-bottom: 10px; margin-right:12px; margin-left:2px;">
			<a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2FwaS50d2VldG1lbWUuY29tL3NoYXJlP3VybD1odHRwJTNBJTJGJTJGd3d3LmRlcmVrZW50cmluZ2VyLmNvbSUyRmJsb2clMkZmbXMtdmlkZW8tY2hhdCUyRg=="><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.derekentringer.com%2Fblog%2Ffms-video-chat%2F&amp;source=derekentringer&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p><!--PLAIN_TEXT--></p>
<p>Here&#8217;s a quick way to setup a Flash Media Server chat room. This process only allows for two users to video chat over Flash Media Server, and was the start of a larger project that I was involved with.</p>
<p>Setting Up the Flash Media Server Application</p>
<p>It really doesn&#8217;t matter what you use in terms of either a FMS hosting company, or your own. Most of the FMS hosting companies use the same techniques when setting up their servers for users, but that might not always be true. In general, you simply need to make sure that you setup a new Application so that the chat app has somewhere to store the published stream, and so that other flash files connected to the same Application can find that stream.</p>
<p>I use the hosting service provided by <a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2luZmx1eGlzLmNvbQ==" target=\"_blank\">Influxis.com</a>. It&#8217;s not as powerful as hosting my own FMS installation, but it definitely does the trick for anything small or for testing.</p>
<p>If you use Influxis, or are going to after reading this article, here&#8217;s how to setup an Application on your server. As I mentioned, this may vary from host to host, but it&#8217;s generally the exact same process.</p>
<p>1) Login to your account, and choose the &#8220;File Admin&#8221; tab.<br />
2) Click &#8220;Add New Application&#8221;.<br />
3) Give your application a name. This can be anything you want.<br />
4) You can leave &#8220;Include the standard main.asc file&#8221; turned on.<br />
5) Hit Continue.<br />
6) Copy and paste the rtmp address into the NetConnection connect portion of both of our users fla files.</p>
<pre class="brush: as3;">
client_nc.connect(&quot;rtmp://fms-server/app-name/&quot;);
</pre>
<p>
You will need to replace &#8220;rtmp://fms-server/app-name/&#8221; with the rtmp address that the Influxis interface has provided you with. If you don&#8217;t use Influxis, you probably already know how your server is setup, and how to reference your new Application folder.</p>
<p>Now, I have two flash files that connect to the same application on the FMS. Each one publishes to a stream called &#8220;live&#8221;. There are two video objects on the stage that act as a preview of yourself, and the live camera from the other user. (The small video object on the left is your preview, and the larger on the right is the person you are talking to.)</p>
<p>Here is the code for the &#8220;user_1&#8243; swf file:</p>
<pre class="brush: as3;">

stop();

//setup the camera and mic for streaming
mycam = Camera.get();
mycam_audio = Microphone.get();

//control the cameras mode and quality
mycam.setMode(320,240,30);
mycam.setQuality(10000,100);

//attach a live preview of the camera to the
//video object that is setup on the stage
cam_feed.attachVideo(mycam);
cam_feed.attachAudio(mycam_audio);

//connect to the Flash Media Server
client_nc = new NetConnection();
client_nc.connect(&quot;rtmp://fms-server/app-name/&quot;);
cam_ns = new NetStream(client_nc);

//attach our camera video and audio to the net stream
cam_ns.attachVideo(mycam);
cam_ns.attachAudio(mycam_audio);

//publish to our Flash Media Server as a
//live stream called user_1
cam_ns.publish(&quot;user_1&quot;, &quot;live&quot;);

//bring in user_2's video/audio
in_ns = new NetStream(client_nc);
in_ns.play(&quot;user_2&quot;);

//attach user_1's published audio and video
//so we can see them in the larger chat window
live_feed.attachVideo(in_ns);
live_feed.attachAudio(in_ns);
</pre>
<p>
And here is the code for the &#8220;user_2&#8243; swf file:</p>
<pre class="brush: as3;">

//setup the camera and mic for streaming
mycam = Camera.get();
mycam_audio = Microphone.get();

//control the cameras mode and quality
mycam.setMode(320,240,30);
mycam.setQuality(10000,100);

//attach a live preview of the camera to the
//video object that is setup on the stage
cam_feed.attachVideo(mycam);
cam_feed.attachAudio(mycam_audio);

//connect to the Flash Media Server
client_nc = new NetConnection();
client_nc.connect(&quot;rtmp://fms-server/app-name/&quot;);
cam_ns = new NetStream(client_nc);

//attach our camera video and audio to the net stream
cam_ns.attachVideo(mycam);
cam_ns.attachAudio(mycam_audio);

//publish to our Flash Media Server as a
//live stream called user_2
cam_ns.publish(&quot;user_2&quot;, &quot;live&quot;);

//bring in user_1's video/audio
in_ns = new NetStream(client_nc);
in_ns.play(&quot;user_1&quot;);

//attach user_1's published audio and video
//so we can see them in the larger chat window
live_feed.attachVideo(in_ns);
live_feed.attachAudio(in_ns);
</pre>
<p>
You&#8217;ll notice the only difference between the two is how the streams are being published. User_1&#8242;s stream publishes to &#8220;user_1&#8243; and User_2 publishes to &#8220;user_2&#8243;. Each then streams in the others live stream while also showing their own stream as a preview for the other user.<br />
<br ><br />
Upload the user_1 and user_2 folders to your server (it doesn&#8217;t matter where they go on your server, just be sure you know how to get to them using your browser), and browse to them in two separate tabs, or windows. You will then get the same results that I have in the screen shot below.<br ><br />
<br ><br />
So by creating an application folder on your FMS server, you can instantly chat with anyone. It&#8217;s not extremely robust, but with a little more work, it could turn into a full application.</p>
<p>Here&#8217;s a screen shot with me chatting with myself to give you an idea of what we are accomplishing.</p>
<p><img src="http://www.derekentringer.com/img/fms_chat_example.jpg" border="0" /></p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vZG93bmxvYWRzL2NoYXQuemlw">Download the source</a></p>
 <img src="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=45" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.derekentringer.com/blog/fms-video-chat/feed/</wfw:commentRss>
		<slash:comments>32</slash:comments>
		</item>
		<item>
		<title>Papervision3d &#8211; Simple Mouse Controlled Interactive Sphere</title>
		<link>http://www.derekentringer.com/blog/papervision3d-simple-mouse-controlled-interactive-sphere/</link>
		<comments>http://www.derekentringer.com/blog/papervision3d-simple-mouse-controlled-interactive-sphere/#comments</comments>
		<pubDate>Thu, 21 Aug 2008 16:39:26 +0000</pubDate>
		<dc:creator>Derek J Entringer</dc:creator>
				<category><![CDATA[Code Samples]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[control]]></category>
		<category><![CDATA[create]]></category>
		<category><![CDATA[interactive]]></category>
		<category><![CDATA[papervision]]></category>
		<category><![CDATA[pitch]]></category>
		<category><![CDATA[sphere]]></category>
		<category><![CDATA[yaw]]></category>

		<guid isPermaLink="false">http://derekentringer.com/blog/?p=42</guid>
		<description><![CDATA[
			
				
			
		

Here&#8217;s a class that renders a simple wireframe sphere in Papervision3d, and allows the mouse to control the pitch and yaw. This example can be applied to any simple interactive environment.

package {
	import flash.display.Sprite;
	import flash.events.Event;
	import org.papervision3d.cameras.*;
	import org.papervision3d.objects.*;
	import org.papervision3d.scenes.*;
	import org.papervision3d.materials.*;

	public class PaperVisionTest extends Sprite {
		/** setup the container */
		private var container: Sprite = new Sprite();

		/** setup the scene */
		private var scene: MovieScene3D = new MovieScene3D(container);

		/** setup the camera */
		private var camera: Camera3D = new Camera3D();

		/** setup the material */
		private var material:WireframeMaterial = new WireframeMaterial(0xFF0000);

		/** setup the sphere */
		private var sphere:Sphere = new ...]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="clear:left; float:left; margin-top:10px; margin-bottom: 10px; margin-right:12px; margin-left:2px;">
			<a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2FwaS50d2VldG1lbWUuY29tL3NoYXJlP3VybD1odHRwJTNBJTJGJTJGd3d3LmRlcmVrZW50cmluZ2VyLmNvbSUyRmJsb2clMkZwYXBlcnZpc2lvbjNkLXNpbXBsZS1tb3VzZS1jb250cm9sbGVkLWludGVyYWN0aXZlLXNwaGVyZSUyRg=="><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.derekentringer.com%2Fblog%2Fpapervision3d-simple-mouse-controlled-interactive-sphere%2F&amp;source=derekentringer&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p><!--PLAIN_TEXT--><br />
Here&#8217;s a class that renders a simple wireframe sphere in Papervision3d, and allows the mouse to control the pitch and yaw. This example can be applied to any simple interactive environment.</p>
<pre class="brush: as3;">
package {
	import flash.display.Sprite;
	import flash.events.Event;
	import org.papervision3d.cameras.*;
	import org.papervision3d.objects.*;
	import org.papervision3d.scenes.*;
	import org.papervision3d.materials.*;

	public class PaperVisionTest extends Sprite {
		/** setup the container */
		private var container: Sprite = new Sprite();

		/** setup the scene */
		private var scene: MovieScene3D = new MovieScene3D(container);

		/** setup the camera */
		private var camera: Camera3D = new Camera3D();

		/** setup the material */
		private var material:WireframeMaterial = new WireframeMaterial(0xFF0000);

		/** setup the sphere */
		private var sphere:Sphere = new Sphere(material, 300, 30, 30);

		/**
		* constructor
		*/
		public function PaperVisionTest() {
			//add the container
			container.x = stage.stageWidth/2;
			container.y = stage.stageHeight/2;
			addChild(container);

			//camera parameters
			camera.z = -500;
			camera.zoom = 5;

			//give the sphere to the scene
			scene.addChild(sphere);

			stage.addEventListener(Event.ENTER_FRAME, update);
		}

		/**
		* Triggered by the enter frame event
		* @param pEvent Event object passed by the dispatcher
		*/
		private function update(pEvent:Event):void {

			//initialize the camera
			sphere.lookAt(camera);

			//mouse movement control
			sphere.pitch(this.mouseY);
			sphere.yaw(this.mouseX);

			//render the scene
			scene.renderCamera(camera);
		}
	}
}
</pre>
<p>The final result:</p>
<p><img src="http://www.derekentringer.com/img/sphere.jpg" border="0" /></p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5kZXJla2VudHJpbmdlci5jb20vZG93bmxvYWRzL1BhcGVydmlzaW9uVGVzdC56aXA=">Click here to download the source.</a></p>
 <img src="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=42" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.derekentringer.com/blog/papervision3d-simple-mouse-controlled-interactive-sphere/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Simple Papervision3d Scene</title>
		<link>http://www.derekentringer.com/blog/simple-papervision3d-scene/</link>
		<comments>http://www.derekentringer.com/blog/simple-papervision3d-scene/#comments</comments>
		<pubDate>Thu, 21 Aug 2008 16:38:49 +0000</pubDate>
		<dc:creator>Derek J Entringer</dc:creator>
				<category><![CDATA[Code Samples]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[3d]]></category>
		<category><![CDATA[create]]></category>
		<category><![CDATA[papervision]]></category>
		<category><![CDATA[scene]]></category>

		<guid isPermaLink="false">http://derekentringer.com/blog/?p=40</guid>
		<description><![CDATA[
			
				
			
		

Here&#8217;s a simple scene that renders a Papervision3d scene within a container. There are no 3d elements added, but this is as simple as it gets.

import org.papervision3d.cameras.*;
import org.papervision3d.objects.*;
import org.papervision3d.materials.*;
import org.papervision3d.scenes.*;

var container:Sprite = new Sprite();
addChild(container);
container.x = stage.stageWidth * 0.5;
container.y = stage.stageHeight * 0.5;

var scene:Scene3D = new Scene3D(container);
var camera:Camera3D = new Camera3D();
camera.zoom = 11;

addEventListener(Event.ENTER_FRAME, loop);

function loop(e:Event):void
{
    scene.renderCamera(camera);
}

If you&#8217;re interested in how this can be improved, check out the next post with a more elaborate Papervision scene.
 ]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="clear:left; float:left; margin-top:10px; margin-bottom: 10px; margin-right:12px; margin-left:2px;">
			<a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2FwaS50d2VldG1lbWUuY29tL3NoYXJlP3VybD1odHRwJTNBJTJGJTJGd3d3LmRlcmVrZW50cmluZ2VyLmNvbSUyRmJsb2clMkZzaW1wbGUtcGFwZXJ2aXNpb24zZC1zY2VuZSUyRg=="><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.derekentringer.com%2Fblog%2Fsimple-papervision3d-scene%2F&amp;source=derekentringer&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p><!--PLAIN_TEXT--><br />
Here&#8217;s a simple scene that renders a Papervision3d scene within a container. There are no 3d elements added, but this is as simple as it gets.</p>
<pre class="brush: as3;">
import org.papervision3d.cameras.*;
import org.papervision3d.objects.*;
import org.papervision3d.materials.*;
import org.papervision3d.scenes.*;

var container:Sprite = new Sprite();
addChild(container);
container.x = stage.stageWidth * 0.5;
container.y = stage.stageHeight * 0.5;

var scene:Scene3D = new Scene3D(container);
var camera:Camera3D = new Camera3D();
camera.zoom = 11;

addEventListener(Event.ENTER_FRAME, loop);

function loop(e:Event):void
{
    scene.renderCamera(camera);
}
</pre>
<p>If you&#8217;re interested in how this can be improved, check out the next post with a more elaborate Papervision scene.</p>
 <img src="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=40" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.derekentringer.com/blog/simple-papervision3d-scene/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flash CS3: Easy to use XML Feed Class</title>
		<link>http://www.derekentringer.com/blog/flash-cs3-easy-to-use-xml-feed-class/</link>
		<comments>http://www.derekentringer.com/blog/flash-cs3-easy-to-use-xml-feed-class/#comments</comments>
		<pubDate>Thu, 21 Aug 2008 16:38:01 +0000</pubDate>
		<dc:creator>Derek J Entringer</dc:creator>
				<category><![CDATA[Code Samples]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[cs3]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://derekentringer.com/blog/?p=38</guid>
		<description><![CDATA[
			
				
			
		
Re-usable class created by brianConnatser that will set up an external XML feed to use E4X, datagrids, and much more.
Check out some of the code
 ]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="clear:left; float:left; margin-top:10px; margin-bottom: 10px; margin-right:12px; margin-left:2px;">
			<a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL2FwaS50d2VldG1lbWUuY29tL3NoYXJlP3VybD1odHRwJTNBJTJGJTJGd3d3LmRlcmVrZW50cmluZ2VyLmNvbSUyRmJsb2clMkZmbGFzaC1jczMtZWFzeS10by11c2UteG1sLWZlZWQtY2xhc3MlMkY="><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.derekentringer.com%2Fblog%2Fflash-cs3-easy-to-use-xml-feed-class%2F&amp;source=derekentringer&amp;style=normal&amp;service=TinyURL.com" height="61" width="50" /><br />
			</a>
		</div>
<p>Re-usable class created by brianConnatser that will set up an external XML feed to use E4X, datagrids, and much more.</p>
<p><a href="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?url=aHR0cDovL3d3dy5jb25uYXRzZXJkZXYuY29tL2Jsb2cvP3A9Njc=">Check out some of the code</a></p>
 <img src="http://www.derekentringer.com/blog/wp-content/plugins/wordpress-feed-statistics/feed-statistics.php?view=1&post_id=38" width="1" height="1" style="display: none;" />]]></content:encoded>
			<wfw:commentRss>http://www.derekentringer.com/blog/flash-cs3-easy-to-use-xml-feed-class/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
