More Books
Flash Communication Server
Flash Communication Server
Table of Contents
Copyright
About the Authors
Brian Lesser
Giacomo
Joey Lott
Robert Reinhardt
Justin Watkins
Foreword
Preface
What Does FlashCom Offer?
What's in This Book?
How to Use This Book
Audience
ActionScript 1.0 Versus ActionScript 2.0
Server-Side ActionScript
The flash-communications.net Site
Director, Breeze, and Other Options
Flash Video Options
Licensing and Hosting Options
Conventions Used in This Book
Voice
Using Code Examples
Safari Enabled
Comments and Questions
Acknowledgments
Part I:  FlashCom Foundation
Chapter 1.  Introducing the Flash Communication Server
Section 1.1.  Clients and Servers
Section 1.2.  Creating an Application
Section 1.3.  Real-Time Messaging Protocol
Section 1.4.  The Communication Classes
Section 1.5.  Communicating with Application Servers, Databases, and Directory Servers
Section 1.6.  Firewalls and Security
Section 1.7.  Getting Started
Section 1.8.  Hello Video!
Section 1.9.  Conclusion
Chapter 2.  Communication Components
Section 2.1.  Overview of Communication Components
Section 2.2.  Summary of Communication Components
Section 2.3.  Creating an Application that Monitorsa Connection
Section 2.4.  Building a Simple Chat Room
Section 2.5.  Adding Audio and Video to the Chat Room
Section 2.6.  Forgoing the SimpleConnect Component
Section 2.7.  Conclusion
Chapter 3.  Managing Connections
Section 3.1.  Making a Connection
Section 3.2.  Managing a Connection
Section 3.3.  Reusing a NetConnection Object
Section 3.4.  Multiple Simultaneous NetConnection Objects
Section 3.5.  Testing and Debugging Network Connections
Section 3.6.  Subclassing the NetConnection Class
Section 3.7.  Communication Components Without SimpleConnect
Section 3.8.  Conclusion
Chapter 4.  Applications, Instances, and Server-Side ActionScript
Section 4.1.  Scripting Application Instances
Section 4.2.  Differences Between Flash ActionScript and Server-Side ActionScript
Section 4.3.  The Life of an Application Instance
Section 4.4.  Running a Simple Hello World Test Script
Section 4.5.  A More Realistic Example
Section 4.6.  Instance-to-Instance Communications
Section 4.7.  Script Filenames and Locations in Detail
Section 4.8.  Testing and Debugging Server-SideScript Files
Section 4.9.  Designing Communication Applications
Section 4.10.  Conclusion
Part II:  Audio, Video, and Data Streams
Chapter 5.  Managing Streams
Section 5.1.  A Simple Publisher/Subscriber Example
Section 5.2.  Stream Names
Section 5.3.  Publishing Streams in Detail
Section 5.4.  Playing Streams in Detail
Section 5.5.  The Stream Class
Section 5.6.  Publishing and Playing ActionScript Data
Section 5.7.  Creating Synchronized Presentations
Section 5.8.  The NetStream and Stream Information Objects
Section 5.9.  Stream Enhancements and Limitations
Section 5.10.  Conclusion
Chapter 6.  Microphone and Camera
Section 6.1.  Working with Microphone/Audio Input
Section 6.2.  Working with Camera Input
Section 6.3.  Building a Message-Taking Application
Section 6.4.  Building a Surveillance Application
Section 6.5.  Conclusion
Chapter 7.  Media Preparation and Delivery
Section 7.1.  Audio and Video Compression
Section 7.2.  Converting Prerecorded Materialto FLV Format
Section 7.3.  Using Flash Pro's Media Components
Section 7.4.  Enabling Multiple Bit Rate FLVsWithin an Application
Section 7.5.  Streaming MP3 Audio
Section 7.6.  Conclusion
Part III:  Remote Connectivity and Communication
Chapter 8.  Shared Objects
Section 8.1.  Objects and Shared Objects
Section 8.2.  Getting a Shared Object in Flash
Section 8.3.  Updates and Frame Rates
Section 8.4.  Scripting Shared Objects on the Server
Section 8.5.  Temporary and Persistent Shared Objects
Section 8.6.  Proxied Shared Objects
Section 8.7.  Shared Objects and Custom Classes
Section 8.8.  Avoiding Collisions
Section 8.9.  Optimizing Shared Object Performance
Section 8.10.  Broadcasting Remote Method Callswith send( )
Section 8.11.  A Simple Video and Text Chat Application
Section 8.12.  Conclusion
Chapter 9.  Remote Methods
Section 9.1.  Why Use Calls?
Section 9.2.  The send( ) and call( ) Methods
Section 9.3.  Client-to-Server Calls
Section 9.4.  Server-to-Client Calls
Section 9.5.  Server-to-Server Calls
Section 9.6.  A Simple Lobby/Rooms Application
Section 9.7.  Debugging Calls
Section 9.8.  Advanced Topics
Section 9.9.  Conclusion
Chapter 10.  Server Management API
Section 10.1.  Connecting to the Admin Service
Section 10.2.  Using the Server Management API
Section 10.3.  Server Management API Uses
Section 10.4.  Conclusion
Chapter 11.  Flash Remoting
Section 11.1.  The Remoting Gateway
Section 11.2.  Remoting Basics
Section 11.3.  Role of Remoting in FlashCom Applications
Section 11.4.  Securing Access
Section 11.5.  Conclusion
Chapter 12.  ColdFusion MX and FlashCom
Section 12.1.  Understanding ColdFusion MXand Flash Remoting
Section 12.2.  Using Flash Remoting to Log Events
Section 12.3.  Getting a List of Streams
Section 12.4.  Using ColdFusion and FTP to Mirror Streams
Section 12.5.  Conclusion
Part IV:  Design and Deployment
Chapter 13.  Building Communication Components
Section 13.1.  Source Files
Section 13.2.  People Lists
Section 13.3.  A Simple People List
Section 13.4.  Listenable Shared Objects
Section 13.5.  Status and People List
Section 13.6.  Text Chat
Section 13.7.  Shared Text
Section 13.8.  Video Conference and Video Window
Section 13.9.  PeopleGrid
Section 13.10.  Summary
Section 13.11.  Conclusion
Chapter 14.  Understanding the Macromedia Component Framework
Section 14.1.  The Component Framework
Section 14.2.  Under the Hood of the Chat Component
Section 14.3.  Creating a Simple Component from Scratch: SharedTextInput
Section 14.4.  Creating a Container Component: SharedAddressForm
Section 14.5.  Creating an Authenticating Component
Section 14.6.  Integrating Components with Your Existing Applications
Section 14.7.  Understanding the Framework
Section 14.8.  Conclusion
Chapter 15.  Application Design Patterns and Best Practices
Section 15.1.  Shared Object Management
Section 15.2.  Moving Code to the Server
Section 15.3.  Building Façades on the Server
Section 15.4.  Server-Side Client Queues
Section 15.5.  A Framework for Recording and Playing Back Componentized Applications
Section 15.6.  Components and Component Frameworks
Section 15.7.  Conclusion
Chapter 16.  Building Scalable Applications
Section 16.1.  Coordinating Instances
Section 16.2.  Scalability and Load Balancing
Section 16.3.  Conclusion
Chapter 17.  Network Performance, Latency,and Concurrency
Section 17.1.  Latency
Section 17.2.  Bandwidth
Section 17.3.  Concurrency
Section 17.4.  Conclusion
Chapter 18.  Securing Applications
Section 18.1.  The Three A's: Authentication, Authorization, and Accounting
Section 18.2.  Authentication
Section 18.3.  Authorization
Section 18.4.  Accounting
Section 18.5.  Suggestions and References
Section 18.6.  Conclusion
Index
SYMBOL
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
R
S
T
U
V
W

