Text Layout Framework Chapter 10: Text 289 Flowing text across multiple containers The last example of the chapter is the most advanced and demonstrates one of TLF’s most powerful features: the ability to flow text across multiple containers. This is called linked text, or threaded text, because the text is not broken apart when populating more than one text field. Instead, it flows through linked text fields, threading its way through your layout. This is fur- ther demonstrated with selectable linked text and the ability to scroll within a field while selecting text—just like you can in a text editor. One of the first things you’re likely to notice, is that this script contains no direct reference to TLF text fields. Instead, it uses the concept of TLF containers—sprites or movie clips that are automatically populated with TLF text by Flash Player. This approach is very powerful because it means that anywhere you can create a sprite, you can fill it with TLF text, and even link it up as part of a chain of TLF text. For example, you could create many text fields across the stage and size them all to accommodate one line of text. You could then link them together, flow “The Rime of the Ancient Mariner” through them, and animate them up and down like undulating waves of water. Best of all, you can easily reflow the text along the linked chain whenever required. The following code is found in the tlf_containers.fla source file. Lines 1 through 6 import all the classes required to complete this exercise. 1 import flashx.textLayout.compose.StandardFlowComposer; 2 import flashx.textLayout.container.ContainerController; 3 import flashx.textLayout.container.ScrollPolicy; 4 import flashx.textLayout.conversion.TextConverter; 5 import flashx.textLayout.edit.SelectionManager; 6 import flashx.textLayout.elements.TextFlow; Lines 8 through 16 fill the field with text. Lines 8 through 12 create a string of TLF markup. Lines 9 and 12 open and close the TextFlow content, and lines 10 and 11 use the dummyText() function (found in lines 49 through 55) to fill the two paragraphs with dummy text. Lines 14 through 16 demonstrate how to create an independent TextFlow instance. They use the TextConverter class’s static method importToFlow() to convert the TextFlow markup into layout format. Not only does this allow you to separate the TextFlow from a text field for easy reuse, but it’s also particu- larly important here because we’re not making direct use of a TLF text field. 7 //create TextFlow instance 8 var textMarkup:String = 9 "<TextFlow xmlns='http://ns.adobe.com/textLayout/2008'>" + 10 "<p>" + dummyText() + "</p><br />" + 11 "<p>" + dummyText() + "</p>" + 12 "</TextFlow>"; 13 14 var textFlow:TextFlow = 15 TextConverter.importToFlow(textMarkup, 16 TextConverter.TEXT_LAYOUT_FORMAT); Download from Wow! eBook <www.wowebook.com> Part III: Text 290 Text Layout Framework Lines 18 through 25 do nothing more than create sprites for cosmetic pur- poses. They will lie under the TLF containers to provide a border for each. This process uses the borderedBox() function, in lines 57 through 63, to draw borders into the sprites. 17 //create border shapes for cosmetic purpose 18 var box1:Sprite = borderedBox(); 19 box1.x = box1.y = 10; 20 addChild(box1); 21 22 var box2:Sprite = borderedBox(); 23 box2.x = 240; 24 box2.y = 10; 25 addChild(box2); Lines 27 through 44 set up containers for the TLF text. Lines 27 through 29, and 31 through 34, create two sprites and position them side by side. Lines 36 through 39 turn these sprites into TLF containers using the ContainerController class. The containers and the width and height of each are passed to the class constructor. The class then does everything required to support TLF text display, all automatically. The last part of the container code occurs in lines 41 through 44. These lines link the containers together and ready them for TLF text. Line 41 adds a new StandardFlowComposer instance to the TextFlow object’s flowComposer prop- erty. Lines 42 and 43 add the two containers to the flow composer using the addController() method, and line 44 updates all the controllers, flowing the text among them. 26 //create TLF containers 27 var container1:Sprite = new Sprite(); 28 container1.x = container1.y = 20; 29 addChild(container1); 30 31 var container2:Sprite = new Sprite(); 32 container2.x = 250; 33 container2.y = 20; 34 addChild(container2); 35 36 var controllerOne:ContainerController = 37 new ContainerController(container1, 200, 200); 38 var controllerTwo:ContainerController = 39 new ContainerController(container2, 200, 200); 40 41 textFlow.flowComposer = new StandardFlowComposer(); 42 textFlow.flowComposer.addController(controllerOne); 43 textFlow.flowComposer.addController(controllerTwo); 44 textFlow.flowComposer.updateAllControllers(); Finally, lines 46 and 47 control the selection and scrolling options. Line 46 populates the interactionManager of the TextFlow with a SelectionManager instance. The interactionManager controls how a user can interact with a container. It can enable selection, editing, or both. In this case, the resulting TLF containers will allow users to select, but not edit, their content. N OT E It’s possible to draw directly into TLF containers, but if they are designed to scroll, they may cover one or more sides of the border. By placing self-contained border objects beneath the TLF contain- ers, this issue is avoided. Download from Wow! eBook <www.wowebook.com> Text Layout Framework Chapter 10: Text 291 Line 47 concludes our discussion by enabling vertical scrolling, but only for the second container. Because the two containers are linked and selectable, users will be able to select text across both containers. Because the second container is scrollable, dragging your mouse through the text will scroll up or down as long as content exists outside the bounds of the container in that direction. Figure 10-12 shows the result of this exercise, with a selection in progress. 45 //enable selection and scrolling 46 textFlow.interactionManager = new SelectionManager(); 47 controllerTwo.verticalScrollPolicy = ScrollPolicy.AUTO; 48 49 function dummyText():String { 50 var str:String = ""; 51 for (var i:int = 0; i < 60; i++) { 52 str += "dummy text "; 53 } 54 return str; 55 } 56 57 function borderedBox():Sprite { 58 var sp:Sprite = new Sprite(); 59 var g:Graphics = sp.graphics; 60 g.lineStyle(1, 0x000000); 61 g.drawRect(0, 0, 220, 220); 62 return sp; 63 } Figure 10-12. Text flowed across two TLF containers with selection in progress Distributing SWFs that use TLF TLF is significantly different from Classic text when it comes to distributing your SWFs. TLF works as a runtime shared library (RSL)—an external archive of code (and sometimes assets) that must be distributed with your SWF. When you publish your file, you will notice in the same directory as your SWF, that a document with the extension .swz has been created. This is the extension for a compressed runtime library. At the time of this writing, the N OT E Although technically a component, this is virtually transparent to the Flash Professional CS5 user. TLF is tightly integrated into the Properties panel and, unlike other components, does not need to be in the Library of your FLA before it can be used. Download from Wow! eBook <www.wowebook.com> Part III: Text 292 What’s Next? file is called textLayout_1.0.0.595.swz, but the numbers used in this filename may change with future releases. Unlike the classes and packages that are compiled into your SWF when you publish your projects, runtime shared libraries remain external. They must be distributed with your SWFs, and their location relative to your SWF should be maintained. For example, if the RSL is in the same directory as your SWF, this should be true when distributing your project, as well. In the case of the TLF, Flash Player will attempt to download the RSL from the Adobe website, but it’s still a good idea to keep your own copy with your SWF in case the Adobe site is unavailable. As external files, runtime shared libraries must be downloaded by the user, so using TLF adds about 160K to your overall project size. The good news is that you need to download each RSL only once. For example, if you create 10 projects that use TLF, and a reader views all 10 projects, the first project will initiate the download of the TLF RSL, but all remaining projects will use the library already on the reader’s hard drive. TLF also causes a problem when a parent SWF loads a child SWF that uses a TLF text field. We’ll discuss this in Chapter 13 when we discuss loading external assets. What’s Next? Text is fundamental to most ActionScript projects, and this chapter should give you the starting knowledge you need to explore text usage further. Once you’ve become more comfortable with using text (including tasks like dis- playing and formatting), start to delve deeper into the raw data that makes up text. Look at strings and break them into their constituent parts. Learn how to build and parse the paragraphs, words, and characters you see every day. Try to think of imaginative ways of generating, deconstructing, and otherwise manipulating text, such as combining string methods and properties with arrays and other ActionScript elements. In the next chapter, we’ll look at many ways of using sound in ActionScript, including: • Understanding the new granular components of sound management, including individual sound channels and a global sound mixer • Playing, stopping, and pausing internal and external sounds • Controlling the volume and pan of sounds • Working with microphone input • Parsing data from sounds, including ID3 tags from MP3 files • Visualizing frequency amplitudes N OT E When authoring a TLF project, Flash Player will attempt to connect to the Internet to retrieve the RSL from Adobe’s site. If you do not have an active connection, you will see an error something like this: “Error opening URL ‘http://fpdownload.adobe.com/pub/swz/ crossdomain.xml’.” If you then activate a connection later, your code will work without this error. Download from Wow! eBook <www.wowebook.com> 293 IN THIS PART Chapter 11 Sound Chapter 12 Video Sound and Video PART IV Part IV covers sound and video, the media types that arguably contributed most significantly to the ubiquitous use of Flash on the web. Chapter 11 cov- ers the use of internal and external sound, and features examples of control- ling sound playback, as well as manipulating volume and stereo panning. The chapter also includes a brief overview of parsing ID3 metadata from MP3 sounds, for display during audio playback. Also featured is a sound visualization exercise that uses the Graphics class from Chapter 8 to draw a waveform in real time. The chapter concludes with new features that allow access to incoming microphone data, allowing you to record, play back, and even save microphone input. Chapter 12 contains information about encoding video using the free Adobe Media Encoder. The chapter also discusses two approaches to authoring video playback. By using components, you’re able to focus more on the bal- ance of your design and application as most of the ActionScript is taken care of for you. However, this chapter also includes the information necessary to code your own video player, so you can keep file size down if you choose not to rely on the video components. Finally, Chapter 12 provides true full-screen video examples, and covers accessibility and multilanguage projects through the use of video captioning. Download from Wow! eBook <www.wowebook.com> Download from Wow! eBook <www.wowebook.com> 295 IN THIS CHAPTER ActionScript Sound Architecture Internal and External Sounds Playing, Stopping, and Pausing Sounds Buffering Sounds Changing Sound Volume and Pan Reading ID3 Metadata from MP3 Sounds Visualizing Sound Data Visualizing Microphone Input Recording, Playing, and Saving Microphone Input What’s Next? As the ActionScript language has evolved, it’s interesting to see how far its sound capabilities have come. Although many audio and ActionScript experts alike will say that many issues still must be overcome before the Flash Platform truly conquers sound, few will deny that the current audio features far surpass anything available in ActionScript before. As of Flash Player 9 you can control multiple discrete channels of audio, gain direct access to the bytes of data that make up the actual sound file, process that data in several ways, and visualize its content. Flash Player 10 adds the ability to extract data from audio files, generate sound from scratch, save audio files, record microphone input without a server, and more. If you want to be inspired before beginning your journey into ActionScript sound control, visit http://www.audiotool.com and play with the incredibly impressive Audiotool. This amazing project replicates a feature-rich electron- ic music studio and allows you to pick from many sound synthesizers, pro- cess them through a host of effects, sequence them in a near infinite number of ways, and even save and share your compositions with others. Make no mistake: Audiotool is a very advanced project created by program- ming experts that have long led the way in ActionScript sound manipulation. In fact, much of what ActionScript can do today in this area is possible par- tially because of the efforts of this team—forever pushing the limits of the language—and the Flash Player engineers who were inspired to add greater sound features to Flash Player as a result. Will you be able to create anything of Audiotool’s complexity and quality after only working through this chapter? Realistically, no; such a project takes great skill, effort, and time to achieve. You will, however, have a good foundation of techniques on which you can build and evolve creative sound toys of your own. sound CHAPTER 11 Download from Wow! eBook <www.wowebook.com> Part IV: Sound and Video 296 ActionScript Sound Architecture To get you started, we’ll look at the following introductory topics in this chapter: • ActionScript Sound Architecture. Depending on what you want to do, you’re likely to work with a handful of sound-related classes in ActionScript 3.0. This section provides a quick overview of the most commonly used classes. • Internal and External Sounds. We’ll show you how to work with internal sounds found in your library, as well as load external MP3 sounds on the fly. • Playing, Stopping, and Pausing Sounds. In addition to playing and stopping sounds, you’ll learn how to pause and resume playback, as well as stop sound playback in all active channels at once. • Buffering Streaming Sounds. To optimize playback across slower con- nections, you can buffer, or preload, sounds. This ensures that sounds play longer without interruption while data continues to download. • Changing Sound Volume and Pan. The SoundTransform class gath- ers volume and panning features, allowing you to increase or decrease volume, as well as move sounds between the left and right speakers. • Reading ID3 Metadata from MP3 Sounds. When creating MP3 files, it’s possible to embed metadata, including artist name, track title, and so on, into the file. The ID3Info class allows you to parse this information, if available, for use in your application. • Visualizing Sound Data. Using ActionScript 3.0, you can dynami- cally poll the amplitude and frequency spectrum data of a sound during playback. You can use the information gathered to display visualizations of the sound, such as waveforms, peak meters, and artistic interpretations while the sound plays. • Working with Microphone Data. You can also access the micro- phone to check the activity level periodically to visualize the ampli- tude of a live sound source. Depending on the version of the Flash Player you want to target, and your ActionScript compiler, you can also access the raw microphone data. • Recording, Playing, and Saving Microphone Input. To end this chapter, we’ll use features introduced in Flash Player versions 10 and 10.1 to record microphone input, generate sound dynamically (rather than playing an MP3, for example), and save the result as a WAV file. ActionScript Sound Architecture The ActionScript 3.0 sound architecture, found in the flash.media package, is composed of several classes that contribute to a finer degree of control over sound data and sound manipulation than previously available. You’ll be Download from Wow! eBook <www.wowebook.com> ActionScript Sound Architecture Chapter 11: Sound 297 using several of these classes, so before moving on to specific examples, let’s take a quick look at each. Sound The Sound class is the first required to work with sound. It’s used to load and play sounds, and manage basic sound properties. SoundChannel This class is used to create a separate channel for each discrete sound file. In this context, we’re not referring to the left or right channel of a stereo sound. Audio playing in an ActionScript sound channel can be either mono or stereo. Instead, an instance of this class is analogous to a channel in a recording studio mixing desk. By placing each sound in its own chan- nel, you can work with multiple audio files but control each separately. SoundMixer As the name implies, the SoundMixer class creates a central mixer object through which all sound channels are mixed. Changes to the mixer will affect all playing sounds. For example, you can use this class to stop all sounds that are playing. SoundLoaderContext In conjunction with the load() method of the Sound class, you can use the SoundLoaderContext class to specify how many seconds of a sound file to buffer. SoundTransform This class is used to control the volume and panning between left and right stereo channels of a source. With it, you can also affect a single sound channel, the SoundMixer object (to globally affect all playing sounds), the microphone, and even the sound of a video. ID3Info The ID3Info class is used to retrieve metadata written into ID3 tags found in an MP3 file. ID3 tags store information about the MP3, includ- ing artist name, song name, track number, and genre. Microphone Using the Microphone class, you can control the gain, sampling rate, and other properties of the user’s microphone, if present. You can check the activity level of the microphone (and create simple visualizations of microphone amplitude values) in all versions of ActionScript. In Flash Player 10 and later, you can also access raw microphone data to visualize, process, and even save recorded input. Although we’ll demonstrate many capabilities of these classes, experiment- ing with sound is one of the most rewarding ways to learn more about what ActionScript has to offer. Be sure to carry on your learning after working through this chapter! Download from Wow! eBook <www.wowebook.com> Part IV: Sound and Video 298 Internal and External Sounds Internal and External Sounds Typically, ActionScript control of sound in your projects will include loading sounds from external sources. Keeping your sounds external to your primary SWF has many benefits. As two simple examples, external audio can keep the file size of your SWF from becoming too large, and it’s easy to change the sound files without having to recompile your SWF. Most of the examples we’ll cover in this chapter use external sound files, but it’s still possible to use internal sounds without having to rely on the timeline. To prepare for the remaining examples, we’ll show you how to store a refer- ence to both an internal and an external sound. Thereafter, you can adapt any exercise to use internal or external audio sources. Working with Sounds in Your Library Creating an instance of a sound from your Flash Professional library is con- sistent with creating an instance of a display object, as described in Chapter 4 and used throughout the book. After importing a sound, you’ll find it in the Library panel of your FLA file. Select the sound in the Library panel and open the Symbol Properties dialog. Click the Export for ActionScript check box and give the sound a class name. Flash Professional will automatically create a class name for you, but look at it carefully, as you may want to edit the provided text. For example, consider a sound in your library called claire elmo.mp3. When exporting this symbol for ActionScript, Flash Professional will remove the space for you (all class names must be one word) giving you claireelmo.mp3. However, you must still remove the period, which is also not allowed in a class name, and omit the file extension. Finally, it’s a good idea to capitalize the first character of class names and use camel case (uppercase letter for each new word) if you want to follow best practices. This gives you ClaireElmo, as shown in Figure 11-1. Appropriately, the Base class automatically assigned is the Sound class, so your class inherits all the accessible properties, methods, and events of the Sound class upon instantiation. Figure 11-1. Detail of the sound symbol’s Properties dialog; choosing a linkage class name for instantiating a sound symbol with ActionScript Download from Wow! eBook <www.wowebook.com> . borderedBox():Sprite { 58 var sp:Sprite = new Sprite(); 59 var g:Graphics = sp.graphics; 60 g.lineStyle(1, 0x 000 000 ); 61 g.drawRect (0, 0, 2 20, 2 20) ; 62 return sp; 63 } Figure 1 0- 12. Text flowed. container1:Sprite = new Sprite(); 28 container1.x = container1.y = 20; 29 addChild(container1); 30 31 var container2:Sprite = new Sprite(); 32 container2.x = 2 50; 33 container2.y = 20; 34 addChild(container2); 35 . addChild(container2); 35 36 var controllerOne:ContainerController = 37 new ContainerController(container1, 200 , 200 ); 38 var controllerTwo:ContainerController = 39 new ContainerController(container2, 200 , 200 ); 40