Decode flv in bytes in AS3 - actionscript-3

I am streaming flv file trough vlc media player running as http streaming server. So I am able to get the bytes but how to decode them?
Shoud I take float from the URLStream with readFloat() or plain bytes with readBytes()?

So long as only flv's are streaming, you will want to use the NetStream.appendBytesAction and NetStream.appendBytes for http streaming flv playback. Checkout the following blog post at ByteArray.org and also the quick example below:
AppendBytes
Playback Initialization:
var video:Video = new Video(width, height);
var video_nc:NetConnection = new NetConnection();
var video_ns:NetStream = new NetStream();
video_nc.connect(null);
video_ns.play(null);
video_ns.appendBytesAction(NetStreamAppendBytesAction.RESET_BEGIN);
video.attachNetStream(video_ns);
ProgressEvent.PROGRESS Handler:
video_ns.appendBytes(bytesAvailable);
This is essentially the jist of it, bytesAvailable will represent the read bytes from the event data buffer. A full example is listed below:
package
{
import flash.display.Sprite;
import flash.events.NetStatusEvent;
import flash.events.ProgressEvent;
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.net.NetStreamAppendBytesAction;
import flash.net.URLRequest;
import flash.net.URLStream;
import flash.utils.ByteArray;
[SWF(width="1280", height="720")]
public class NetStreamAppendBytes extends Sprite
{
var video:Video;
var video_nc:NetConnection;
var video_ns:NetStream;
var video_stream:URLStream;
public function NetStreamAppendBytes()
{
super();
video_nc = new NetConnection();
video_nc.connect(null);
video_ns = new NetStream(video_nc);
video_ns.client = this;
video_ns.addEventListener(NetStatusEvent.NET_STATUS, ns_statusHandler);
video = new Video(1280, 720);
video.attachNetStream(video_ns);
video.smoothing = true;
video_ns.play(null);
video_ns.appendBytesAction(NetStreamAppendBytesAction.RESET_BEGIN);
video_stream = new URLStream();
video_stream.addEventListener(ProgressEvent.PROGRESS, videoStream_progressHandler);
video_stream.load(new URLRequest("path_to_flv"));
addChild(video);
}
private function ns_statusHandler(event:NetStatusEvent):void
{
trace(event.info.code);
}
private function videoStream_progressHandler(event:ProgressEvent):void
{
var bytes:ByteArray = new ByteArray();
video_stream.readBytes(bytes);
video_ns.appendBytes(bytes);
}
}
}
Best of luck!

Related

Error with loader.dataFormat

So I have a class that should send data to an external php file.
Here is my code:
package {
import flash.display.Sprite;
import flash.display.DisplayObject;
import flash.display.Loader;
import flash.system.Security;
import flash.system.Capabilities;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.net.URLVariables;
import flash.net.URLLoaderDataFormat;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.AsyncErrorEvent;
import flash.events.SecurityErrorEvent;
public dynamic class myClass extends Sprite {
public static function showAd(mainParent:Sprite, devId:int, adWidth:int, adHeight:int, posX:int, posY:int):myClass {
var vars:URLVariables = new URLVariables();
vars["sandboxType"] = Security.sandboxType;
vars["ver"] = Capabilities.version;
vars["devid"] = devId;
// Init connection to the server
var zadsReq:URLRequest = new URLRequest("http://...");
zadsReq.contentType = "application/x-www-form-urlencoded";
zadsReq.method = URLRequestMethod.POST;
zadsReq.data = vars;
var loader:Loader = new Loader();
loader.dataFormat = URLLoaderDataFormat.TEXT;
self.addChild(loader);
loader.addEventListener(Event.COMPLETE, dataLoaded1);
loader.load(zadsReq);
return self;
}
public static function dataLoaded1(evt:Event):void {
trace('ok');
}
}
}
But I get this error:
1119: Access of possibly undefined property dataFormat through a reference with static type flash.display:Loader.
As you can see, I have already imported flash.net.URLLoaderDataFormat. So what could be the issue here?
The issue is that you are using a Loader object when what you need is URLLoader. For your reference, Loader is used to load local files (swf, gif, jpg, etc).
So, change the relevant part of your code to use a URLLoader rather than just Loader:
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.TEXT;
loader.addEventListener(Event.COMPLETE, dataLoaded1);
loader.load(zadsReq);