5.7. Creating Synchronized Presentations

One of the most compelling features of FlashCom-enabled applications is the way Flash content and streaming audio and video can be merged into a seamless and full-featured presentation. With some careful scripting, you can create a presentation that includes optional viewing of closed captions, animated slides, dynamic repositioning of video, and other effects all synchronized to video playback. There are two approaches to synchronizing events, such as displaying closed captions, to stream time.

The first approach is to embed information about events directly in a stream using the NetStream.send( ) method. The advantages of send( ) are that synchronization is as precise as it can be and that it often requires less scripting. The disadvantages are that send( ) must be called on the publishing stream while it is being recorded and, if the user is allowed to seek to different parts of a stream, additional scripting is required to replay or reestablish the events up to the time the user seeks to. In the future, FLV editors may become available that allow postproduction embedding and editing of remote method calls.

The second approach is to synchronize a list of instructions to a stream by regularly checking (polling) the stream time to see if an instruction should be executed. An instruction can be used to display a caption, resize or hide a video object, or display an animation. For presentations, especially when prerecorded video and audio from multiple sources must be assembled, synchronizing lists of instructions to a stream by regularly checking stream time is the most practical approach.

5.7.1. Adding Closed Captions

Closed captions are a good place to experiment with synchronizing presentation events to a stream. When someone is speaking, the caption containing the correct words must be displayed. A simple and flexible way to provide closed captioning data is to provide a list of caption start times along with the text of each caption in an XML file:

