I am trying to do a little multimedia player where I have at least 9 small videoclips that I would like to place and play - all controlled by AS 3.0.
It might even be more than 9 clips, but they will show randomly in 9 places. A movie can switch viewport too.
I will preload them all into buffers and I would like to play them randomly at the same time.
This means that there could be 9 equally sized areas showing small movieclips including sound and random times.
Like this:
[1][2][3]
[4][5][6]
[7][8][9]
So its 1 Flash canvas/player showing them all at the same time.
Is this possible or will it crash Flash to play 9 movies including their sound? The movies might be of different length and will have to be reset and played many times, but I cant prerender the result as its randomly generated from user input.
Any sharp AS 3.0 guru in here who can point me in the right direction for this idea?
EDIT
like in... an example code of where to start? I've been thinking that I could put all the parts into one "sprite movie" and the play from frame XYZ for each "window" - but not sure how or if it will work... nor whats best approach.
I think it's more than possible. You create 9 video objects and you need 9 NetStreams for them. You set a timer to start each video respectively.
So the easiest is to have 9 flv names in an array, and 9 times in an array. Then you create a loop, where you create the 9 video objects, arrange them in a matrix, then use a timeout to start each at the specific time.
The easiest and shortest code I can think of is as follows:
//we use the same flv now
var flvs:Array = ["filename.flv", "filename.flv", "filename.flv", "filename.flv", "filename.flv", "filename.flv", "filename.flv", "filename.flv", "filename.flv"];
//setting the times in milliseconds
var times:Array = [0, 500, 1000, 1500, 2000, 2500, 3000, 3500, 4000];
//creating a NetConnection
var nc:NetConnection = new NetConnection();
//connect null, the flv is in the same folder and a simple file loading
nc.connect(null);
//the loop
for(var i:int = 0; i < times.length; i++)
{
var ns:NetStream = new NetStream(nc);
var video:Video = new Video(100, 100);
addChild(video);
//i%3 and int(i/3) arranges them in a 3x3 matrix
video.x = (i%3) * video.width;
video.y = int(i/3) * video.height;
video.attachNetStream(ns);
//the tricky timeout to call the funcion playFlv, in times[i] time, for the specific nc NetStream to play the given flvs[i] flv
flash.utils.setTimeout(playFlv, times[i], ns, flvs[i]);
}
function playFlv(ns:NetStream, flv:String):void
{
ns.play(flv);
}
Yes this is definitely possible. You will want to optimize you videos as much as possible of course. There is precedent for this in the Pine Point website, (you'll have to navigate to the "shelf life" section, and hit "next" a few times to see it) It is playing 12 videos at once, all different lengths. In terms of building it, its no different than playing one video, just repeat the steps X number of times.
I hope that helps,
Related
I have a setup of 4x4 drum pads which are essentially buttons or movie clips with 3 states to show visual feedback (like the lighting up of the pads when they are pressed). I have tested this setup on an android tablet as well as a windows 7 touch-enabled laptop. Obviously the windows 7 laptop is more powerful and thus more responsive.
But not responsive enough.
I am wondering how I should be approaching the loading of audio files which are short drum-kit sample sounds in mp3 format stored in an assets folder next to the swf file.
Is there a better way, such as a way to cache the sounds so that I don't have to reload them each time the sound event is triggered?
Any help on this is greatly appreciated. (I just am not aware of how else, right now, to approach loading sounds other than calling a new sound each time the pad is pressed, thus not really caching the sound)
var kickc_03:Sound=new kickc_03_mp3(); // not sure whether to use Sound() or kickc_03 here..
// or
var kickc_03:kickc_03_mp3=new kickc_03_mp3();
// they will both work because kickc_03_mp3 subclasses Sound.
if i were you i would do something like:
// execute this once
var drumNum:int = 16;
var soundArray:Array = [null];
var C:Class;
init();
function init():void{
for(var i:int=1;i<=drumNum;i++){
C = Class(getDefinitionByName("kickc_"+formatF(i)+"_mp3");
soundArray.push(new C());
}
function formatF(n:int):String{
var s:String=n.toString();
while(s.length<2){
s="0"+s;
}
return s;
}
//////////////////////////////////////////////
now anytime you want to generate a kickc_somenum_mp3 sound, use:
soundArray[somenum].play();
One of the things I most love about the MOD format is the ability to loop back to any given point in the song, making it perfect for songs that have an "intro" followed by a "main loop".
Of course, MP3 can't do this.
Up until now, I've done things like this:
<audio src="/path/to/song.mp3" onEnded="this.currentTime = 12.345;"></audio>
Where the float value is the time at which the main loop starts.
While this works there is a noticeable fraction-of-a-second pause as the audio restarts. I can lessen the effect of this pause by setting the target time a little ahead of where it should be, so the beats are at least kept closer in time, however it's not really ideal.
The main alternative I can think of is to manually loop the audio file (eg. in Audacity by copy-pasting) to produce a song that is longer than it would most likely be needed for, but the problem with that is that it would result in a lot of wasted hard drive space and bandwidth, and it wouldn't solve the problem of people liking a song and stopping to listen to it for a long time.
So I was wondering if there's any way to loop an MP3 stream. If I understand the format correctly, I should be able to determine at what position in the file (in bytes) the main loop starts (in seconds), so in theory I could construct a stream that loops indefinitely. However, would such a stream be supported by HTM5 audio?
Try measuring the delay each time:
function playSeamless(clip, next) {
if(!next) {
next = clip.cloneNode(true);
next.controls = false;
}
var start = Date.now();
clip.play();
setTimeout(function() {
var time = (Date.now() - start) / 1000;
var position = clip.currentTime;
var delay = time - position;
setTimeout(function() {
// Set desired currentTime on next here and adjust delay above
playSeamless(next, clip);
}, (clip.duration - clip.currentTime - delay * 2.35) * 1000 | 0);
}, 200);
}
playSeamless(yourAudioClip);
It was better, but not entirely accurate, so I need to adjust * 2.35 or make it a subtraction or something.
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.
I'm trying to make a pure AS3 game, and need a way to split the screen so that two players can have individual "cameras" that follow the around the game world. The problem is that a sprite can't have multiple parents. I'm trying to hack my way around this problem by having classes that duplicate sprites and manage all of their updates, but I'm not getting very far and my code is getting very, very ugly.
Does anyone know a good workaround or method for doing this? I can't seem to find much on-line on the subject.
I think you should use BitmapData copyPixels method
.copyPixels(point_0, rectangle_0)---> FirstPlayerScreen
World.Bitmap -
.copyPixels(point_0, rectangle_0)---> SecondPlayerScreen
Thanks for everyone's suggestions. What I've ended up with is a World class that I can add regular Sprite objects to as children. The World object manages and updates copies of those sprites, and world.getCamera() can be called as many times as necessary to display custom copies of the game world.
The key part is making copies of the sprites, this is the function I wrote to do that:
public function bitmapCopy(original:DisplayObject):Sprite
{
var returnSprite:Sprite = new Sprite();
if (original.width == 0 || original.height == 0) return returnSprite
var x = original.x; var y = original.y
var rotation = original.rotation
original.x = 0; original.y = 0; original.rotation = 0
var bounds:Rectangle = original.getBounds(original.parent)
var m:Matrix = new Matrix()
m.tx = -bounds.x
m.ty = -bounds.y
var bitmapData:BitmapData = new BitmapData( bounds.width, bounds.height, true,
0xFF0000 );
bitmapData.draw(original, m);
var bitmap:Bitmap = new Bitmap( bitmapData );
bitmap.x = bounds.x
bitmap.y = bounds.y
returnSprite.addChild(bitmap);
returnSprite.x = original.x = position.x
returnSprite.y = original.y = position.y
returnSprite.rotation = original.rotation = rotation
return returnSprite;
}
The returned Sprite can be added to the stage and will act in exactly the same way as the original (except for being static, of course). Hopefully this should help anyone else who comes across this problem.
Your theory is on the right track - you're probably just stumbling over your implementation. Organization and keeping things object-oriented will be your best friend in this scenario.
It's hard to give you a good example based off of a limited description of your game, but in general, I'd have a Screen class that can be instantiated multiple times, and I'd keep track of each instantiation (that gives us our multiple "players"). Each Screen has a stage, and you're building your game world on that stage.
The key here is data organization and good communication. Remember, there's only one "world", and you're just showing multiple instances of it. So you'll want a central Model to store data about every object in your singular game world. That Model will drive the rendering of that world to your multiple screens. If a player changes an object on their screen (let's say they move it), then you'll update the Model with that object's new location. Then, you'll broadcast those new coordinates to each Screen instance, so that all of your screens will update.
How you "broadcast" this can vary (and depends largely on the real-time nature of your game). If your game is very real-time and you're running a game loop, then you may just want to pass the objects' data along in every loop, and they'd update that way. If your game isn't as dependent of being real-time, then you can set up event listeners or a custom notification system that'll alert all of the instances of an object to update itself.
I know this is very high-level, but it's hard to give an in-depth answer without more info about your game. Hopefully this helps point you in the right direction - what you're attempting is definitely not simple, so don't get discouraged!
If you develop your game using MVC architecture principles then it should be trivial to draw your game twice, each player having an instance of the game's "view" but positioned according to a different character. If you give a layer mask to each instance then you could put the two instances side by side and so create a split screen effect.
Happy coding!
I'm working on a split screen myself just now:
masking to draw 1 world in 2 branches of your DisplayObject tree (separated cleanly), copying pixels for a split screen is a bad idea
data object to describe the world (not Sprite or DisplayObject)
Works very well so far. I've got 1 level, 2 players who move independently from each other and 2 screens that follow one player at a time. I see the other player in one player's screen and the one player in the other player's screen.
Here is how I did the data object part:
Define a central data object which describes the world and all it's world objects.
Write: make some sprites being able to manipulate 1 object of the world.
Read: update sprites by checking the properties of the world objects. 2 Screens -> 2 sprites for every world object. Check them every frame or try events.
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.