play flv using netStream appendBytes

I know that there are many ways to play an FLV file but considering my project requirements, I need to play the flv using URLStream and NetStream
here's the complete sample code that I'm doing my tests on:
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.NetStatusEvent;
import flash.events.ProgressEvent;
import flash.utils.ByteArray;
import flash.net.URLRequest;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.NetStreamAppendBytesAction;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.media.Video;
import flash.net.URLStream;
/**
* ...
* #author Hadi Tavakoli
*/
public class Main extends Sprite
{
private var netConnection:NetConnection;
private var netStream:NetStream;
private var ul:URLStream;
private var video:Video;
private var bytes:ByteArray = new ByteArray();
private var _isSeek:Boolean = false;
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
video = new Video();
addChild(video);
netConnection = new NetConnection();
netConnection.addEventListener(NetStatusEvent.NET_STATUS, netConnectionStatusHandler);
netConnection.connect(null);
}
private function netConnectionStatusHandler(ev:NetStatusEvent):void
{
switch(ev.info.code)
{
case 'NetConnection.Connect.Success':
ul = new URLStream();
ul.addEventListener(ProgressEvent.PROGRESS, onProgress);
ul.load(new URLRequest('01.flv'));
break;
}
}
private function onProgress(e:ProgressEvent):void
{
ul.readBytes(bytes, bytes.length);
if (!netStream)
{
netStream = new NetStream(netConnection);
netStream.client = { };
video.attachNetStream(netStream);
netStream.play(null);
trace("BEGIN")
netStream.appendBytesAction(NetStreamAppendBytesAction.RESET_BEGIN);
}
else
{
if (!_isSeek)
{
trace("SEEK")
netStream.appendBytesAction(NetStreamAppendBytesAction.RESET_SEEK);
_isSeek = true;
}
}
if (bytes.length == e.bytesTotal)
{
trace("END")
netStream.appendBytesAction(NetStreamAppendBytesAction.END_SEQUENCE);
}
netStream.appendBytes(bytes);
trace("-")
}
}
}
I'm not sure if I am using "appendBytes" method correctly? the video is shown but only a very few first frames will play and then the video stops!
in my eyes it seems all ok! do you have any advice on where my problem is?
I don't think you need the if (!_isSeek) block. It looks like you are pushing the bytes as you receive them in a sequential order and so there's never a seek. It looks like it will push the first set of bytes and then append a seek action and append the rest of the bytes. Try just removing that block and see if it works.
Otherwise I think it's ok.
in "ul.readBytes(bytes, bytes.length);" line, there is a bug i guess. It's never worked for me also. It always return full length (from 0 to the available bytes). So It have a huge memory leak. But if you are using flash player 11.4 or later, you can change it like this.
ul.position = bytes.length;
ul.readBytes(bytes);

Playing successive wav sounds in as3

I am trying to play through AS3 external wav sounds in a successive way. The obvious way to do it is to use this algorithm:
1. play sound 1
2. when sound 1 is done, play sound 2
etc.
The problem is that I fail the step number 2 (the "when sound 1 is done" part).
Please answer for wav sounds only, NOT mp3.
Here is my code:
package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.events.Event;
import flash.utils.ByteArray;
import flash.media.Sound;
import org.as3wavsound.WavSound;
import org.as3wavsound.WavSoundChannel;
public final class Main extends Sprite
{
public final function Main():void
{
playB.addEventListener(MouseEvent.MOUSE_UP, loadWav);
}
private final function loadWav(e:MouseEvent):void
{
var urlRequest:URLRequest = new URLRequest('Phone.wav');
var wav:URLLoader = new URLLoader();
wav.dataFormat = 'binary';
wav.load(urlRequest);
wav.addEventListener(Event.COMPLETE, playWav);
}
private final function playWav(e:Event):void
{
var tts:WavSound = new WavSound(e.target.data as ByteArray);
tts.play();
}
}
}
(This is step 1 of course)
Thanx
Try putting your sound into a SoundChannel - which is returned from the play command, then listen for the complete event:
private final function playWav(e:Event):void
{
var tts:WavSound = new WavSound(e.target.data as ByteArray);
var channel:WavSoundChannel = tts.play();
channel.addEventListener(Event.SOUND_COMPLETE, completeHandler)
}
private function completeHandler(e:Event):void {
//play next sound
}

