Im having a bit of a problem with controlling videos. I have this Main.as where I'm adding a child. The child contains a video thats looping.
In Main.as i run this, which just adds the video. (video is in _idleView)
_idleView = new IdleView(this.stage);
addChild(_idleView);
My IdleView.as looks like this. This is the constructor which adds the video and loops it.
_video = new Video();
addChild(_video);
_nc = new NetConnection();
_nc.connect(null);
_ns = new NetStream(_nc);
_ns.client = _meta;
_video.attachNetStream(_ns);
_ns.play(Settings.VIDEO_URL + "idle.flv");
In Main.as i will later on add a new child (by click) also containing a video. Just like the idleView but no loop. Whenever that new child gets added i want to be able to play the idleView video to the end, stop it, and then let the new childs video start to play.
Don't know how to achieve this really. Anyone?
Add a playVideo function to IdleView that just plays the idle video without looping it, then call it in your click handler:
_newChild:ChildVideo;
private function click(e:Event):void {
//other stuff
//Set the new child video to the _newChild variable
_idleView.addEventListener(Event.COMPLETE, onIdleVideoComplete);
_idleView.playVideo();
}
private function onIdleVideoComplete(e:Event):void {
_newChild.playVideo();
}
In IdleView:
public function playVideo():void {
_video = new Video();
addChild(_video);
_nc = new NetConnection();
_nc.connect(null);
_ns = new NetStream(_nc);
_ns.client = {};
_ns.client.onPlayStatus = onPlayStatus;
_ns.client = _meta;
_video.attachNetStream(_ns);
_ns.play(Settings.VIDEO_URL + "idle.flv");
}
private function onPlayStatus(item:Object):void {
if (item.code == NetStream.Play.Complete) {
dispatchEvent(new Event(Event.COMPLETE));
}
}
See also https://stackoverflow.com/questions/20736656/correctly-trap-onplaystatus-for-netstream and the Adobe docs for NetStream and playStatus
Related
I have an instance of a movieclip Video_Flow called flow. I'm trying to make it to play only when you press a button, but for some reason the audio starts playing every time I run the program. This is my code:
var flow:Video_Flow = new Video_Flow();
PlayButton.addEventListener(MouseEvent.CLICK, PlayVideo);
function PlayVideo(event:MouseEvent)
{
addChild(flow);
flow.x = 0;
flow.y = 50;
}
Because in AS3 objects can exist and operate even if they are not added to display list. As soon as you instantiate your Video_Flow it starts playing video. Adding it to display list only makes you able to see it.
var flow:Video_Flow;
PlayButton.addEventListener(MouseEvent.CLICK, playVideo);
function playVideo(e:MouseEvent):void
{
flow = new Video_Flow;
flow.x = 0;
flow.y = 50;
addChild(flow);
}
I want to loop a swf file that has been loaded with via the Loader class in AS3.
My code looks as following:
public class MyLoader extends MovieClip {
public function MyLoader() {
var myLoader:Loader = new Loader();
var url:URLRequest = new URLRequest("external-movie.swf");
myLoader.load(url);
myLoader.contentLoaderInfo.addEventListener("complete", function() {
});
addChild(myLoader);
}
}
From what I understand the Loader has no event for when the embedded movie is finished? Is there a way to figure that out? It must not be a AS3 implementation. I just want a movie that has been exported from Indesign to run in a loop. Thanks in advance
Especially when you have little experience programming you should avoid dirty shortcuts as they'll only get you a lot of trouble. So avoid anonymous function and avoid using string in place of static event variables.
This being said, if your loaded movie has its own timeline then it will be converted into a MovieClip. Also that movie is not embedded but loaded and that's a big difference.
Keep a reference of that movie and the loader:
private var theLoadedMovie:MovieClip;
private var myLoader:Loader;
Listen for the INIT event instead of the COMPLETE event (movies with timeline start to play when their first frame is loaded "INIT", the COMPLETE event fires when the whole movie is loaded).
myLoader = new Loader();
var url:URLRequest = new URLRequest("external-movie.swf");
myLoader.load(url);
myLoader.contentLoaderInfo.addEventListener(Event.INIT, handleInit);
In your handleInit method keep a reference of that movie:
theLoadedMovie = myLoader.content as MovieClip;
addChild(theLoadedMovie);
theLoadedMovie.addEventListener(Event.ENTERFRAME, handleEnterFrame);
in your handleEnterFrame method check the movie progress to know when it has ended:
if(theLoadedMovie.currentFrame == theLoadedMovie.totalFrames)
{
//movie has reached then end
}
My project has a main loader that load all the assets for the project. I need to load a bit of my video with it.
The video has 16mb, i want to load 3mb to use after the main loader is completed.
I've tried to open a new connection using Netconnection/Netstream to load 3mb and close the connection, but when the project starts and the video is played, a new connection is opened loading it from beginning.
I'm trying to find a way that i can use those 3mb already loaded. Doing this way, the user don't need to wait a main loader and a secondary loader (buffertime).
That's my code, sorry guys.
var loader:Loader = new Loader();
var nc:NetConnection = new NetConnection();
var ns:NetStream = new NetStream(nc);
var client:Object = new Object();
var swfRatio:Number;
var videoRatio:Number;
function init():void
{
nc.connect(null);
client.onCuePoint = cuePointHandler;
client.onMetaData = metaDataHandler;
ns.client = client;
loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressLoader);
addEventListener(Event.ENTER_FRAME, progressTotal);
loader.load(new URLRequest("swf/main.swf"));
ns.play("f4v/main_movie.f4v");
ns.pause();
}
function progressLoader(event:ProgressEvent):void
{
swfRatio = (event.bytesLoaded / event.bytesTotal);
}
function progressTotal():void
{
//Here i get the amount that i want to preload from my video, in this case i want 3mb or 3072000 bytes
videoRatio = (ns.bytesLoaded / 3072000);
//This is a variable that i use to fill my loader asset and verify if my content its totaly loaded.
var frameValue:int = ((videoRatio + swfRatio) / 2) * 100;
if (frameValue >= 100)
{
removeEventListener(Event.ENTER_FRAME, progressTotal);
// Here i close my connection, i suppose that i need to use the same connection in my player.
ns.close();
ns = null;
nc.close();
nc = null;
loaderComplete();
}
}
function loaderComplete():void
{
removeChild(assetLoader);
//Here i add my player to the stage, i want to use the preloaded video with him.
addChild(loader.content);
}
function cuePointHandler(infoObject:Object):void {
trace(infoObject.name);
}
function metaDataHandler(infoObject:Object):void {
trace("metaData");
}
Then in my player that i've just loaded and added to the stage i'm using OSMF to help me with controls.
To test the "preloaded video" i'm doing this:
private var mediaPlayer:MediaPlayerSprite;
private function _init(e:Event):void
{
this.removeEventListener(Event.ADDED_TO_STAGE, _init);
mediaPlayer = new MediaPlayerSprite();
addChild(mediaPlayer);
//And here OSMF start to load the entire main_movie.f4v again.
mediaPlayer.resource = new URLResource("f4v/main_movie.f4v");
}
It looks like your strategy would work if you let the video download completely. I'm assuming if the video downloaded completely, the browser may cache it and make it available to the next NetStream that comes along.
Your strategy looks OK otherwise. What you are doing (playing, then pausing the video immediately) is the way to start buffering the video. But since there are two NetStream's being used (one by the main loader, the other by the OSMF player) this won't work.
Perhaps you can devise a scheme where you pass the NetStream from the main loader into the loaded SWF (main.swf). So that it can use the data it's already downloaded. Just a thought, I've never tried this.
Another idea would be to get the OSMF player in your main.swf to do the buffering. That would mean the buffering would start happening only after main.swf is loaded (which may be too late).
I have this function where I want to get a movie clip (the function target) and change it to another one. The problem is that it obviously removes the movie clip before the new one is loaded.
var changePeca:Loader = new Loader;
var changeLoad:URLRequest = new URLRequest(e.target.name.substr(0,4)+".png");
changePeca.load(changeLoad);
e.target.removeChildAt(0);
e.target.addChild(changePeca);
I know that I must use the Event.COMPLETE thing, but how do I say which movie clip to remove, since I cant use e.target anymore?
"The problem is that it obviously removes the movie clip before the new
one is loaded."
Because you code says do so! :) You need to add the event listener which checks if the stuff is loaded.
private var holderMC:Sprite;
private var imageLoader:Loader;
private function load(e:Event):void
{
holderMC = e.target as Sprite // or something else you have there, just store it.
imageLoader = new Loader ();
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, handleLoadComplete)
imageLoader.load(new URLRequest(e.target.name.substr(0, 4) + ".png"));
}
private function handleLoadComplete(e:Event):void
{
if(holderMC.numChildren > 0)
holderMC.removeChildAt(0);
holderMC.addChild(imageLoader.content)
}
I'm using Loader to add AMV1Movie (movie created using Toon Boom Studio) to my AS3.0 stage. How can I determine when AMV1Movie plays it's last frame?
Without dispatching something from the original movie, you'd have to poll it's currentFrame and numFrames properties, and that will only be accurate if the main timeline is an accurate depiction of the animation/program. If the AVM1Movie animates via code or has nested movieclips, there's no good way to know when it is "finished".
The best bet is to open it up and add an event to the end.
I use ForcibleLoader to load AVM1Movie as MovieClip:
var uic: UIComponent = ....
...
var loader:Loader = Loader(1uic.addChild(new Loader()));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, startPlay);
var fLoader:ForcibleLoader = new ForcibleLoader(loader);
fLoader.load(new URLRequest("....swf"));
then I check if (movie.currentFrame + 1 >= movie.totalFrames)
I use this function to control uic.click event to stop and play movie:
private function controlSwf(event: Event): void {
var e: Event = event;
var movie: MovieClip = MovieClip(Loader(event.target).content);
if (movie.currentFrame + 1 >= movie.totalFrames) {
movie.gotoAndPlay(1);
play = true;
} else if (play) {
play = false;
movie.stop();
} else {
play = true;
movie.play();
}
}