Since the YouTube video revolution of 2006, Flash has been the premiere method of video delivery through web browsers, avoiding the fragmentation that otherwise persisted as a result of warring codecs and players. The VP6
Flash Video (FLV
) format standardized most video playback over the Web in alignment with Flash Player. Over the years, different container formats and codecs have been added to the Flash Player to keep up with industry trends, including H.264
decoding with Flash Player 9. With Flash Player 11, we have a set of new enhancements to take advantage of.
With Flash Player 11, developers now have the ability to encode H.264
video streams within the Flash Player itself. Prior versions of the runtime were able to decode H.264
and with the additional encoding functionality, a whole other set of applications can be built to record and broadcast in this industry standard format.
Warning
H.264/AVC software encoding is only available on the desktop. Mobile devices cannot utilize this feature due to the amount of CPU it takes to encode the streams.
To compile and run the examples included below effectively, it is recommended that you install Flash Media Server.
Note
Note that if you do not have access to a commercial license for Flash Media Server, Adobe does offer a free developer edition with which you can test this and other examples. When doing any serious work through FMS, it is encouraged that you begin with a local development instance such as this.
Flash Media Server developer edition can be acquired from Adobe via http://www.adobe.com/products/flashmediaserver/
Warning
Flash Media Server is available for either Windows or Linux.
To encode a video stream using H.264
within Flash Player 11, we must employ the new H264VideoStreamSettings
class and associated objects. When constructing a H264VideoStreamSettings
instance for use in our project, we can set the particular profile and level of the encoding. This is useful for targeting certain specific devices which may only support something like baseline encoding. Once we have configured our H264VideoStreamSettings
instance, we assign it to the videoStreamSettings
property of a NetStream
instance and then process the stream as normal.
package { import flash.display.Sprite; import flash.events.NetStatusEvent; import flash.media.Camera; import flash.media.H264Level; import flash.media.H264Profile; import flash.media.H264VideoStreamSettings; import flash.media.Video; import flash.net.NetConnection; import flash.net.NetStream; import flash.text.TextField; import flash.text.TextFormat; [SWF(width="600", height="500", backgroundColor="#CCCCCC")] public class AVCEncode extends Sprite { private var traceField:TextField; private var video:Video; private var camera:Camera; private var connection:NetConnection; private var stream:NetStream; private var streamClient:Object; public function AVCEncode() { generateDisplayObjects(); performOperations(); } protected function generateDisplayObjects():void { video = new Video(stage.stageWidth, stage.stageHeight); addChild(video); var defaultFormat:TextFormat = new TextFormat(); defaultFormat.font = "Arial"; defaultFormat.size = 24; defaultFormat.color = 0xFFFFFF; traceField = new TextField(); traceField.backgroundColor = 0x000000; traceField.alpha = 0.7; traceField.autoSize = "left"; traceField.background = true; traceField.defaultTextFormat = defaultFormat; addChild(traceField); } protected function performOperations():void { camera = Camera.getCamera(); camera.setMode(stage.stageWidth, stage.stageHeight, 30); camera.setQuality(60000, 80); video.attachCamera(camera); streamClient = new Object(); streamClient.onBWDone = onBWDone; connection = new NetConnection(); connection.client = streamClient; connection.addEventListener(NetStatusEvent.NET_STATUS, monitorStatus); connection.connect("rtmp://localhost/live"); } protected function monitorStatus(e:NetStatusEvent):void { traceField.appendText(e.info.code + "\n"); if(e.info.code == "NetConnection.Connect.Success"){ beginStreaming(); }else if(e.info.code == "NetStream.Publish.Start"){ traceField.appendText("\n" + e.info.description + "\n"); traceField.appendText("codec: " + stream.videoStreamSettings.codec); } } protected function beginStreaming():void { var h264Settings:H264VideoStreamSettings = new H264VideoStreamSettings(); h264Settings.setProfileLevel(H264Profile.BASELINE, H264Level.LEVEL_2); stream = new NetStream(connection); stream.addEventListener(NetStatusEvent.NET_STATUS, monitorStatus); stream.videoStreamSettings = h264Settings; stream.attachCamera(camera); stream.publish("mp4:h264livestream.f4v", "live"); } public function onBWDone():void {} } }
So long as we have Flash Media Server installed and running on our local machine, we will receive a message stating that the stream is being published and that the codec being used to encode the video is H.264
, along with a preview of the camera feed. In this example, we are simply viewing the raw camera output and not the encoded stream.
The ability to decode H.264
has been available since Flash Player 9. To play back a stream or file encoded to H.264
with Flash Player 11 is the same procedure we would normally use. First, create a NetConnection
and establish a connection to Flash Media Server. In this case, we use rtmp://localhost/live, as the server exists on the same machine. We then hook in a NetStream
object and request to play the previously published stream.
package { import flash.display.Sprite; import flash.events.NetStatusEvent; import flash.media.Video; import flash.net.NetConnection; import flash.net.NetStream; import flash.text.TextField; import flash.text.TextFormat; [SWF(width="600", height="500", backgroundColor="#CCCCCC")] public class AVCPlayback extends Sprite { private var traceField:TextField; private var video:Video; private var connection:NetConnection; private var stream:NetStream; private var streamClient:Object; public function AVCPlayback() { generateDisplayObjects(); performOperations(); } protected function generateDisplayObjects():void { video = new Video(stage.stageWidth, stage.stageHeight); addChild(video); var defaultFormat:TextFormat = new TextFormat(); defaultFormat.font = "Arial"; defaultFormat.size = 24; defaultFormat.color = 0xFFFFFF; traceField = new TextField(); traceField.backgroundColor = 0x000000; traceField.alpha = 0.7; traceField.autoSize = "left"; traceField.background = true; traceField.defaultTextFormat = defaultFormat; addChild(traceField); } protected function performOperations():void { streamClient = new Object(); streamClient.onBWDone = onBWDone; connection = new NetConnection(); connection.client = streamClient; connection.addEventListener(NetStatusEvent.NET_STATUS, monitorStatus); connection.connect("rtmp://localhost/live"); } protected function monitorStatus(e:NetStatusEvent):void { traceField.appendText(e.info.code + "\n"); if(e.info.code == "NetConnection.Connect.Success"){ beginStreaming(); } } protected function beginStreaming():void { stream = new NetStream(connection); stream.addEventListener(NetStatusEvent.NET_STATUS, monitorStatus); stream.play("mp4:h264livestream.f4v"); video.attachNetStream(stream); } public function onBWDone():void {} } }
When this class is compiled to SWF
, so long as we have the encoded stream successfully published to Flash Media Server through the previous code example, we will see the published, natively encoded H.264
stream render through a Video
object similar to Figure 4-2.
Get What's New in Flash Player 11 now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.