<closedCaptions>
  <caption seconds="0.0"><![CDATA[]]></caption>
  <caption seconds="3.0"><![CDATA[Welcome to my presentation.]]></caption>
  <caption seconds="7.0"><![CDATA[I hope you enjoy it.]]></caption>
</closedCaptions>

Each <caption> tag contains a seconds attribute, which is the stream time at which the caption should first be displayed. Within each <caption> tag, a <![CDATA[]]> tag is used to contain unencoded text. Any unencoded text, including the & and < characters, can safely be placed in a CDATA section. When Flash parses the XML, the contents of the CDATA section will be converted to a text node. The first <caption> tag contains no text so that when the stream starts, no caption text will be visible. Other empty captions can be added to a list of captions to pad the list for intervals when no one is speaking.

When the XML data is loaded into a Flash movie, it can be used to create an array of objects. Each object can have a time property and a text property.

During playback of the stream, the stream time must be checked at regular intervals against the caption that is currently displayed. If the wrong caption is displayed, the correct one must be found and displayed. Either setInterval( ) or onEnterFrame( ) can be used to regularly call a function to check the stream time against the current caption. Unless a very low frame rate is used, checking with onEnterFrame( ) is a good practice as it will be called just before the next frame is redrawn. There is often little point in choosing an interval that checks several times in between frames or more often than the movie's frame rate.

Since the stream time will be checked repeatedly, the process of finding the correct caption should be as efficient as possible. A simple and efficient way to check the caption is to store caption objects in an array sorted by time, as depicted in Figure 5-2. An index into the array can be used to keep track of the current caption and easily get the time of the next caption.

Figure 5-4. An array of caption objects laid out against time


Assuming the stream begins to play at 0 seconds and proceeds forward linearly, the first caption can be displayed, and the time of the next captionin the illustration, 3 secondskept in a variable. As long as the current stream time is less than the next caption time, nothing has to be done. When the time finally progresses to being equal to or greater than the time of the next caption, the next caption can be displayed and the time of the one following it retrieved. Later, when time becomes equal to or greater than 7, the next caption is shown. Assuming that an array named captionList containing caption objects with time properties is available, a simple onEnterFrame( ) function might look something like this:

// Start with caption number 0.
currentIndex = 0;
// Get the time of the next caption.
nextCaptionTime = captionList[1].time;
// Deal with the case where there is no next caption.
if (!nextCaptionTime) nextCaptionTime = Number.POSITIVE_INFINITY;
// Show the current caption.
showCaption(currentIndex);

// As the stream plays, keep checking the stream time.
function onEnterFrame ( ) {
  // If the stream time has progressed far enough, show the next caption.
  if (ns.time >= nextCaptionTime) {
    currentIndex++;
    nextCaptionTime = captionList[currentIndex + 1].time;
    if (!nextCaptionTime) nextCaptionTime = Number.POSITIVE_INFINITY;
    showCaption(currentIndex);
  }
}

The showCaption( ) function is not shown but is responsible for displaying the text of a caption. A strategy like this works well if the stream only plays through from the beginning to the end. If the user is allowed to navigate to any part of the stream at any time, another approach must be used to find the current caption in the array. Since the captions are stored in time order, a binary search can be performed on the array to quickly find the current caption when necessary. When the stream begins to play again, the script can go back to checking the time of the next caption.

Captions are much like other events that have to be synchronized to stream time, so it makes sense to create a general purpose container to hold events and keep them synchronized to a stream.

The book's web site includes a complete tech note that describes the design and development of a SynchronizedEventsList class, which can store, find, and return events given a stream time. The tech note contains a complete sample presentation and source code. The sample combines closed captioning with repositioning, hiding, and showing of video as the presentation progresses and synchronized animations. For the sake of brevity, the entire application, which includes a NetStream subclass; the ClosedCaptionsManager, CaptionEvent, and PlaybackDirector classes; and methods to read and parse an XML file, is not listed here.

5.7.2. Adding Synchronized Slides

The presentation on the book's site uses the SynchronizedEventsList class from within other objects to synchronize events to a stream. A SynchronizedEventsList instance can be used by another object to store events and then to find an event for a specific time. For example, another object that has the responsibility of responding to stream events by always displaying the correct caption can create its own SynchronizedEventsList instance and then use it to store captions and find the right one at any time. In fact, it is a good idea to use a separate events list because it makes searching for the correct event much simpler than trying to mix caption and other types of events within a single array.

The presentation implements custom SlideManager and SlideEvent classes. As the slideshow stream plays, the playhead of the client movie's timeline must be moved to a labeled frame representing each slide at the appropriate time. The example uses an XML file to define the start times in seconds when each frame label should be played.