<?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>Carl Sziebert &#187; ActionScript</title>
	<atom:link href="http://sziebert.net/posts/category/actionscript/feed/" rel="self" type="application/rss+xml" />
	<link>http://sziebert.net</link>
	<description>is a software engineer with an interest in Spring, Hibernate, Red5 and jQuery development.</description>
	<lastBuildDate>Thu, 29 Jul 2010 20:25:08 +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>Server-side stream recording example updated</title>
		<link>http://sziebert.net/posts/server-side-stream-recording-updated/</link>
		<comments>http://sziebert.net/posts/server-side-stream-recording-updated/#comments</comments>
		<pubDate>Tue, 14 Apr 2009 04:08:32 +0000</pubDate>
		<dc:creator>Carl Sziebert</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Red5]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://sziebert.net/?p=92</guid>
		<description><![CDATA[<p>With this being my most popular blog topic, I felt the time has come for a little update. (You can catch up on the original <a href="http://sziebert.net/posts/server-side-stream-recording-with-red5/">here</a>.)  Frankly, there&#8217;s not much too it.  The server-side code didn&#8217;t change much, just an update to take advantage of the built-in logging support of Red5.  Both clients have been completely rewritten using ActionScript 3. (I know, it&#8217;s about time.) <!--more--></p>
<p>Recording the stream on the server takes one simple line as displayed here:</p>
<p><strong>StreamManager.java</strong></p>
<pre class="brush: java;">
ClientBroadcastStream stream = (ClientBroadcastStream) app.getBroadcastStream(conn.getScope(), &quot;hostStream&quot;);
try {
	// Save the stream to disk.
	stream.saveAs(streamName, false);
} catch (Exception e) {
	logger.error(&quot;Error while saving stream: {}&quot;, streamName);
}
</pre>
<p>The only button in the broadcast application starts and stops the recording session.  The <tt>click</tt> handler does all the work:</p>
<p><strong>Broadcast.as</strong></p>
<pre class="brush: as3;">
private function onClick(event:MouseEvent):void {
	var button:Button = event.target as Button;
	// Record the stream by triggering a server event.
	if (button.label == &quot;Record&quot;) {
		// Tell the remote server to start recording.
		runtime.conn.call(&quot;streamManager.recordShow&quot;, null);
		// Re-label the button.
		button.label = &quot;Stop&quot;;
	// Stop recording the stream.
	} else if (button.label == &quot;Stop&quot;) {
		// Tell the remote server to stop recording.
		runtime.conn.call(&quot;streamManager.stopRecordingShow&quot;, null);
		// Re-label the button.
		button.label = &quot;Record&quot;;
	}
}
</pre>
<p>Like I said, not much to it.  But there&#8217;s a lot of power wrapped up in this little piece of functionality.  </p>
<p><strong>Grab the source code for this tutorial <a href="http://garagetech.googlecode.com/files/Recorder.zip">here</a>.</strong> The example code was updated to be compatible with Red5 0.9.1 on July 29, 2010.</p>
]]></description>
		<wfw:commentRss>http://sziebert.net/posts/server-side-stream-recording-updated/feed/</wfw:commentRss>
		<slash:comments>43</slash:comments>
		</item>
		<item>
		<title>jQuery Transmit file upload plugin updated</title>
		<link>http://sziebert.net/posts/jquery-transmit-file-upload-plugin-updated/</link>
		<comments>http://sziebert.net/posts/jquery-transmit-file-upload-plugin-updated/#comments</comments>
		<pubDate>Fri, 13 Mar 2009 22:03:47 +0000</pubDate>
		<dc:creator>Carl Sziebert</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://sziebert.net/?p=80</guid>
		<description><![CDATA[<p>Having finally gotten a few hours to myself, I&#8217;ve updated the jquery-transmit file upload plugin to support Flash 10.  Because of the security restrictions added in the most recent revision of the flash browser plugin, the calls to trigger the file selection dialog needed to occur in the SWF itself.  To achieve this, the SWF is placed on a layer above the links triggering the dialog.  You should be able to successfully edit the HTML to your liking without much consequence.  Though, you should be careful not to rename any of the ids or classes.  The plugin relies on them to place the SWF and resize it as necessary. As with the initial release, the plugin should be considered a work in progress and is not yet suitable for a production environment. Hopefully, this fact won&#8217;t deter you from giving the plugin a try.  Source and downloads are available at <a href="http://code.google.com/p/jquery-transmit/">googlecode</a>.  As always, constructive feedback is very much appreciated.</p>
]]></description>
		<wfw:commentRss>http://sziebert.net/posts/jquery-transmit-file-upload-plugin-updated/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Flickr style multiple file upload with jQuery</title>
		<link>http://sziebert.net/posts/flickr-style-multiple-file-upload-with-jquery/</link>
		<comments>http://sziebert.net/posts/flickr-style-multiple-file-upload-with-jquery/#comments</comments>
		<pubDate>Fri, 12 Sep 2008 21:37:52 +0000</pubDate>
		<dc:creator>Carl Sziebert</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://sziebert.net/?p=15</guid>
		<description><![CDATA[<p>A while back, <a href="http://gregoire.org/">Paul Gregoire</a> introduced me to the <a href="http://jquery.com">jQuery JavaScript library</a>.  It didn&#8217;t take long for me to realize the power and elegance of this library.  For the longest time, I&#8217;ve been wanting to take a shot at authoring a plugin for jQuery and I&#8217;ve finally gotten around to it.  So, it is my pleasure to announce the creation of the <a href="http://code.google.com/p/jquery-transmit">jquery.transmit plugin</a>.  It is a flash-backed multiple file upload utility with a user experience similar to that of Flickr&#8217;s current uploader.  The goals for the plugin were simple: Provide an easy-to-use interface, use flash to work around HTML and JavaScript based file upload issues, and wire it all together with jQuery. Getting started with the plugin is quite simple.  Import the necessary <acronym title="Cascading Style Sheets">CSS</acronym> and JavaScript dependencies, edit the supplied HTML to your liking and  invoke the plugin like so:</p>
<pre class="brush: jscript;">
    $(document).ready(function() {
        $('#transmit').transmit('http://mysite.com/upload/');
    });
</pre>
<p>While the plugin is still very much in its infancy and should be considered a work in progress, it is my opinion that it is easier to shake out bugs using an iterative development process.  So, keeping that in mind, I&#8217;m hoping that a couple of you brave souls will wander over to <a href="http://code.google.com/p/jquery-transmit">googlecode</a> and give it a try.  Constructive feedback is very much appreciated.</p>
]]></description>
		<wfw:commentRss>http://sziebert.net/posts/flickr-style-multiple-file-upload-with-jquery/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Jedai Framework for Red5</title>
		<link>http://sziebert.net/posts/jedai-framework-for-red5/</link>
		<comments>http://sziebert.net/posts/jedai-framework-for-red5/#comments</comments>
		<pubDate>Sat, 03 May 2008 23:00:43 +0000</pubDate>
		<dc:creator>Carl Sziebert</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flash Media Server]]></category>
		<category><![CDATA[Red5]]></category>
		<category><![CDATA[jedai]]></category>

		<guid isPermaLink="false">http://sziebert.net/?p=12</guid>
		<description><![CDATA[<p>As the Red5 media server continues to mature, new and exciting additions are announced with greater frequency.  Once such addition to Red5 is the Jedai project.  Anyone familiar with Flash Media Server knows that it provides a solid component library for rapid development of collaborative media applications.  With the introduction of the Jedai project, Red5 is no longer lacking in the area.<!--more-->  </p>
<p>The project consists of two main parts, the Jedia Networking Framework (JNF) and the Jedai Collaboration Suite (JCS).  The Networking Framework delivers a development stack that &#8220;builds upon the services that most real-time applications need&#8221; such as user, stream and data management.  The Collaboration Suite is a set of reusable components providing services such as authentication, text chat and video publishing and is designed to be used directly with the JNF.  Leveraging these two pieces gives Red5 application developers a great deal of power and flexibility with a minimum of effort.  </p>
<p>From the project developers themselves: &#8220;We have seen the need for this framework for quite some time, and here is our answer. Please, feel free to try it out and watch as it becomes a standard in real-time application development with Red5 and Flash.&#8221;  </p>
<p>Check it out here: <a href="http://code.google.com/p/jedai/">http://code.google.com/p/jedai/</a></p>
]]></description>
		<wfw:commentRss>http://sziebert.net/posts/jedai-framework-for-red5/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Server-side stream recording with Red5</title>
		<link>http://sziebert.net/posts/server-side-stream-recording-with-red5/</link>
		<comments>http://sziebert.net/posts/server-side-stream-recording-with-red5/#comments</comments>
		<pubDate>Wed, 05 Sep 2007 02:48:25 +0000</pubDate>
		<dc:creator>Carl Sziebert</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flash Media Server]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Red5]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://sziebert.net/posts/server-side-stream-recording-with-red5/</guid>
		<description><![CDATA[<p><strong>This tutorial has been updated. Please check out the <a href="http://sziebert.net/posts/server-side-stream-recording-updated/">new post</a>.</strong</p>
<p>While most developers are content to record video using the <tt>NetStream.publish(&#8220;streamName&#8221;, &#8220;record&#8221;)</tt> API, it is sometimes useful to take FLV snippets from the publishing stream instead.  In my opinion, this is one of the greatest features of Flash Media Server (FMS) and Red5.  Utilizing this strategy allows the application developer to precisely control when and how much of the video is recorded.  While recording via the <tt>NetStream</tt> function has been available in Red5 since the beginning, recording video from the server-side application has not.  In this post, I'll demonstrate Red5's ability to record an FLV with a very simple pair of publish and subscribe flash applications.<!--more--> </p>
<p>I'll jump right in by creating a simple ApplicationAdapter subclass.  This step isn't really necessary, however I feel that it is good practice when creating Red5 applications.  As your application grows in functionality, you'll have the most essential building block ready to go. </p>
<p><strong>Application.java</strong></p>
<pre class="brush: java;">
public class Application extends ApplicationAdapter {

	...

	/**
	 * Delegate method used to accept/reject incoming connection requests.
	 *
	 * @param conn
	 * @param params
	 * @return true/false
	 */
	@Override
	public boolean roomConnect(IConnection conn, Object[] params) {
		log.debug(&quot;New connection attempt from &quot; + conn.getRemoteAddress() + &quot;...&quot;);
		// Insure that the listeners are properly attached.
		return super.roomConnect(conn, params);
	}

	/**
	 * Delegate method which logs connection/client/user disconnections.
	 *
	 * @param conn
	 */
	@Override
	public void roomDisconnect(IConnection conn) {
		log.debug(&quot;Connection closed by &quot; + conn.getRemoteAddress() + &quot;...&quot;);
		// Call the super class to insure that all listeners are properly
		// dismissed.
		super.roomDisconnect(conn);
	}
}
</pre>
<p>As you can see, there isn't much to it, just a couple of logging statements to track new connections to the application.  Next, I'll define a simple service bean to handle the <tt>NetConnection</tt> calls to start and stop the stream recordings.</p>
<p><strong>StreamManager.java</strong></p>
<pre class="brush: java;">
public class StreamManager {

	...

	/**
	 * Start recording the publishing stream for the specified
	 * IConnection.
	 *
	 * @param conn
	 */
	public void recordShow(IConnection conn) {
		log.debug(&quot;Recording show for: &quot; + conn.getScope().getContextPath());
		String streamName = String.valueOf(System.currentTimeMillis());
		// Get a reference to the current broadcast stream.
		ClientBroadcastStream stream = (ClientBroadcastStream) app.getBroadcastStream(
				conn.getScope(), &quot;hostStream&quot;);
		try {
			// Save the stream to disk.
			stream.saveAs(streamName, false);
		} catch (Exception e) {
			log.error(&quot;Error while saving stream: &quot; + streamName, e);
		}
	}

	/**
	 * Stops recording the publishing stream for the specified
	 * IConnection.
	 *
	 * @param conn
	 */
	public void stopRecordingShow(IConnection conn) {
		log.debug(&quot;Stop recording show for: &quot; + conn.getScope().getContextPath());
		// Get a reference to the current broadcast stream.
		ClientBroadcastStream stream = (ClientBroadcastStream) app.getBroadcastStream(
				conn.getScope(), &quot;hostStream&quot;);
		// Stop recording.
		stream.stopRecording();
	}

	...
}
</pre>
<p>This is where the meat of the application lies.  The broadcast client starts recording the stream by calling <tt>streamManager.recordShow()</tt> and stops it by calling <tt>streamManager.stopRecordingShow()</tt>.  In the example broadcast application, I've added a button to the Stage and created a simple <tt>onClick</tt> function to invoke the server-side methods.</p>
<p><strong>BroadcastController.as</strong></p>
<pre class="brush: as3;">
        /**
	 * Handle the record button click events.
	 */
	private function onClick(ev:Object):Void {
		// Record the stream by triggering a server event.
		if (ev.target.label == &quot;Record&quot;) {
			// Tell the remote server to start recording.
			conn.call(&quot;streamManager.recordShow&quot;, null);
			// Re-label the button.
			button.label = &quot;Stop&quot;;
		// Stop recording the stream.
		} else if (ev.target.label == &quot;Stop&quot;) {
			// Tell the remote server to stop recording.
			conn.call(&quot;streamManager.stopRecordingShow&quot;, null);
			// Re-label the button.
			button.label = &quot;Record&quot;;
		}
	}
</pre>
<p>Take note, the name of the recorded stream differs from that of the publishing stream.  I am using a simple timestamp as a unique name for each new FLV.  It is even possible to reuse an existing FLV and append new video data to it.  Simply change the second argument of the <tt>stream.saveAs()</tt> method call to <tt>true</tt> while reusing the same stream name. Check the streams directory of the recorder application for the output files.  Reviewing the FLVs is as easy as opening them up with an FLV player<a class="sup" href="#wimpy">[1]</a>.   </p>
<p>While this is an interesting bit of functionality, the possibilities are much greater.  Consider, for example, a security application that needs to record video when the camera detects movement and also needs to have a unique file for each incident. With some minor tweaks to this example, you've got exactly that.  In addition, it would be quite easy to extend this application to extract a JPEG preview snapshot from each FLV using FFMPEG<a class="sup" href="#ffmpeg">[2]</a>.</p>
<p>The example source code for this post can be downloaded <a href="http://garagetech.googlecode.com/files/Recorder.zip">here</a>.</p>
<p>1. <a name="wimpy" href="http://www.wimpyplayer.com/products/wimpy_standalone_flv_player.html">http://www.wimpyplayer.com</a> Wimpy Desktop FLV Player is a free cross platform (Mac and PC) standalone Flash Video FLV player for you, which will allow you to watch your FLV and SWF videos from your desktop.  Check it out.</p>
<p>2. <a name="ffmpeg" href="http://www.ffmpeg.org/">http://www.ffmpeg.org/</a> FFmpeg is a complete solution to record, convert and stream audio and video. It includes libavcodec, the leading audio/video codec library. FFmpeg is developed under Linux, but it can compiled under most operating systems, including Windows.</p>
]]></description>
		<wfw:commentRss>http://sziebert.net/posts/server-side-stream-recording-with-red5/feed/</wfw:commentRss>
		<slash:comments>66</slash:comments>
		</item>
		<item>
		<title>Server-side ActionScript plugin for Eclipse</title>
		<link>http://sziebert.net/posts/server-side-actionscript-plugin-for-eclipse/</link>
		<comments>http://sziebert.net/posts/server-side-actionscript-plugin-for-eclipse/#comments</comments>
		<pubDate>Fri, 24 Aug 2007 17:26:41 +0000</pubDate>
		<dc:creator>Carl Sziebert</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Flash Media Server]]></category>
		<category><![CDATA[SSAS]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://sziebert.net/posts/server-side-actionscript-plugin-for-eclipse/</guid>
		<description><![CDATA[<p>Server-side ActionScript (SSAS) has long been the bastard child of the ActionScript permutations.  There are a number of editors that offer syntax highlighting and in the case of the Flash development tool, the bare minimum of auto-completion features for SSAS.  That is until now.<!--more--> FCZone has put together an excellent plugin for the Eclipse platform that makes editing SSAS a joy.  They are even porting it to the Mac and other *nix operating systems for those of us that prefer not to work on Windows.</p>
<p><span style="text-decoration: line-through;">Grab the plugin here: </span><a href="http://fczone.com/eclipse/"><span style="text-decoration: line-through;">http://fczone.com/eclipse/</span></a></p>
<p>Seems as though the original link is no longer valid. Fret not for <a href="http://www.igorcosta.org/?p=151">Igor Costa</a> has created a mirror: <a href="http://www.igorcosta.org/downloads/fmseditor_eclipseplugin.zip">http:​/​/​www.igorcosta.org/​downloads/​fmseditor_eclipseplugin.zip</a></p>
]]></description>
		<wfw:commentRss>http://sziebert.net/posts/server-side-actionscript-plugin-for-eclipse/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Red5 + Hibernate</title>
		<link>http://sziebert.net/posts/red5-hibernate/</link>
		<comments>http://sziebert.net/posts/red5-hibernate/#comments</comments>
		<pubDate>Thu, 23 Aug 2007 17:07:37 +0000</pubDate>
		<dc:creator>Carl Sziebert</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Red5]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://sziebert.net/posts/red5-hibernate/</guid>
		<description><![CDATA[<p><strong>This tutorial has been updated. Please check out the <a href="http://sziebert.net/posts/red5-hibernate-revisited">new post</a>.</strong></p>
<p>Having followed the growth of the Red5 Media Server<a class="sup" href="#red5">[1]</a> from it&#8217;s fledgling 0.3 days, I&#8217;ve become fairly familiar with its offerings. One of the most frequently asked questions on the Red5 mailing list pertains to database connectivity for user authentication and application security.  I&#8217;ll attempt to tackle one solution here using Hibernate<a class="sup" href="#hibernate">[2]</a>, an object/relational persistence framework.<!--more-->  Because Red5 is implemented in Java and makes heavy use of the Spring Framework<a class="sup" href="#spring">[3]</a>, I&#8217;ll be sticking with it for the purposes of this post.  Hibernate should be familiar to most Java developers these days, or at least the concept of an ORM framework should be.  If not, then you&#8217;ve got some homework to do before continuing on here.  One other item of note, I won&#8217;t be covering MySQL<a class="sup" href="#mysql">[4]</a> in any detail here, even though it is required for the example code to run.  My goal is to cover the integration of the technologies and not to reiterate the numerous introductions already available.</p>
<p>I&#8217;ll start by defining a simple Hibernate-backed User object and it&#8217;s mapping file.  Note: I&#8217;ve also included an annotated version of the User object in case you would prefer to run without mapping files.  </p>
<p><strong>User.java:</strong></p>
<pre class="brush: java;">
@Entity
@Table(name=&quot;users&quot;)
public class User
{
	@Id @GeneratedValue
        @Column(name=&quot;id&quot;, nullable=false)
	private Long id;

	@Column(name=&quot;user_name&quot;, nullable=false, length=32, unique=true)
	private String userName;

	@Column(name=&quot;password&quot;, nullable=false)
	private String password;

        ...
}
</pre>
<p><strong>User.hbm.xml:</strong></p>
<pre class="brush: xml;">
&lt;hibernate-mapping package=&quot;net.sziebert.red5.adapter.entity&quot;&gt;
	&lt;class name=&quot;User&quot; table=&quot;users&quot;&gt;
		&lt;id name=&quot;id&quot; type=&quot;long&quot; column=&quot;id&quot;&gt;
			&lt;generator class=&quot;native&quot;/&gt;
		&lt;/id&gt;
		&lt;natural-id&gt;
			&lt;property name=&quot;userName&quot; column=&quot;user_name&quot; length=&quot;32&quot; not-null=&quot;true&quot; unique=&quot;true&quot; /&gt;
		&lt;/natural-id&gt;
		&lt;property name=&quot;password&quot; not-null=&quot;true&quot; /&gt;

		...

	&lt;/class&gt;
&lt;/hibernate-mapping&gt;
</pre>
<p>Both are very straight forward.  The User class defines fields for a unique identifier and the user&#8217;s credentials. It is mapped to the users table via Users.hbm.xml.  At this point, a Hibernate session factory and datasource definition are necessary.  I&#8217;ve defined both in the red5-web.xml file. This file is the means by which Red5 applications wire together resources and define dependencies.</p>
<p><strong>red5-web.xml:</strong></p>
<pre class="brush: xml;">
&lt;bean id=&quot;dataSource&quot; class=&quot;org.apache.commons.dbcp.BasicDataSource&quot; destroy-method=&quot;close&quot;&gt;
        &lt;property name=&quot;driverClassName&quot; value=&quot;${jdbc.driverClassName}&quot; /&gt;
        &lt;property name=&quot;url&quot; value=&quot;${jdbc.url}&quot; /&gt;
        &lt;property name=&quot;username&quot; value=&quot;${jdbc.username}&quot; /&gt;
        &lt;property name=&quot;password&quot; value=&quot;${jdbc.password}&quot; /&gt;
    &lt;/bean&gt;

    &lt;bean id=&quot;sessionFactory&quot; class=&quot;org.springframework.orm.hibernate3.LocalSessionFactoryBean&quot;&gt;
        &lt;property name=&quot;dataSource&quot; ref=&quot;dataSource&quot; /&gt;
        &lt;property name=&quot;mappingResources&quot;&gt;
            &lt;list&gt;
                &lt;value&gt;net/sziebert/red5/adapter/entity/User.hbm.xml&lt;/value&gt;
            &lt;/list&gt;
        &lt;/property&gt;
        &lt;property name=&quot;hibernateProperties&quot;&gt;
            &lt;props&gt;
                &lt;prop key=&quot;hibernate.dialect&quot;&gt;org.hibernate.dialect.MySQLInnoDBDialect&lt;/prop&gt;
                &lt;prop key=&quot;hibernate.show_sql&quot;&gt;true&lt;/prop&gt;
                &lt;prop key=&quot;hibernate.format_sql&quot;&gt;true&lt;/prop&gt;
                &lt;prop key=&quot;hibernate.cache.use_query_cache&quot;&gt;true&lt;/prop&gt;
                &lt;prop key=&quot;hibernate.bytecode.use_reflection_optimizer&quot;&gt;true&lt;/prop&gt;
                &lt;prop key=&quot;hibernate.current_session_context_class&quot;&gt;thread&lt;/prop&gt;
                &lt;prop key=&quot;hibernate.cache.provider_class&quot;&gt;org.hibernate.cache.HashtableCacheProvider&lt;/prop&gt;
                &lt;prop key=&quot;hibernate.hbm2ddl.auto&quot;&gt;update&lt;/prop&gt;
            &lt;/props&gt;
        &lt;/property&gt;
    &lt;/bean&gt;
</pre>
<p>If you choose to take advantage of Hibernate Annotations, you&#8217;ll need to modify your session factory definition to use the AnnotationSessionFactoryBean template.</p>
<p><strong>red5-web.xml:</strong></p>
<pre class="brush: xml;">
&lt;bean id=&quot;sessionFactory&quot; class=&quot;org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean&quot;&gt;
        &lt;property name=&quot;dataSource&quot; ref=&quot;dataSource&quot; /&gt;
        &lt;property name=&quot;annotatedClasses&quot;&gt;
            &lt;list&gt;
            	&lt;value&gt;net.sziebert.red5.adapter.entity.User&lt;/value&gt;
            &lt;/list&gt;
        &lt;/property&gt;
        &lt;property name=&quot;annotatedPackages&quot;&gt;
            &lt;list&gt;
                &lt;value&gt;net.sziebert.red5.adapter.entity&lt;/value&gt;
            &lt;/list&gt;
        &lt;/property&gt;
        &lt;property name=&quot;hibernateProperties&quot;&gt;
            &lt;props&gt;
                &lt;prop key=&quot;hibernate.dialect&quot;&gt;org.hibernate.dialect.MySQLInnoDBDialect&lt;/prop&gt;
                &lt;prop key=&quot;hibernate.show_sql&quot;&gt;true&lt;/prop&gt;
                &lt;prop key=&quot;hibernate.format_sql&quot;&gt;true&lt;/prop&gt;
                &lt;prop key=&quot;hibernate.query.factory_class&quot;&gt;org.hibernate.hql.classic.ClassicQueryTranslatorFactory&lt;/prop&gt;
                &lt;prop key=&quot;hibernate.cache.use_query_cache&quot;&gt;true&lt;/prop&gt;
                &lt;prop key=&quot;hibernate.bytecode.use_reflection_optimizer&quot;&gt;true&lt;/prop&gt;
                &lt;prop key=&quot;hibernate.current_session_context_class&quot;&gt;thread&lt;/prop&gt;
                &lt;prop key=&quot;hibernate.cache.provider_class&quot;&gt;org.hibernate.cache.HashtableCacheProvider&lt;/prop&gt;
                &lt;prop key=&quot;hibernate.hbm2ddl.auto&quot;&gt;update&lt;/prop&gt;
            &lt;/props&gt;
        &lt;/property&gt;
    &lt;/bean&gt;
</pre>
<p>Sticking with patterns most often referenced by other developers/authors, I&#8217;ll define a simple data access object and service layer next. Spring offers a template for Hibernate usage which plays very nicely with its transaction management facilities which I&#8217;ll cover later.</p>
<p><strong>HibernateApplicationDAO.java:</strong></p>
<pre class="brush: java;">
public class HibernateApplicationDAO extends HibernateDaoSupport implements ApplicationDAO {
	...

	/**
	 * @see ApplicationDAO#getUser(String, String)
	 */
	public User getUser(String user, String pass) {
		log.debug(&quot;Retrieving user from the database.&quot;);
		// Ask Hibernate to query for the user based upon the specified user/pass.
		Criteria crit = getSession().createCriteria(User.class);
		crit.add(Restrictions.eq(&quot;userName&quot;, user));
		crit.add(Restrictions.eq(&quot;password&quot;, pass));
		User u = (User)crit.uniqueResult();
		// Insure that we got something back from Hibernate.
		if (null == u) {
			log.warn(&quot;User does not exist for credentials: &quot; + user + &quot;/&quot; + pass);
			throw new ObjectRetrievalFailureException(User.class, user);
		}
		// Return the results.
		return u;
	}
}
</pre>
<p><strong>ApplicationServiceImpl.java:</strong></p>
<pre class="brush: java;">
public class ApplicationServiceImpl implements ApplicationService {

	...

	/**
	 * @see ApplicationService#getUser(String, String)
	 */
	public User getUser(String user, String pass) throws ServiceException {
		log.debug(&quot;Looking up user for user/pass of: &quot; + user + &quot;/&quot; + pass);
		try {
			// Return the result of the data access call.
			return dao.getUser(user, pass);
		} catch (Exception e) {
			log.error(&quot;Could not load user!&quot;, e);
			throw new ServiceException(&quot;Could not load user!&quot;, e);
		}
	}
}
</pre>
<p>You&#8217;ll want to take note of the red5-web.xml definition for the ApplicationService implementation.  It extends the TransactionProxyFactoryBean definition.  By defining the HibernateTransactionManager and this proxy template, we automagically get a Spring-managed Hibernate transaction every time we access the service layer to look up the User.  This means that you can skip the boilerplate code for opening a session and starting a transaction.  </p>
<p><strong>red5-web.xml:</strong></p>
<pre class="brush: xml;">
&lt;bean id=&quot;transactionManager&quot; class=&quot;org.springframework.orm.hibernate3.HibernateTransactionManager&quot;&gt;
        &lt;property name=&quot;sessionFactory&quot; ref=&quot;sessionFactory&quot; /&gt;
    &lt;/bean&gt;

    &lt;bean id=&quot;txProxyTemplate&quot; abstract=&quot;true&quot; class=&quot;org.springframework.transaction.interceptor.TransactionProxyFactoryBean&quot;&gt;
        &lt;property name=&quot;transactionManager&quot;&gt;
            &lt;ref local=&quot;transactionManager&quot; /&gt;
        &lt;/property&gt;
        &lt;property name=&quot;transactionAttributes&quot;&gt;
            &lt;props&gt;
                &lt;prop key=&quot;get*&quot;&gt;PROPAGATION_REQUIRED,readOnly&lt;/prop&gt;
                &lt;prop key=&quot;save*&quot;&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
                &lt;prop key=&quot;update*&quot;&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
                &lt;prop key=&quot;delete*&quot;&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
            &lt;/props&gt;
        &lt;/property&gt;
    &lt;/bean&gt;

    &lt;bean id=&quot;applicationDAO&quot; class=&quot;net.sziebert.red5.adapter.dao.hibernate.HibernateApplicationDAO&quot;&gt;
        &lt;property name=&quot;hibernateTemplate&quot; ref=&quot;hibernateTemplate&quot; /&gt;
    &lt;/bean&gt;

    &lt;bean id=&quot;applicationService&quot; parent=&quot;txProxyTemplate&quot;&gt;
        &lt;property name=&quot;target&quot;&gt;
            &lt;bean class=&quot;net.sziebert.red5.adapter.service.impl.ApplicationServiceImpl&quot;&gt;
                &lt;property name=&quot;applicationDAO&quot; ref=&quot;applicationDAO&quot; /&gt;
            &lt;/bean&gt;
        &lt;/property&gt;
    &lt;/bean&gt;
</pre>
<p>I&#8217;ll wrap up the Red5 application definitions with the injection of the ApplicationService object into the ApplicationAdapter subclass, defined in red5-web.xml as web.handler.   The user authentication process happens within the ApplicationAdapter subclass, Application.java.  When a user with valid credentials connects to Red5, the application accepts the connection attempt and allows the user to stay connected.  In all other cases, the connection attempt is rejected and the connection is closed.</p>
<p><strong>red5-web.xml:</strong></p>
<pre class="brush: xml;">
&lt;bean id=&quot;web.handler&quot; class=&quot;net.sziebert.red5.adapter.Application&quot; singleton=&quot;true&quot;&gt;
    &lt;property name=&quot;applicationService&quot; ref=&quot;applicationService&quot; /&gt;
&lt;/bean&gt;
</pre>
<p><strong>Application.java:</strong></p>
<pre class="brush: java;">
public class Application extends ApplicationAdapter {

	...

	public boolean roomConnect(IConnection conn, Object[] params) {
		log.debug(&quot;New connection attempt from &quot; + conn.getRemoteAddress() + &quot;...&quot;);
		// Parse the user/pass out of the connection parameters
		String userName = (String)params[0];
		String password = (String)params[1];
		// Get the User object for this connection
		User user = null;
		// Insure that we have received the proper set of parameters.
		if (StringUtils.isNotBlank(userName) &amp;&amp;
				StringUtils.isNotBlank(password)) {
			user = authenticate(userName, password);
		}
		// If we got a valid user object, then allow the connection. Otherwise,
		// the user could not be found or something bad happened. In either
		// case, we do not want to allow the connection.
		return user != null;
	}	

	...
}
</pre>
<p>The ActionScript side of things is also very straight forward.  I&#8217;ve created a simple client SWF which passes the specified user credentials as part of the NetConnection.connect() call and defines callback functions for handling the results of the connection attempt.  The results are also logged to a TextArea instance for convenient review.</p>
<p><strong>HibernateController.as:</strong></p>
<pre class="brush: as3;">
class net.sziebert.ria.HibernateController {

	...

	/**
	 * Initialize the connection to the Red5 media server.
	 */
	private function initConnection(user:String, pass:String):Void {
		trace(className + &quot;: initConnection(&quot; + user + &quot;, &quot; + pass + &quot;)&quot;);
		// Create the new connection object.
		conn = new Red5Connection({server:&quot;localhost&quot;, app:&quot;hibernate&quot;, room:&quot;test&quot;});
		// Add the NetConnection event listeners
		conn.addEventListener(&quot;onConnect&quot;, Delegate.create(this, onConnect));
		conn.addEventListener(&quot;onReject&quot;, Delegate.create(this, onReject));
		conn.addEventListener(&quot;onClose&quot;, Delegate.create(this, onClose));
		conn.addEventListener(&quot;onFail&quot;, Delegate.create(this, onFail));
		// Connect to the remote server
		log(&quot;Connecting to &quot; + conn.getServerUrl());
		conn.connect(conn.getServerUrl(), user, pass);
	}

	...
}
</pre>
<p>That&#8217;s more or less it.  Take a look over the <a href="http://sziebert.net/software/examples/Red5+Hibernate.zip">example code</a>, drop it into your Red5 install and let&#8217;er rip.  Keep in mind that you&#8217;ll need to configure MySQL to allow Red5 to talk to it. (Notes on this can be found in the README file with the examples.)  You&#8217;ll also need to add your user data to the tables once Hibernate has generated the schema.</p>
<p><strong>This tutorial has been updated. Please check out the <a href="http://sziebert.net/posts/red5-hibernate-revisited">new post</a> for the latest source code bundle.</strong></p>
<p>1. <a name="red5" href="http://osflash.org/red5">http://osflash.org/red5</a>  For those that aren&#8217;t up on Red5, it is a robust Flash Media Server alternative written entirely in Java that supports multi-user video chat, video streaming and real-time, multi-player gaming.  </p>
<p>2. <a name="hibernate" href="http://hibernate.org">http://hibernate.org</a>  Hibernate lets you develop persistent classes following object-oriented idiom &#8211; including association, inheritance, polymorphism, composition, and collections. It allows you to express queries in its own portable SQL extension (HQL), as well as in native SQL.</p>
<p>3. <a name="spring" href="http://springframework.org">http://springframework.org</a> Spring is a layered Java/JEE application framework founded on the simple concepts that any tool should be a pleasure to use, that your application code should not depend on Spring APIs and that it should not compete with existing solutions, but should foster integration.</p>
<p>4. <a name="mysql" href="http://mysql.com">http://mysql.com</a>  The MySQL database has become the world&#8217;s most popular open source database because of its consistent fast performance, high reliability and ease of use.</p>
]]></description>
		<wfw:commentRss>http://sziebert.net/posts/red5-hibernate/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>
