Adobe Media Encoder CS4, , , " />

FlashPlatformist
Articles, Information, News, & Tutorials for Adobe Flash Platform Developers and Architects

Streaming Video with the F4V File Format

Adobe’s long awaited update to the FLV streaming video format, now called F4V, has finally come to fruition. It is true that F4V was supported as of version 9.0.r115 of the Flash player, but options were extremely limited as far as how to encode a video in that format. Included with each version of Creative Suite 4 (and Flash CS4 if purchased separately) is what Adobe is referring to as “Adobe Media Encoder CS4″. This is a substantial upgrade to the original “Flash Video Encoder” that has been around since Flash 8 was released, and includes a number of enhancements and major bug fixes. The most notable of these is the ability to encode to the new F4V format, which uses the H.264 video codec. This means that we can stream our videos in HD using a native Adobe Flash video format. Word on the street is that Flash Media Server 3 will get a significant upgrade any day now to support streaming of F4V files. It is unknown at this time whether or not this upgrade will actually be referred to as FMS4.

To get started with the F4V format, simply open the Flash Media Encoder CS4 program, and click “Add”. Now select a video file. Select the first arrow icon under “Format”.

The file that I selected was a .MOV file. However, assuming I want to use the F4V file format, I need to have “FLV | F4V” selected. Next, click the arrow icon under “Preset”, and choose “Edit Export Settings…” After selecting the Edit Export Settings option, a new window is brought up with a wide array of settings to customize the encoding. This is where we really see the enhancements that have been made with the new encoder. Now select the “video” tab in the middle of the window. Selecting the Video tab reveals a number of customization options.

After you’ve finished customizing the encoding options, select “OK” and then “Start Queue”. Your video will now start encoding with the options you selected. It is worth noting that you can save your customizations as a preset for easy access later.

Possibly Related Posts:



Posted by Dan Orlando on October 19th, 2008 :: Filed under Video Technology
Tags :: , , ,

Adobe Releases CS4

I’ve definitely had my hands full these last few days testing out the release of Creative Suite 4 and the new Adobe AIR, version 1.5 (not publicly available yet). I will publish information on the new version of AIR 1.5 after it has been released by Adobe. In the meantime, here is a summary of my findings with CS4 so far…

Adobe Creative Suite 4
Adobe is referring to CS4 as the company’s biggest release in its 25-year history. So far, I just might have to personally agree. Of particular interest, is the new 3D capabilities of Flash Pro CS4. Additionally, Photoshop CS4 Extended and Illustrator CS4 have both gotten upgrades to complement the new 3D capabilities of Flash.

Other new features of Flash include the “Bones” tool, which makes animating objects quicker and more realistic by creating relationships between connected objects using pivot points. For example, I could tell flash that my stick-man’s arm, forearm, and hand is connected and the elbow and wrist are the pivot point. I can then set certain parameters which let Flash know how these objects are related and what the movement restrictions are. Therefore, if my stick-man’s hand moves forward and up at an angle, the forearm and upper arm will automatically move with it. It’s pretty sweet once you figure out how to leverage the power of this tool.

Integration with Photoshop Extended and Illustrator has gotten better as well. For example, you can easily create a 3D object in Illustrator or Photoshop, and then Export it to Flash, where you can add your 3D animations to the object.

Possibly Related Posts:



Posted by Dan Orlando on October 18th, 2008 :: Filed under Flash Platform News
Tags :: , ,

Simple Papervision3D

Add Animated Transitions and Custom Navigation to Your Flex Viewstack Components

One of my biggest issues with the Flex Viewstack element is the lack of built-in transitions to choose from. So in this demonstration, I will show you how to create your own. We will first create a reusable animation factory class that we can call from anywhere in our application. Then, I will demonstrate how we can put the animation factory to work by creating a slide transition for a viewstack component. Note that Flex has a built in Slide object, and if you don’t mind mixing up your ActionScript behaviors with your MXML display, then that is also a viable option worth looking into for accomplishing the same end result. Just like anything you’ll find on this site though, we want to build abstraction and reusability into our code.

