AS3 - How to save streaming video to an image sequence? - actionscript-3

When I am streaming a video (using RTMP) in my flash player (AS3) - the frames I see are colored [b]a bit [/b] differently than the frames in the original video !
I would like to somehow save the frames I am showing in my player to an image sequence,
so that I can examine it and understand the difference between each frame I was showing from the stream to the original frame in the original video.
How can this be achieved ? (the video is 5 minutes long, and has 25 frames-per-second).

First you should set the following flags on the fms script, which allows you to access the streaming video or audio.
application.onConnect = function(client,....)
{
...
client.audioSampleAccess = "/";
client.videoSampleAccess = "/";
}
Secondly on the client side, you may use the BitMapData.draw method to capture the video from the VideoDisplayObject
var snapshot:BitmapData = new BitmapData(video.width, video.height);
snapshot.draw(videoDisplay);

Related

AS3 Audio Synch & preloading

I have a video that is an swf file with length 03:02 (3 minutes & 2 seconds) 4552 Frames.
Now in different timing of this video I want to synch 4 audio files.
Is there any possibility to synchronize all sounds on the video?
My audio files must be placed in exactly positions. For example the second audio must be loaded at 01:27:30.
I have extended my timeline to 4552 frames (03:02) and I am using the code below in different frames to load my audio files:
var soundClip:Sound=new Sound();
//Create a new SoundChannel Object
var sndChannel:SoundChannel=new SoundChannel();
//Load sound using URLRequest
soundClip.load(new URLRequest("secondsound.mp3"));
sndChannel=soundClip.play();
And if there is a way to synch my audio files is there any possibility to preload the whole movie with all sounds and with my .swf file?
track the netstream time property and call your sounds when the video reaches the times you want to hear them.

html5+canvas+getusermedia: how to rec video

I want to record video from getUserMedia.
Itsdemo pageor this one (Press Start, then Stop, then Play recorded)
Every 67ms I make snapshot of the canvas and add data64 to array by: video_arr.push(canvas.toDataURL());
Frame rate of my "recorded" video (when to press Play recorded) is smaller than one frame in 67 ms. Why?
Or can somebody tell true way of record and then playing video from getUserMedia?
Its just an idea to do it. I hope it should help you.
Use blobbuilder to store the recorded frames and you need to convert the canvas data to blob for that use polyfill canvas to blob
here is the polyfill usage and download
http://eligrey.com/blog/
https://github.com/blueimp/JavaScript-Canvas-to-Blob
var bb = new BlobBuilder();//global variable
//record for every frame
canvas.toBlob(function(blob) {
bb.append(blob)
});
//onstop upload the blob builder data to server

How to slow down the Webcam reproduction

What I need to do is easy: the purpose of this test is show down the speed of my webcam when the camera capture a white pixel so:
1/ I create a Camera
this.cam = Camera.getCamera();
this.velocidad = 24; // I set up the fps in 24
this.cam.setMode(ancho,alto,velocidad);
vid = new Video(640,480);
vid.width = ancho;
vid.height = alto;
vid.attachCamera(cam);
addChild(vid);
2/ So now, when the pixel is recognized I need to change the current speed of the camera to 12 in order to slow down the user speed
I've tried with this code but the camera is frozen and nothing change.. I don't know if I have to delete the current instance of the camera and set up again with the disire fps
cam.setMode(640,480,12);
See Camera.setMode() to request a different frame rate, but note that what's available will depend on the camera.
I think this is not possible with just a config setting, property or method.
The possible solution would be to capture the cam and store its frames as bitmaps in and play (or render) them in sequence.
If this is not a commercial project, you can use this: http://code.google.com/p/flvrecorder/ to record and than load the video to play as you want.
Edit:
Here are some more links, since I can't code something for you now:
Post-processing captured video in AS3, creating slow motion
playing slow motion, fast forward , rewind in a video player in flash video player
Also, you can search Google for "as3 video slow" and it will give you more reference material and some examples.

Netstream and step() or seek()?

