9.3. Scripting Your Own Video Control If you're not using Flash 8 Pro or don't want to weigh down your Flash movie by using components, ActionScript will give you full control over external FLV files. A few lines of code accomplish the same thing the components did, with a smaller file size. You will lose the graphical interface provided by the components, but you can create your own or do without. Sometimes you just want a video to begin playing automatically and to present required information to the user without a controller, but for this project, you will create simple play and stop buttons. Don't use components for this, however. Instead, roll your own buttons. 9.3.1. Creating a Video Object To load an external FLV into your file, either from a server stream or a local file, you need to have a video object on the Stage: Create a new file and save it as nero4.fla in your 09 folder. Set the document dimensions to 320 x 280. Open the Options menu in the Library and choose New Video. The Video Properties dialog will display, asking you to name the symbol and choose the type of video you intend to create. Name the symbol Video 1 and select the "Video (ActionScript-controlled)" option. Rename Layer 1 in your timeline video, and drag an instance of Video 1 to the Stage. Resize it to 320 x 240 pixels, and position it at (0, 0). Assign the video object an instance name of my_video and lock the video layer. In a few minutes, you'll reference my_video in the ActionScript for the project. First, however, you need to connect to the video source and stream it. 9.3.2. Making a Connection Remember from the earlier discussion on "Streaming Versus Progressive Download" that the term stream is most accurately used when referring to data being transmitted by streaming server software, such as the Flash Media Server 2. When scripting your own video interface, you will use the ActionScript necessary to receive a stream, but change one parameter if you wish to load a file via progressive download. NULL | A null value is a way to specifically say that there is no value at all. This is better than using 0, for example, because 0 is actually a value: it is an integer and it has a Number data type, and therefore it cannot stand in for the equivalent of no value. Using null, instead of using nothing at all, tells the ActionScript compiler that the value required has not been accidentally omitted. Consider an example explained earlier in this chapter (repeated here for context). When working with external Flash video files, or FLV files, you can literally connect to a streaming server and receive the FLV via streamed data, or you can download the FLV, either from a remote location or locally, until it is on your local system and ready to play. The latter file may appear to stream, because Flash can buffer a portion of this type of FLV and then continue to download the file in progressive stages even while the video is playing. However, this method of delivery, known appropriately as "progressive download," is not really streaming. So, if connecting to a server is expected in the first part of the process of playing an FLV, you must tell the ActionScript compiler that you will not be taking that step. For example, assume the syntax for connecting to an actual server is: var connection_nc: NetConnection = new NetConnection(); connection_nc.connect("URI_to_server_here"); If you wanted to use a progressive download FLV, and therefore didn't want to connect to a server, you might think of omitting the URI value, like this: var connection_nc:NetConnection = new NetConnection(); connection_nc.connect(); However, the ActionScript compiler would interpret that as an omission by mistake. Instead, you need to send a null value in the place of the URI, indicating to the compiler that you don't want to connect and want to work with a progressive download FLV instead. It is not always possible to replace an undesired value with null, but it a useful tool when this option is understood by the syntax with which you're working. | The first step is to create a NetConnection object. In simple terms, this is the part of the process needed to connect to a specific server. This is also where the aforementioned parameter change will allow you work with a nonstreaming file. The second step is to create a NetStream object. This is the actual stream that you will receive from the connection established earlier. Although it's an imperfect analogy, it may help to think of the NetConnection as the phone call you make to a company switchboard, and the NetStream as the conversation you have via one of the extensions at the company. That is, the main phone line is the server to which you connect. You then specify which extension you want to talk to, and that data is delivered. The complete process is not difficult. Here, you will add a simple button control to create a working file that is similar to the previous component examples, but much smaller: Add a new layer called actions. In frame 1 of the actions layer, build a script over the following five steps. First, create a NetConnection object and give it the name connection_nc: var connection_nc:NetConnection = new NetConnection(); Next, use that object to connect to a Flash Media Server by passing the URI of the server to the object. Or, in this case, specify that the object should not make a connection by passing a null value in for the server URI. (See the "Null" sidebar for more information about null values.) This tells the connection object that you will be working with a progressive download rather than a stream, so the object will not actually expect to communicate with a server: connection_nc.connect(null); Next, you want to create a NetStream object that will hold the specific stream from the server connection or, in this case, the progressive download file. Call it stream_ns: var stream_ns:NetStream = new NetStream(connection_nc); Now that the stream has been created, tell it to buffer five seconds of the file before allowing playback to begin. This helps keep the download process ahead of the playback: stream_ns.setBufferTime (5); If you are working with very limited or overtaxed bandwidth, the playback may catch up to the download, and the video will stutter or stop. In that case, you may need to increase the buffer amount to give the download process a bigger head start. Finally, attach the video delivered by the stream_ns object (whether it is an actual stream or a download) to the video object you created on the Stage: my_video.attachVideo(stream_ns); Save your movie. This part of the script is done. Now you just have to wire up the buttons to control the objects you just created. 9.3.3. Wiring a Simple Interface While the previous examples had full-featured controllers, this project will be brief and simple. Once you've had success with three simple buttons, you can move on to adding additional elements to the interface: Add two layers below your actions layer. Name the lower of the two buttons, and give the name buttons text to the layer immediately below actions. In the buttons text layer, create three static text elements that say Play, Pause/Resume, and Stop. In the buttons layer, create an invisible button that can easily be reused for all three playback control purposes. (If you need a refresher on invisible buttons, see the similarly named section in Chapter 4.) Give them instance names of play_btn, pause_btn, and stop_btn, and match them with the appropriate text in the buttons text layer. Now move on to the scripting. Create an onRelease event handler and instruct the stream_ns object to play the nero_01.flv file: play_btn.onRelease = function():Void { stream_ns.play("nero_01.flv"); }; For the Pause/Resume button, create a simple toggle. This is inadequate in the long run, because it provides no visual feedback, but it will serve its purpose here, keeping the code simple and easy to understand. Create a Boolean (true/false) variable and start it off with a value of false. Your video will not begin in the paused state: var pausedState:Boolean = false; Note: For an example of a toggle with visual feedback, see the bonus mute_01.fla file in the 08 folder. Be sure to read Chapter 8 first, for any necessary background.
Next, create an onRelease event handler for the Pause/Resume button. Every click must reverse the true/false value of the variable you just created. When the value starts as false, make it true. Conversely, if it's true, make it false. Do this by using the not operator. (For more information, see the sidebars on conditionals and operators in Chapter 7.) Finally, use the pause property of the stream object, sending in the true or false value you just modified: pause_btn.onRelease = function():Void { pausedState = !pausedState; stream_ns.pause(pausedState); }; The last step is to create your Stop button. As far as the streaming process goes, all that remains is to close the connection. However, this will leave the asset visible in the on-Stage video object, so you need to clear that so it will disappear: stop_btn.onRelease = function():Void { stream_ns.close(); my_video.clear(); }; Save your work and test your movie. Note: Closing down the stream object is just like hanging up a phone at the end of a conversation. It signals the end of communication with the party on the other line (equivalent to the stream or progressive download asset), and it frees up the line for another conversation later (akin to freeing the memory used by the now-terminated stream and allowing future streams). Your file should now play and stop when you click the Play and Stop buttons and pause and resume with each successive click of the Pause/Resume button, as seen in Figure 9-5. If you have any problems, check your work against the nero_04.fla file in your 09 folder. Figure 9-5. The completed custom player Ideally, this chapter has given you an overview of video use in Flash, without being too difficult. You've covered a lot of ground here, including embedded and external video assets, using components, and scripting your own video controls. The only significant remaining asset type is text, which will be discussed in Chapter 11. First, however, you'll take one last look at visual assets. 9.3.4. What's Next? Before you continue, try to expand on what you've learned in this chapter. Practice compressing video files using Flash, the Flash 8 Video Encoder, and the Flash 8 Video Exporter, if you can install it in a video editing application. Compare and contrast the quality and compression speeds of each tool. Investigate some of the video features not covered in the limited space of this text. Look into cue points and how to embed them in FLV files and make use of them. Cue points are like frame labels, in that they are markers that are added to FLV files prior to, or during, compression, and they can be recognized by ActionScript and used as navigation points when seeking through the video. They can also be used for synchronizing video events with other parts of your Flash file. Finally, build more robust custom controllers. Start with the remainder of the FLV Playback Custom UI components, and then move on to expand on your simple hand-scripted interface. In the next chapter, you will discover a number of ways to composite bitmap and vector assets on the fly and learn how to inject a heightened sense of expression into your files with real-time filter effects. You will: Learn how to increase the performance of movie clips by caching them as bitmaps at runtime Apply bitmap effects to movie clips, including custom filters such as Drop Shadow, Bevel, and Glow, which have long been popular in bitmap editing applications such as Photoshop Composite bitmaps and movie clips at runtime using blend modes such as Darken, Screen, and Multiply (also long-time features of many bitmap editors) Come to understand the core ActionScript structures arrays and loops |