Step 1: Create the Animation Factory

Our first step is to create the animation factory class. We can instantiate this object from anywhere in an application and call the animateTo method, passing it the x, y position that we want it to end at, and the duration in milliseconds that we want the animation to last.

ObjectSlider.as

package {

   import flash.display.DisplayObject;
   import flash.events.Event;
   import flash.events.TimerEvent;
   import flash.utils.Timer;
   import flash.utils.getTimer;

   /**
    * @author Dan Orlando
    */
   public class ObjectSlider
   {
        // The object being animated
	private var _target:DisplayObject;
	 // Each time an animation starts we record its start time
	private var _startTime:Number;
	 // The duration of the animation in milliseconds
	private var _duration:Number;
	 // Record the target's start position
	private var _startX:Number;
	private var _startY:Number;
	 //  Record the difference between the starting and ending positions
	private var _deltaX:Number;
	private var _deltaY:Number;

	public function ObjectSlider() { }

   // Starts an animation that moves the target object from its current
   // position to the specified new position over a specified period of time.
	public function animateTo(target:DisplayObject, toX:Number,
           toY:Number, duration:Number):void {
	   //store where the target was when the animation started
	   _target = target;
	   _startX = _target.x;
	   _startY = _target.y;
	   // calculate difference between target's start position
           // and final destination
	   _deltaX = toX - _target.x;
	   _deltaY = toY - _target.y;
	   _startTime = getTimer();
	   //store how long the animation should take
	   this._duration = duration;
	   //update target's position each time a screen update occurs
	   _target.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
	}

   // Updates the target's position on each ENTER_FRAME event
	private function enterFrameHandler(event:Event):void {
	   var elapsed:Number = getTimer()- _startTime;
	   var percentDone:Number = elapsed/_duration;
	   if (percentDone < 1) {
	      updatePosition(percentDone);
	   }
	   else {
	      updatePosition(1);
	      _target.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
	   }
	}

   // Sets the position of the target object
	private function updatePosition(percentDone:Number):void {
	   _target.x = _startX + (_deltaX * percentDone);
	   _target.y = _startY + (_deltaY * percentDone);
	}

   }
}

Step 2: Create the MXML component
For our MXML display component, we will create a simple canvas that initializes a “helper” class that contains all of the behavior and functionality for the component in ActionScript. Note that when we instantiate the helper class, we pass it the current instance of our canvas component as a display object argument using the this keyword. We also place two left and right arrow buttons here, which we will use to move the viewstack back and forward by changing the selectedIndex value of the ViewStack when one of the buttons is clicked.

CustomCanvas.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="750" height="550"
   creationComplete="init()">
   <mx:Script>
      <![CDATA[
      import com.danorlando.util.ViewStackHelper;

      private var _helper:ViewStackHelper;

      private function init():void {
         _helper = new ViewStackHelper(this);
      }
      ]]>
   </mx:Script>

// place additional mxml components that should not be part
// of the viewstack here, like buttons, labels, etc...
   <mx:HBox x="693" y="56" horizontalGap="5">
      <mx:Button x="64" y="13" id="backBtn" styleName="iconButtonBack"
         width="16" height="16"/>
      <mx:Button x="85" y="13" id="forwardBtn" styleName="iconButtonForward"
         width="16" height="16"/>
   </mx:HBox>
</mx:Canvas>

ViewStackHelper.as

