How can I copy a NetStream Object? - actionscript-3

I'm using BulkLoader to load an array of 10 or so FLV files. I want to be able to use and control these FLVs throughout my app independently. So for instance, FLV_1 may be displayed in duplicate but I want to pause one instance and play the other in tandem.
I would like to pass the NetStream object around to other Video objects and display both. Is this possible? If so, how do I go about doing it?

It's definitely possible. BulkLoader will expose you the NetStream object, so you can pass it around to Video or anything else, for example:
var videoItem : VideoItem = bulkLoader.get("my-video.flv");
var video : Video = new Video();
video.attachStream(videoItem.content);
// or the shortcut:
video.attachStream(bulkLoader.getNetStream("my-video.flv");
Regards

Haven't tested this but logically you shouldn't be able to play more than one video containing the same instance of a NetStream asynchronously, simply because the pause/play/etc. methods are triggered directly on the NetStream instance (and not on the Video containers...).
On the other hand you can probably play the same instance of a NetStream synchronously within different Video instances (to be double checked!).
Probably the easiest hack would be to load the same FLV into two different items (in case you use BulkLoader) referencing them with unique ID's and hoping the end-user has his browser cache enabled. Thereafter you would add and control each NetStream separately just as if you were handling two different movies.

Related

How do you change source in a web audio context

I'm making a game that changes some of it's object depending on what music is playing. After each song has ended I want my audio context to load in a new source and analyze that. However whenever I tried to do that I've gotten the error that an audio object or buffer can't be called twice.
After some researching I learned that ctx.createMediaElementSource(MyHTML5AudioEl) lets you create a sourceNode that takes the source from a HTML5 object. With this I was able to loop through different song.
However for my game I need to play/analyze a 30 seconds "remote url" that comes out of the Spotify API. I might be wrong but ctx.createMediaElementSource(MyHTML5AudioEl)does not allow you to analyze a source that is on a remote site.
Also the game needs to work on Mobile Chrome, which createMediaElementSource(MyHTML5AudioEl) does not seem to work on.
I might be on the completely wrong path here but my main question is:
How can I switch remote songs urls in web audio api. With it being compatible with mobile chrome.
Thanks!
First, as you found out, you can't set the buffer again for an AudioBufferSource. The solution is to create a new one. AudioBufferSources are intended to be light-weight objects that you can easily create and use.
Second, in Chrome 42 and newer, createMediaElementSource requires appropriate CORS access so you have to make sure the remote url sends the appropriate headers and you set the crossOrigin attribute appropriately.
Finally, Mobile Chrome currently does not pass the data from an audio element through createMediaElementSource.

How to get Flex SWFLoader unloadAndStop to unload sound also?

public var swfLoader:SWFLoader = new SWFLoader();
[Embed(source="/some/file1.swf")]
public var file1:Class;
[Embed(source="/some/file2.swf")]
public var file2:Class;
then I do:
swfLoader.load(file1);
Later on:
swfLoader.unloadAndStop(true);
which unloads the video, but not the sound! So I add in
SoundMixer.stopAll();
Which is ok, for a while. Later on, I do:
swfLoader.load(file2);
And eventually, while watching file2, file1's audio will start playing in the background over file2's audio, with no way to stop it! What is the proper way to stop the audio of file1? The way I keep seeing is use unloadAndStop() which I am using. Unless I have to create a new swfLoader object each time?
As per Konrad's answer below, I should stop playing the sound in cleanup events, such as REMOVED_FROM_STAGE, however, how can I stop playing the sound on a swf file that is loaded with a SWFLoader? I don't see an obvious way to do that.
Solutions is bit tricky, because problem is with loaded content.
Garbage collector won't remove sound because it is still playing (so its referenced by Flash Player) but you don't have access to its sound channel (because its hidden similar to private variables in classes). That behavior is totally correct.
Solution: In loaded swf code you should stop playing that sound (in REMOVED_FROM_STAGE or other 'cleanup' event handler). Other solutions (like SoundMixer.stopAll) will work in some cases but not in all.
We often forget to clean after ours applications. Its not problem if they exist same as instance of Flash Player (removing it will clean all memory used by our swf). Problems begins when we load and unload swfs. Ignoring cleanups is fast way to memory leaks.
swfLoader.unloadAndStop(true);
Does remove the swf and the sound as well .
Works fine for me .
Even the documentation says :
Unloads an image or SWF file. After this method returns the source property will be null. This is only supported if the host Flash Player is version 10 or greater. If the host Flash Player is less than version 10, then this method will unload the content the same way as if source was set to null. This method attempts to unload SWF files by removing references to EventDispatcher, NetConnection, Timer, Sound, or Video objects of the child SWF file. As a result, the following occurs for the child SWF file and the child SWF file's display list:
Sounds are stopped.
Stage event listeners are removed.
Event listeners for enterFrame, frameConstructed, exitFrame, activate and deactivate are removed.
Timers are stopped.
Camera and Microphone instances are detached
Movie clips are stopped.

FLVPlayback clip loading delays

I'm building a narrative click-through kiosk app in Flash/AS3. Currently, there are several (10+) locally loaded .flv files that I'm loading into an FLVPlayback component on the timeline. I am experiencing loading delays and am wondering what the best practice / best case scenario for this case. These are all using the "Load external video with playback component" option for Video importing.
So far I've tried implementing it two ways:
One frame, one FLVPlayback playback on the stage named "video_player", and upon the click through / user action to switch the video, I do the following:
var new_flv:String = "next_flv.flv";
video_player.stop();
video_player.source("_flvs/"+new_flv);
video_player.seek(0);
video_player.play();
This results in delays anywhere from a few seconds to 10 seconds.
This is unconventional to me, but I used multiple frames on the timeline. Each frame had an FLVPlayback instance on the stage, each with a different relative path placed in the 'source' property in the component parameters (see http://www.ashleylovespizza.org/stuff/flv_example.png ). The code is switching between frames based on frame label and then hitting play (autoplay is off in the component parameters as well).
var new_flv_frame_name:String = "next_frame";
this.gotoAndStop(new_flv_frame_name);
this.video_player.play();
The issue, again, is that loading is taking a long time. What could prevent this behavior? One long flv that I seek() to different moments of time on the playhead? Can I preload in a separate FLVPlayback instance, similar to double buffering?
Any tips or best practices are appreciated.
Although you have not told me where the flv files are being loaded from (locally or remote), and as you have said you are building a kiosk style app, I am going to go out on a limb here and say that you should almost certainly use Adobe AIR for a kiosk app.
There is no reason for creating more than one FLVPlayback instance, its capable of playing multiple videos using getVideoPlayer(index), its up to you to manage the streams by calling close() on them.
If you are loading files remotely, then using Adobe AIR you can download each video to a local folder using the FileStream class. This will speed up the process of playing back these files.

How to get netstream bytesLoaded and bytesTotal from streaming .mp4?

I have a flex 3 app that uses netstream and a video object to stream .mp4 movies. I want to use the bytesLoaded and bytesTotal properties of the netstream to display the buffering information. I would also like to get any information about the number of frames that are dropped if possible.
When I've tested on .flv I'm able to get the information without a problem, but it doesn't seem to work on .mp4.
Is it possible to get this information streaming .mp4? Is there some configuration that I'm missing to make things work the same for .mp4 as .flv?
Thanks!
edit: I should also mention that the streaming is done over RTMP
I figured out that when using RTMP you can't get the byte information because the data isn't downloaded, it's purely streaming.
So instead I'm using the buffering info instead
Math.min(Math.round(ns.bufferLength/ns.bufferTime*100), 100);

AS3: How to dynamically load movieclip from library without exporting in frame 1?

I have some fairly large movieclips in the library which need to be dynamically loaded at runtime. I don't want to export them all in frame 1, because that would slow down initial loading of the movie.
I tried putting an instance of each of these clips later in the timeline where they wouldn't normally be encountered. When I then tried to load one from the library dynamically, I was able to successfully get an instance of the movieclip, but its currentFrame property was 0 and I couldn't see anything on the stage. As soon as I enabled "Export in frame 1", it worked properly.
Does this old trick of putting an instance on the timeline somewhere no longer work in AS3?
I have had similar issues with large library assets and to solve my issue I would always just put the assets into separate swf's and load the external swf file when I needed it.
Check out the Loader class 'content' property - http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/Loader.html#content
The only downfall to this is managing the assets in separate files.
I hope this helps.