<?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>timwhitlock.info &#187; RTMP</title>
	<atom:link href="http://timwhitlock.info/blog/tag/rtmp/feed/" rel="self" type="application/rss+xml" />
	<link>http://timwhitlock.info</link>
	<description>Tim Whitlock&#039;s personal site and blog</description>
	<lastBuildDate>Thu, 15 Dec 2011 13:51:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>node-amf and node-rtmp</title>
		<link>http://timwhitlock.info/blog/2010/08/07/node-amf-and-node-rtmp/</link>
		<comments>http://timwhitlock.info/blog/2010/08/07/node-amf-and-node-rtmp/#comments</comments>
		<pubDate>Sat, 07 Aug 2010 13:56:16 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[AMF]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[NodeJS]]></category>
		<category><![CDATA[RTMP]]></category>

		<guid isPermaLink="false">http://web.2point1.com/?p=449</guid>
		<description><![CDATA[AMF and RTMP libraries for node.js &#8211; Flash remoting with node. I&#8217;ve been having fun playing with node.js over the past year, but have had little, or no excuse to use it in any production work, so I thought I&#8217;d set myself a challenge and build a module. That challenge was firstly to create a [...]]]></description>
			<content:encoded><![CDATA[<h3>AMF and RTMP libraries for node.js &#8211; Flash remoting with node.</h3>
<p>I&#8217;ve been having fun playing with <a href="http://nodejs.org/" target="_blank">node.js</a> over the past year, but have had little, or no excuse to use it in any production work, so I thought I&#8217;d set myself a challenge and build a module. That challenge was firstly to create a simple AMF gateway for Flash remoting, and secondarily to see if an RTMP socket server was achievable in node.</p>
<p>If you don&#8217;t know about &#8220;<a href="http://nodejs.org/" target="_blank">node&#8221;</a> &#8211; It&#8217;s a JavaScript runtime that allows you to write socket servers. I like it a lot &#8211; it brings asynchronous, event-driven programming to the server side and provides a truly global variable scope across all connections. I&#8217;ll blog about it in more detail later, perhaps.</p>
<p>At <a href="http://www.publicreative.com/" target="_blank">Public</a> we do a lot of <a href="http://www.innocentkids.co.uk/" target="_blank">Flash work</a>, and regularly implement Flash remoting using a PHP AMF gateway. I wasn&#8217;t necessarily looking to replace this stock approach with node, but node offers proper socket connections that PHP can&#8217;t, so I was imagining the possibilities of using node as a free, and more flexible alternative to Flash Media Server. Not for streaming media, but for real-time messaging, for example in multi-player games. If I&#8217;m honest though, I did this mostly for fun, an academic exercise and as an excuse to work with node.</p>
<h3><span id="more-449"></span>node-amf</h3>
<p>node-amf is on GitHub as a <em>public</em> repository: <a href="http://github.com/timwhitlock/node-amf" target="_blank">http://github.com/timwhitlock/node-amf</a></p>
<p>The first step was to write a pure JavaScript AMF implementation. i.e. a library for serializing and deserializing AMF packets. If you&#8217;re not familiar with <a href="http://en.wikipedia.org/wiki/Action_Message_Format" target="_blank">AMF (Action Message Format)</a> &#8211; it&#8217;s a binary serialization and messaging format invented by Adobe for passing data back and forth between Flash and a remote server. I am not the only person to implement this in JavaScript: mid-way through my project I noticed <a href="http://www.jamesward.com/2010/07/07/amf-js-a-pure-javascript-amf-implementation/" target="_blank">amf.js</a> appear &#8211; just a little too late for me. This library is probably much better than my own, but mine is designed specifically for node, so I shall stick with it for now.</p>
<p>With a working AMF library all that remained was to create a HTTP gateway. There are many examples of AMF gateways in other languages, including <a href="http://framework.zend.com/download/amf" target="_blank">PHP</a>. The general approach is that a single request/response  exchange carries one or more messages, each one calling a web service  on the server and returning the result. AMF also has the ability to invoke methods in the Flash client on response &#8211; an underused feature.</p>
<p>Node makes it incredibly easy to implement an <a href="http://github.com/timwhitlock/node-amf/blob/master/node-amf/http-server.js" target="_blank">HTTP server</a>, all that I had to do was decide how to expose the web services to the gateway. I decided to do this by passing a user-defined JavaScript object when initializing the server &#8211; each property of the object is a function callable by name &#8211; <a href="http://github.com/timwhitlock/node-amf/tree/master/examples/http-server/" target="_blank">example AMF gateway here</a>. This suitably sandboxes the method calls, and ensures the client cannot execute arbitrary JavaScript functions &#8211; that would be bad.</p>
<p>This part of the project is largely complete and working. It has not been used in production yet, so if you&#8217;re brave enough to use it, please let me know how it&#8217;s going!</p>
<h3>node-rtmp</h3>
<p>node-rtmp is currently under the same project as node-amf because it&#8217;s dependant upon the AMF library. This <strong>incomplete</strong>, highly <strong>unstable</strong>, and <strong>experimental </strong>work is under the <a href="http://github.com/timwhitlock/node-amf/tree/master/node-rtmp/" target="_blank">node-rtmp subdirectory</a> with <a href="http://github.com/timwhitlock/node-amf/tree/master/examples/" target="_blank">examples here</a>.</p>
<p>If you&#8217;re not familiar with <a href="http://en.wikipedia.org/wiki/Real_Time_Messaging_Protocol" target="_blank">RTMP (Real Time Messaging Protocol)</a> it provides bi-directional streaming media and messaging over persistent socket connections. It&#8217;s the messaging I&#8217;m interested in. Flash talks to Flash Media Server over RTMP sockets and can securely call methods in both directions.</p>
<p>As it turns out the <a href="http://www.adobe.com/devnet/rtmp/" target="_blank">RTMP specification</a> is very badly written. (The <a href="http://en.wikipedia.org/wiki/Action_Message_Format#References" target="_blank">AMF specs</a> were quite easy to read, although possibly much simpler). If I was a cynic, I may even suggest that Adobe has purposefully written them badly to avoid third party developers being able to adhere to the usage license which insists in adequate conformance to the spec. However, it doesn&#8217;t seem to have stopped numerous projects such as <a href="http://sourceforge.net/projects/librtmp/" target="_blank">librtmp</a> from gluing the pieces together.</p>
<p>This is the point where I realised I might be out of my depth. I am currently in the process of glueing the pieces together myself. Armed with the dodgy specification, <a href="http://www.wireshark.org/" target="_blank">Wireshark</a>, and the fragmented information dotted around the Internet, I am making some slow progress. At the time of writing I have the RTMP handshake working correctly, and have just about deciphered the command messaging packets.</p>
<p>I may give up before this is at all useful.<em> </em></p>
<h3>librtmp and node add-ons</h3>
<p>As you may have noticed, I&#8217;m talking about implementing all of this in pure JavaScript, and you may be thinking that&#8217;s nuts. You are probably right. As libraries, these don&#8217;t really need to be written in JavaScript. In addition to pure JavaScript modules, node supports <a href="http://nodejs.org/api.html#addons-310" target="_blank">add-ons</a> &#8211; compiled libraries which can be built against C and C++ system libraries. A good example of this is <a href="http://github.com/vanillahsu/node-memcache" target="_blank">node-memcache</a>.</p>
<p>C and C++ is unfortunately outside my skill set, but I imagine it may be possible to build an RTMP node add-on using <a href="http://sourceforge.net/projects/librtmp/" target="_blank">librtmp</a>. Anyone fancy a crack at that?</p>
]]></content:encoded>
			<wfw:commentRss>http://timwhitlock.info/blog/2010/08/07/node-amf-and-node-rtmp/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Flash Media Server &amp; FLVPlayback nightmare</title>
		<link>http://timwhitlock.info/blog/2008/05/14/flash-media-server-flvplayback-nightmare/</link>
		<comments>http://timwhitlock.info/blog/2008/05/14/flash-media-server-flvplayback-nightmare/#comments</comments>
		<pubDate>Wed, 14 May 2008 23:33:51 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Flash Media Server]]></category>
		<category><![CDATA[FMS]]></category>
		<category><![CDATA[RTMP]]></category>

		<guid isPermaLink="false">http://web.2point1.com/2008/05/14/flash-media-server-flvplayback-nightmare/</guid>
		<description><![CDATA[I am pretty new to Flash Media Server, but on my current project I have been charged with setting it up. Today, I ran into a thoroughly unpleasant problem, possibly a bug, which I thought I would share. I set up our simple FMS application, which merely streams video from a three-directory-deep file structure. This [...]]]></description>
			<content:encoded><![CDATA[<p><strong>I am pretty new to Flash Media Server</strong>, but on my current project I have been charged with setting it up. Today, I ran into a thoroughly unpleasant problem, possibly a bug, which I thought I would share.</p>
<p><span id="more-37"></span>I set up our simple FMS application, which merely streams video from a three-directory-deep file structure. This means our Flash front end must,<br />
a. connect to an instance of the application, say: <code>rtmp://mydomain.com/myApp/_definst_</code><br />
b. request the stream of an FLV resource, such as:<br />
<code>flv:ab/cd/ef/vwxyz</code>.</p>
<p>Note the explicit use of the default application instance <code>_definst_</code>, and also the odd reshuffling of the FLV path. This is how you&#8217;re supposed to do it [apparently]  and it worked just fine. Hoorah.</p>
<p>After running some successful tests with a simple front end using <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/net/NetConnection.html" target="_blank">NetConnection</a>, I am told that our Flash front end (actually Flex) will be using a skinned <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/fl/video/FLVPlayback.html" target="_blank">FLVPlayback</a> component. This component doesn&#8217;t ask you to split the resource into these two pieces; it takes a single, complete stream URL. The above example would mean passing in: <code>rtmp://mydomain.com/myApp/_definst_/ab/cd/ef/vwxyz.flv</code><br />
Note we still keep the instance name, and the flv extension is optional.<br />
This worked just fine on our dev server, and when we deployed to a live server it seemed to be ok too. Hoorah x 2!</p>
<p><strong>Anyhow, I&#8217;ll get to the &#8220;but&#8221;.</strong></p>
<p>After gong live, we received reports of videos not playing, and were unable to replicate the problem at will. Eventually I noticed in the log files that FMS was throwing 404s. On closer inspection, the 404s were for resources prefixed with our application instance name <code>_definst_</code>. The successful 200 responses were requested correctly as <code>ab/cd/ef/vwxyz</code>, but the failures were referenced as <code>_definst_/ab/cd/ef/vwxyz</code>. Most alarmingly these were sometimes for the same resources, and even from the same client.</p>
<p>It looks like under certain [unknown] circumstances, the application and the resource are not getting correctly split out of the full URL. I do not know at what point this error creeps in. I also don&#8217;t know what FLVPlayback does internally to make the stream request from the full URL you pass in. All I know is that the error appears arbitrarily, and has proved impossible to raise on purpose. Possibly a bug in FLVPlayback, or a bug in Flash Media Server?</p>
<p><strong>Solution</strong></p>
<p>A real solution I have not found, so I did a very dirty hack.<br />
As I have failed to avoid the 404s, I turned the bad paths into valid paths by sym-linking the FLV directory back to itself with the name <code>_definst_</code>, as follows:</p>
<pre class="code">cd /path/to/flvs
ln -s . _definst_</pre>
<p>Job done, but I&#8217;m not happy about it. Anyone able to offer a real solution, please post a comment!</p>
]]></content:encoded>
			<wfw:commentRss>http://timwhitlock.info/blog/2008/05/14/flash-media-server-flvplayback-nightmare/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