package com.danorlando.util
{
   import com.danorlando.display.components.CustomCanvas;
   import com.danorlando.effects.animation.ObjectSlider;
   import flash.display.DisplayObject;
   import flash.events.MouseEvent;
   import mx.containers.ViewStack;

   public class ViewStackHelper
   {
      private var _parent:CustomCanvas;
      private var _viewStack:ViewStack;
      private var _currentIndex:Number;
      private var _slider:ObjectSlider = new ObjectSlider();

      public function ViewStackHelper(canvas:Canvas) {
            _parent = object;
            addListeners();
            createChildren();
      }

   // add event listeners to the forward and back buttons
      public function addListeners():void {
       _parent.backBtn.addEventListener(MouseEvent.CLICK, viewStackBack);
       _parent.forwardBtn.addEventListener(MouseEvent.CLICK, viewStackForward);
      }

   // create and add the viewstack and it's children
      public function createChildren():void {
         _viewStack = new ViewStack();
         _parent.addChild(_viewStack);
         _viewStack.selectedIndex = 0;
         _viewStack.x = 39;
         _viewStack.y = 72;
         _viewStack.width = 675;
         _viewStack.height = 402;
         var vsChild1:Canvas = new Canvas();
         _viewStack.addChild(vsChild1);
      // add other components and params to the 1st index/child here
         var vsChild2:Canvas = new Canvas();
         _viewStack.addChild(vsChild2);
      // add additional components and params to the 2nd index/child here
         var vsChild3:Canvas = new Canvas();
         _viewStack.addChild(vsChild3);
      // add additional components and params to the 3rd index/child here
      // get the first child that is about to be displayed in the viewstack
         var curChild:DisplayObject = _viewStack.getChildAt(_currentIndex);
      // set the x-position of the child to the x-pos of the viewstack + 600
         curChild.x = _viewStack.x + 600;
      // now slide the child into view
         _slider.animateTo(curChild, _viewStack.x-40, 0, 500);
      }

   // event handler for the back button in the parent container
      private function  viewStackBack(event:Event):void {
         if(_currentIndex > 0) {
            _currentIndex = _currentIndex - 1;
            var newChild:DisplayObject = _viewStack.getChildAt(_currentIndex);
         // set the x-position of the new child 600 pixels to the right
            newChild.x = _viewStack.x + 600;
         // use the animateTo method of our animation factory to slide the new
         // child into position
            _slider.animateTo(newChild, _viewStack.x-40, 0, 500);
         // set the new index
            _viewStack.selectedIndex = _currentIndex;
         // set the forward button to visible if it is hidden
            if (!_parent.forwardBtn.visible) {
               _parent.forwardBtn.visible = true
            }
         // if the _currentIndex property is 0, then hide the back button
            if (_currentIndex == 0) {
                _parent.backBtn.visible = false;
            }
         }
      }

   // event handler for the forward button
      private function viewStackForward(event:Event):void {
         // get the highest index value of the viewstack
         var lastIdx:Number = _viewStack.numChildren-1;
         if(_currentIndex < lastIdx) {
            _currentIndex = _currentIndex + 1;
            var newChild:DisplayObject = _viewStack.getChildAt(_currentIndex);
          // place the incoming child 600px to the left
            newChild.x = _viewStack.x - 600;
          // slide the new child into position using our animation factory
            _slider.animateTo(newFaq, _viewStack.x-40, 0, 500);
          // set the new index of the viewstack
            _viewStack.selectedIndex = _currentIndex;
          // make the back button visible if it is hidden
            if(!_parent.backBtn.visible) {
               _parent.backBtn.visible = true }
          // hide the forward button if we are at the last index
            if (_currentIndex == lastIdx) {
               _parent.forwardBtn.visible = false;
            }
         }
      }

   }
}

Ok, so we’ve got a few things going on here in the helper class. The first thing we do is set the Canvas object that was passed in the constructor to our local (i.e. private) canvas property which is of type CustomCanvas. We then add the event listeners to the forward and back buttons of the parent container – which is the Canvas object that was passed in the constructor – with the addListeners method. We then instantiate the ViewStack and add its children with the createChildren method. You will see the use of our animation factory with the call to _slider.animateTo. Notice that we are initially setting the position of the child off to the left or the right, depending on which button was clicked, then we slide the child into place. Lastly, in order to ensure that we never get a runtime error because the forward button was clicked when we were already viewing the last child, or the back button was clicked when we were already on the first child, we simply set the visible property to false for the respective button based on said conditions.

Possibly Related Posts:



Posted by Dan Orlando on October 14th, 2008 :: Filed under Tutorials, User Experience
Tags :: , , , , , , , ,

New Technology for ActionScript Data Communications