I'm on an AS3 project, playing a video (H264). I want, for some special reasons, to go to a certain position.
a) I try it with NetStream.seek(). There it only goes to keyframes. In my current setting, this means, i can find a position every 1 second. (for a better resolution, i'd have to encode the movie with as many keyframes as possible, aka every frame a keyframe)
this is definetly not my favourite way, because I don't want to reencode all the vids.
b) I try it with NetStream.step(). This should give me the opportunity to step slowly from frame to frame. But in the documentation it says:
This method is available only when data is streaming from Flash Media Server 3.5.3 or higher and when NetStream.inBufferSeek is true.
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetStream.html#step()
Does this mean, it is not possible with Air for Desktop? When I try it, nothing works.
Any suggestions, how to solve this problem?
Greetings & Thank you!
Nicolas
Flash video can only be advanced by seconds unless you have Flash Media Server hosting your video. Technically, that means that you can have it working as intended in Air, however, the video would have to be streaming (silly adobe...).
You have two options:
1) Import the footage as a movieclip. The Flash IDE has a wizard for this, and if you're developing exclusively in non-FlashIDE environment, you can convert and export as an external asset such as an SWF or SWC. This would then be embedded or runtime loaded into your app giving you access to the per-frame steppable methods of MovieClip. This, however, does come with some audio syncing issues (iirc). Also, scrubbing backwards is not an MC's forté.
2) Write your own video object that loads an image sequence and displays each frame in order. You'd have to setup your own audio syncing abilities, but it might be the most direct solution apart from FLVComponent or NetStream.
I've noticed that flash player 9 scrubs nice and smooth but in players 10+ I get this no scrub problem.
My fix, was to limit frequency the calls to the seek function to <= 200ms. This fixed scrubbing but is much less smooth as player 9. Perhaps because of the "Flash video can only be advanced by seconds" limitation? I used a timer to tigger the function that calls seek() for the video.
private var scrubInterval:Timer = new Timer(200);
private function videoScrubberTouch():void {
_ns.pause();
var bounds:Rectangle = new Rectangle(0,0,340,0);
scrubInterval.addEventListener(TimerEvent.TIMER, scrubTimeline);
scrubInterval.start();
videoThumb.startDrag(false, bounds);
}
private function scrubTimeline(e:TimerEvent):void {
var amt:Number = Math.floor((videoThumb.x / 340) * duration);
trace("SCRUB duration: "+duration+" videoThumb.x: "+videoThumb.x+" amt "+amt);
_ns.seek(amt);
}
Please check this Demo link (or get the SWF file to test outside of browser via desktop Flash Player).
Note: Demo requires FLV with H.264 video codec and AAC or MP3 audio codec.
The source code for that is here: Github link
In the above demo there is (bytes-based) seeking and frame by frame stepping. The functions you want to study mainly are:
Append_SEEK ( position amount ) - This will got to the specified position in bytes and search for the nearest available keyframe.
get_frame_TAG - This will extract a tag holding one frame of data. Audio can be in frames too but lets assume you have video-only. That function is your opportunity to adjust timestamps. When it's run it will also append the tag (so each "get_frame_TAG" is also a "frame step").
For example : You have a 25fps video, you want the third-frame at 4 seconds into playback...
1000 milisecs / 25 fps = 40 units for each timestamp. So 4000 ms == 4 secs + add the 40 x 3rd frame == an expected timestamp of 4120.
So getting that frame means... First find a keyframe. Then step through each frame checking the timestamps that represent a frame you want. If it isnt then change it to the same as most recent keyframe timestamp (this forces Flash to fast-forward through the frames to keep things in sync as it assumes the frame [with smaller than expected timestamp] should have been played by that time). You can "hide" the video object during this process if you don't like the look of fast-forwarding.

Pausing issue with flash webcam recording

I'm building a webcam recording app in CS5 and I'm having some seemingly random issues with the recorded flv. Currently I'm publishing a stream to Wowza Media Server using the standard _netstream.publish("movieName", "record") command. Everything regarding this works fine and I can play the file back but sometimes there's a 3 to 4 second pause at the beginning or end of the video. There will be a still frame and the time will sit at 0 and then snap to 4. I've explored bandwidth options and I've turned the resolution and quality down considerably and it doesn't seem to have any effect and the rest of the video will play back smoothly. Here are my current camera and mic settings.
_cam.setMode(160, 120, 30, false);
_cam.setQuality(0, 88);
_cam.setKeyFrameInterval(30);
_mic.rate = 11;
I'm also flushing the buffer before closing out the publish stream
_netstream.publish('null');
Could there be something going on with camera initialization/deactivation that causes the lag?
Any help would be greatly appreciated. Let me know if you need more details
I believe this has something to do with the way that the Flash plugin itself initializes and displays the camera.
If you set up a simple test to try setting and unsetting the video stream:
var cam:Camera = Camera.getCamera();
var webcam:Video = new Video(500, 375);
addChild(webcam);
var isPaused:Boolean = false;
function showWebcam():void {
if (!isPaused) {
cam = null;
} else {
cam = Camera.getCamera();
}
webcam.attachCamera(cam);
isPaused = !isPaused;
}
pausingButton.addEventListener(MouseEvent.CLICK, showWebcam);
You'll notice a definite pause as it switches between the two states.
From what I've seen, every time I call attachCamera() with a video object, there is a noticeable pause of the Flash Player itself (including all tweens, interactions, everything) when the method is called, even if the object I'm attaching is null.
Four seconds seems like an excessive lag, but I have noticed that the larger the input/video render and with smoothing = true set on the video object can affect the length of the delay.
As for a solution; I'm not sure if there is one achievable via pure Actionscript, since the delay appears to be down to how the Flash Player itself initializes and renders the live video object.