as3 Adobe Air access iPad device camera

Is there a way you can use as3 to access iPad's camera?
I mean start the Camera within the app itself
have ability take a shoot and save the image to byteArray and applying the image to the background or doing some manipulation
I have done some research most of them just showing how to access the android devices.
Thanks for any suggestion or help.
Yes, you can absolutely do this. The beauty of Flash is that the code to do it is the same that you would use on Android or a PC.
Literally, you can do this to connect the camera to a Video object:
var camera:Camera = Camera.getCamera();
var video=new Video();
video.attachCamera(camera);
this.addChild(video); // 'this' would be a Sprite or UIComponent, etc...
There's a lot more to do if you want to do something useful, but it's fairly straight forward once you get started :)
bluebill1049, I'm not certain from the thread if you got what you were looking for, but I did see your request for the whole class. I found the same information (that Jason Sturges posted in his answer) in this post.
take photo using Adobe Builder (flex) for iOS
Unlike his reply here, his reply to that post had had a link to a great tutorial on building a mobile app and it was from that tutorial that this code was lifted/quoted. It requires an event class (event.CameraEvent - only a few lines) that's contained in that project/tutorial so it's important to be able to go back to the source, as it were. That source is located here:
http://devgirl.org/files/RIAUnleashed/
My thanks to Jason. Just so you don't have to dig, here's the event class that's missing from the quote:
package events
{
import flash.events.Event;
import flash.filesystem.File;
public class CameraEvent extends Event
{
public static const FILE_READY:String = "fileReady";
public var file:File;
public function CameraEvent(type:String, file:File=null, bubbles:Boolean = true, cancelable:Boolean = true)
{
super(type, bubbles, cancelable);
this.file = file;
}
}
}
Hope that helps!
Using the loader is not the only way to access the image bytes on iOS. It turns out the data is already in JPEG format to begin with, so encoding it again is not necessary.
Just do a mediaPromise.open() to get at the bytes and save them directly instead.
XpenseIt example code offers this camera implementation:
Class: CameraUtil:
package utils
{
import events.CameraEvent;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.MediaEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.media.CameraRoll;
import flash.media.CameraUI;
import flash.media.MediaPromise;
import flash.media.MediaType;
import flash.utils.ByteArray;
import mx.events.DynamicEvent;
import mx.graphics.codec.JPEGEncoder;
[Event(name = "fileReady", type = "events.CameraEvent")]
public class CameraUtil extends EventDispatcher
{
protected var camera:CameraUI;
protected var loader:Loader;
public var file:File;
public function CameraUtil()
{
if (CameraUI.isSupported)
{
camera = new CameraUI();
camera.addEventListener(MediaEvent.COMPLETE, mediaEventComplete);
}
}
public function takePicture():void
{
if (camera)
camera.launch(MediaType.IMAGE);
}
protected function mediaEventComplete(event:MediaEvent):void
{
var mediaPromise:MediaPromise = event.data;
if (mediaPromise.file == null)
{
// For iOS we need to load with a Loader first
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderCompleted);
loader.loadFilePromise(mediaPromise);
return;
}
else
{
// Android we can just dispatch the event that it's complete
file = new File(mediaPromise.file.url);
dispatchEvent(new CameraEvent(CameraEvent.FILE_READY, file));
}
}
protected function loaderCompleted(event:Event):void
{
var loaderInfo:LoaderInfo = event.target as LoaderInfo;
if (CameraRoll.supportsAddBitmapData)
{
var bitmapData:BitmapData = new BitmapData(loaderInfo.width, loaderInfo.height);
bitmapData.draw(loaderInfo.loader);
file = File.applicationStorageDirectory.resolvePath("receipt" + new Date().time + ".jpg");
var stream:FileStream = new FileStream()
stream.open(file, FileMode.WRITE);
var j:JPEGEncoder = new JPEGEncoder();
var bytes:ByteArray = j.encode(bitmapData);
stream.writeBytes(bytes, 0, bytes.bytesAvailable);
stream.close();
trace(file.url);
dispatchEvent(new CameraEvent(CameraEvent.FILE_READY, file));
}
}
}
}