I spent a large portion of this week learning a new technology based on a collaboration between Adobe and Zend Technologies for data communications and an unified workflow for PHP RIA developers. My assignment was to write up an article/tutorial on implementing the new technology into Flex/AIR applications. Since it is a new technology that has yet to be released to the public, the setup and configuration process was naturally a bit daunting. After I got it up and running though, I was pretty impressed with what this new technology offers. The article is set to be published initially at OnLamp.com immediately following the public announcement and release of this new technology. I will provide more details and additional information on getting up and running with this new technology here, but for now, mum’s the word.  :-)

Possibly Related Posts:



Posted by Dan Orlando on October 10th, 2008 :: Filed under General
Tags :: , , , , ,

Using Events to Instantiate Display Objects in an Ordered Fashion

For larger applications that have an ordered process by which objects are instantiated, you are sometimes required to position your objects on the stage using only Actionscript, at a certain time. For example, let’s say your business logic needs to gather all of its data and run through a series of tasks before the user interface can be displayed. It then must dispatch a custom event to notify the display layer that it is ready. However, you do not want display objects that are defined in your mxml to be instantiated prematurely, resulting in the infamous flex 1009 error, “Cannot access a property or method of a null object reference”. In this case, our best bet is to instantiate these objects through actionscript when the “ok, im ready now!” event is dispatched from our controller class. Let’s take a look at an example:

First, we’d want to add a listener on our controller for the “I’m Ready!” event, which we will call MODEL_INITIALIZED, like so:

private var _uiCtrl:UIController;

private function init():void {
     _uiCtrl = new UIController();
     _uiCtrl.addEventListener(ControllerEvent.MODEL_INITIALIZED, createDisplayObjects);
}

Here we assume that our UIController class has an event in it of type ControllerEvent, and dispatches the ControllerEvent.MODEL_INITIALIZED when it has completed all of its background work and is ready for the user interface to be displayed.

Our createDisplayObjects handler function would then look something like the following:

private function createDisplayObjects(event:ControllerEvent):void {
     createControlBar();
     createCanvas();
     createGrid();
}

Here we are simply calling a series of methods to create our display objects. The function takes event:ControllerEvent as an argument. If this is not included, we will get a runtime error that says “Expecting 0 arguments, received 1″.

Here is an example of what our display object instantiation methods would then look like:

private function createControlBar():void {
     var bar:CustomApplicationControlBar = new CustomApplicationControlBar();
     addChild(bar);
     bar.dock = true;
     bar.uiController = this._uiCtrl;
}

private function createCanvas():void {
     var canvas:Canvas = new Canvas()
     addChild(canvas);
     canvas.percentWidth = 100;
     canvas.percentHeight = 100;
     canvas.x = 10;
     canvas.y = 10;
}

private function createGrid():void {
     var grid:CustomDataGrid = new CustomDataGrid();
     canvas.addChild(grid);
     grid.x = 0;
     grid.y = 0;
     grid.width = 500;
     grid.height = 500;
     grid.dataProvider = _uiCtrl.gridData;
}

I should first point out that the example above is meant to provide a “real-world” example of what this might look like, so allow me to explain what is going on here. In the first method, createControlBar, we are instantiating a custom component that extends the Flex ApplicationControlBar component. The ApplicationControlBar component has a property called “dock”, which docks it to the top of the stage in such a way that it is always on top, and the stage’s 0,0 point is now directly under the ApplicationControlBar so no display object will ever get covered up by the control bar. Our CustomApplicationControlBar component has a property of “uiController”, which is the current instance of the UIController class. This gives our component access to the data model within the application.

The createCanvas method is pretty straight-forward and probably requires no explanation. The createGrid method however, has a few things going on. In this example, the CustomDataGrid component extends DataGrid. We are then adding this component to the canvas that we created above it. Lastly, we set the dataProvider property to an ArrayCollection, which was part of the data model that was created when the UIController was instantiated. Since we can access our entire data model through our UIController class, we can directly bind the dataProvider of our CustomDataGrid to any of the collections within our model.

Possibly Related Posts:



Posted by Dan Orlando on October 1st, 2008 :: Filed under Tutorials
Tags :: , ,