Flash Webcam Permissions

I'm having an issue with flash, which I am not really familiar with. I'm basing this code off of what came with the wowza media server in the video chat example, but unlike that example flash is not prompting me for whether or not to allow the video camera.
Below is my actionscript:
import flash.events.MouseEvent;
import flash.events.NetStatusEvent;
import flash.media.Camera;
import flash.media.Microphone;
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.system.Security;
import flash.system.SecurityPanel;
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.StatusEvent;
public class QandA extends Sprite {
Security.LOCAL_TRUSTED;
private var nc:NetConnection = null;
private var camera:Camera;
private var microphone:Microphone;
private var nsPublish:NetStream = null;
private var nsPlay:NetStream = null;
private var videoCamera:Video;
public var prompt:TextField;
public function QandA():void {
stage.align = "TL";
stage.scaleMode = "noScale";
videoCamera = new Video(160,120);
addChild(videoCamera);
camera = Camera.getCamera();
microphone = Microphone.getMicrophone();
if (camera.muted) {
trace("Camera Muted");
Security.showSettings(SecurityPanel.CAMERA);
camera.addEventListener(StatusEvent.STATUS, statusHandler);
} else {
startCamera();
}
}
private function statusHandler(e:StatusEvent):void {
if (e.code == "Camera.Unmuted") {
trace("Camera Unmuted");
startCamera();
camera.removeEventListener(StatusEvent.STATUS, statusHandler);
} else {
trace("StatusEvent: " + e.code + " " + e.toString());
}
}
private function startCamera():void {
// here are all the quality and performance settings that we suggest
camera.setMode(160, 120, 12, false);
camera.setQuality(0, 75);
camera.setKeyFrameInterval(24);
microphone.rate = 11;
microphone.setSilenceLevel(0);
nc = new NetConnection();
nc.connect("rtmp://localhost/live/");
// get status information from the NetConnection object
nc.addEventListener(NetStatusEvent.NET_STATUS, ncOnStatus);
}
private function nsPublishOnStatus(infoObject:NetStatusEvent):void
{
trace("nsPublish: "+infoObject.info.code+" ("+infoObject.info.description+")");
}
private function ncOnStatus(infoObject:NetStatusEvent):void
{
trace("nc: "+infoObject.info.code+" ("+infoObject.info.description+")");
nsPublish = new NetStream(nc);
nsPublish.addEventListener(NetStatusEvent.NET_STATUS, nsPublishOnStatus);
nsPublish.bufferTime = 0;
nsPublish.publish("testing");
// attach the camera and microphone to the server
nsPublish.attachCamera(camera);
nsPublish.attachAudio(microphone);
}
}
I'm fairly confident it's something simple; as I've seen this code in/on countless sites when discussing how to publish to a live server.
Any help would be greatly appreciated, I've attempted using this code on a webserver to see if it was simply local security settings, but that was not the case.
Logs I receive when debugging the application in Flash CS5:
Attempting to launch and connect to Player using URL D:\development\qanda\qandaHost.swf
[SWF] D:\development\qanda\qandaHost.swf - 3583 bytes after decompression
Camera Muted
nc: NetConnection.Connect.Success (Connection succeeded.)
nsPublish: NetStream.Publish.Start (Publishing testing.)
Below is wrong:
Security.showSettings(SecurityPanel.**CAMERA**);
You should write:
Security.showSettings(SecurityPanel.**PRIVACY**);
I wasn't attaching the camera to the video, thus I couldn't see myself -- even though the video was in fact streaming.
private function startCamera():void {
trace("Attempting to start camera");
// here are all the quality and performance settings that we suggest
camera.setMode(160, 120, 12, false);
camera.setQuality(0, 75);
camera.setKeyFrameInterval(24);
videoCamera.attachCamera(camera);
microphone.rate = 11;
microphone.setSilenceLevel(0);
}