Pre-Load Multiple Videos in Flash? In Flex? - apache-flex

I'm doing a project where we play multiple videos back to back, and if we load them the normal way by providing a stream url, there is a load delay each time we start the next video.
I've looked through Adobe's docs for both Flash and Flex, and I can't find a way to pre-load the videos. Embedding them is not workable in this application. Ideally we would pre-load them, display a progress bar or other short video in the meanwhile, and only start the video playback when all the videos have loaded.
I'm not used to asking questions of others for programming, I RTFM, but I find the Adobe docs to be lacking, and googling flash/flex problems is tough. There's a lot to sift through, and I can't find the relevant technique/solution.
As to Flex/Flash I'm interested in the solution for either, or both. Perhaps it is the same, as it is actionscript?

This should be very straightforward. For straight flash, use either fl.video.VideoPlayer or fl.video.FLVPlayback. Create multiple players, one per video, calling load() on each with the url to your source video. Then listen for VideoProgressEvent.PROGRESS events to find out when the video is loaded. Finally, you can attach the videos in succession to a visual component and call play() to play them.
Example code(not tested):
var video1:VideoPlayer = new VideoPlayer();
video1.load("http://example.com/video1.flv");
video.addEventListener(VideoProgressEvent.PROGRESS,
function(e:VideoProgressEvent):void
{
if (e.bytesLoaded == e.bytesTotal)
{
trace("video1 loaded.");
parent.addChild(video1);
video1.play();
}
}
var video2:VideoPlayer = new VideoPlayer();
video2.load("http://example.com/video1.flv");
video.addEventListener(VideoProgressEvent.PROGRESS,
function(e:VideoProgressEvent):void
{
if (e.bytesLoaded == e.bytesTotal)
{
trace("video2 loaded.");
}
}

You could try looking at the bulk-loader project and see if it might be useful for this.
An excerpt from the front page:
"BulkLoader is a minimal library written in Actionscript 3 (AS3) that
aims to make loading and managing
complex loading requirements easier
and faster. BulkLoader takes a more
dynamic, less architecture heavy
aproach [sic]. Few imports and making heavy
use of AS3's dynamic capabilities,
BulkLoader has a one-liner feel that
doesn't get in your way."

Related

Directshow advice for range of functionality or is there a better alternative (.NET)?

I've been doing some work in VB.Net with Directshow over the past 3-4 weeks. I'm creating an application to keep tags on a video and eventually want to be able to extract the tagged parts of the video to a new file. In a video that is 2 hours long I might want to extract say 50 10-15 second "clips" up to 15 times (event tagging). This will be for a free application.
I've found it brilliant (and easy) to render / seek / play clips, etc on XP-Win7 with no issues. I've "discovered" the joys of GraphEdit, creating graphs, the issues with COM in VB.NET, GMFBridge, ....etc.
Now I need some advice. Am I using the right technology. Directshow seems to be very resistant to the idea of "open video", "seek to clip", "write clip to file", .....repeat for all clips, close file. I can sort of do this already if I visibly render the video but would need to do it as a background task faster than realtime render speed.
Things that seem to be missing are:
- an example of anyone doing anything similar (export multiple clips to a single file)
- no easily available 64bit compressors (lots of 32bit stuff around)
- all the references and examples I do find are VERY old
- VB.NET is not the first "port of call" for DirectShow developers
So, the question is, should I be using something else?
If not, has anyone done anything similar before. I'm not looking for their code, I just want some guidelines as it takes ages to figure things out in DirectShow and VB.Net just using trial & error (and Google).
I've looked at AFORGE (no sound), FFMPEG (command line toolset), Media Foundation (reluctant to throw away XP) and a variety of commercial helper libraries but not really getting any further.
Apologies for the length but I wanted readers to understand the background.
All help appreciated.
To output clips to a single file Microsoft had created the "DirectShow Editing Services". Sometimes it works, sometimes not. We use it in our software to create videos from clips like you. With a little bit work you can also include effects to the video.
It is also possible to use AviSynth. It's a scripting system and frameserver for DirectShow.
As I know, with MediaFoundation you can also create a video from multiple clips, but I never tried this.

Concatenate Multiple media files into one output/listening to Media Foundation Events

I've written an application that will transcode and manipulate media files using Microsoft Media Foundation, but now I've got to make the same application concatenate/join media files together.
Is there any existing documentation on doing something like this? Any pointers/hints? Any existing code that does this?
If not, I figure I've got to write or find a custom media source-something like a ConcatenatingMediaSource(a source that wraps the series of sources it's concatenating together), but I'm unsure if this is the best course to accomplish this.
EDIT:
It seems the relevant event I need to be concerned with are MEEndOfPresentation-this indicates that a source(or perhaps one of my embedded sources) has reached the end of all it's streams.
MSDN docs state that if a wrapped source fires this event, I have the ability set a new PresentationDescriptor on my Source. Perhaps I could just return the next embedded source's PresentationDescriptor?
Right now I'm held up on how to actually listen to an individual source's events. How to do this isn't exactly clear (at least to someone who mostly writes code for the JVM).
EDIT:
I think I want to use a SequenceSource; it's part of the API but seems fairly undocumented.

Providing raw MP3/AAC data to Flex/Flash from a custom container

Having had a quick look at the Flex docs I can't seem to find any reference to providing audio content to be played from a custom (possibly encrypted - don't worry, it's not that evil) container format. Is this possible and if so, could someone point me in the right direction.
Or if that's not possible, some way to hook into the disk/network (disk is much more important in this case) I/O of the sound playing mechanism to provide a supported container in memory from a custom wrapper.
Since Flash Player 10, it's posible to write PCM / raw audio data to a Sound Object.
Basically, you call play on an "empty" Sound Object and it will start dispatching periodically a SampleDataEvent, requesting data. You then can write to the audio stream through the data ByteArray exposed by the event object.
http://help.adobe.com/en_US/FlashPlatform//reference/actionscript/3/flash/events/SampleDataEvent.html?filter_flex=4
http://www.adobe.com/devnet/flash/articles/dynamic_sound_generation/index.html
Also, if you're interested in good articles and reference for audio programming in Actionscript, you might want to check out Andre Michelle's stuf:
http://blog.andre-michelle.com/
http://lab.andre-michelle.com/
A flash.media.Sound must either be:
constructed/loaded with a URLRequest,
inherit its data through embedding
There currently is no provision for directly piping mp3 (or aac, or video) data to a any "media" object, such as Sound. You can only get the Sound object to download the data for itself. There are people who are upset about this, including myself; you are not alone!
I say "at this stage" because it's not unthinkable that Adobe will update the API to make this possible in a future version. For the now, you're best to go with the decoding-to-a-dynamic-sound workaround mentioned by Juan, if you really need to be able to do this.
And post a feature request at Adobe's bug tracker, or vote on an existing one!

Delay before playing embedded mp3 in Actionscript / Flex 3

I am embedding an mp3 into my Flex project for use as a sound effect, but I am finding that every time I play it, there is a delay of about half a second from when I call .play() to when you can hear the sound. This makes it weird because I want the sound effects to sync to game events. My mp3 itself is only about a fifth of a second long so it isn't because of the contents of the mp3.
I'm embedding with
[Embed(source="assets/Tock.mp3")]
[Bindable]
public static var TockSound:Class;
public var tock_sound:SoundAsset;
and then playing with
if (tock_sound == null) {
tock_sound = new TockSound() as SoundAsset;
}
Alert.show("tock");
tock_sound.play();
I know there's a delay because the sound plays about a half second after the Alert displays. I did consider that maybe it was the initial loading time of constructing the TockSound, but the delay is there on all the subsequent calls as well.
How can I avoid this delay on playing a sound?
Update: It turns out this delay is only present when playing the swf on Linux. I believe it is a Linux-specific flaw in Adobe's flash player.
Not sure about the reason, other than Flash always has had some bad audio latency issues. Read Tinic's blog to stay on top of this stuff: http://www.kaourantin.net/
One thing that might help: make sure your MP3 is 44.1kHz or else Flash will need to resample it.
You can actually embed a WAV file, it just takes work. You embed it as a byte array, and in FP9, dynamically construct a SWF file on the fly. Pretty horrible, but doable. :-) In FP10, you can use the dynamic sound API, so it's easy.
Try StandingWave
http://code.google.com/p/standingwave/
It has the ability to "cache" the sound before playing getting rid of those delays and clicks you normally hear
I haven't worked with audio in Flash too much but it sounds like the half second delay might be the Flash Player opening up the file and reading it into memory. You could try doing a play() and a stop() when you load the application. That might push it into memory.
The other option is using the StandingWave library which was built by the guys at Noteflight. You can get some additional control over the audio files with that library and hopefully it'll help your delay problem.
The problem is that all MP3s have a random amount of blank time at the beginning of the file that is put there during the compression process. Modern software jukeboxes(itunes, songbird etc...) compensate for this by scanning the file before its played and determining the songs actual starting point. Your best bet for sound effects is to use .wav files as their format allows for instant playback, but with a filesize hit.
you might also try: http://www.mptrim.com/ <- they claim to be able to trim the space off the mp3.

Flex: Testing UI components at the click level?

I've been working on a Flex component and I'd like to write some automated tests for it. The trouble is, the UI testing tools I've looked at (FlexMonkey and Selenium Flex API) don't simulate "enough":
Most of the bugs which have come up so far relate to the way Flex deals with dragging and dropping, which these libraries can't simulate accurately enough. For example, I need to test a case where there is a "drop" event which occurs in the bottom half of a component – neither FlexMonkey nor Selenium Flex API can do that (they may simulate a mouse event, but they won't include coordinates).
So, is there any "good" way to automate that sort of testing?
Edit: After much research, it looks like the only piece of software that can do this is iMacros, which is Windows-only and the interface is... Lacking. So I'm going to be writing my own. Basically, it will put an HTTP interface on java.awt.Robot so code (in any language) can simulate mouse/keyboard events. If you're interested, PM me and I'll keep you updated.
Edit 2: I have published the first version of the framework I wrote, Blunderbuss, over at BitBucket: http://bitbucket.org/wolever/blunderbuss/ . You'll need Jython to run it (http://www.jython.org/), but after that the flex-client example should work.
Videos of Blunderbuss live over at Vimeo:
Automating Flex testing with Blunderbuss
Blunderbuss test suite running
At the moment this remains a proof-of-concept, as I haven't had the cycles to clean it up and make it more useable… But maybe enough people bothering me would give me that time :)
I've used Eggplant to test Flash and AIR apps without having to add any hooks into the code. It's a great tool but it's quite expensive. It simulates a real user by VNC-ing into a system and uses image recognition - among other things - to interact with the app.
I am definitely interested in your custom Java class, and (though I am not the best at Java (yet...)), I would be willing to help out if you're thinking of making this collaborative.
As to Flash MouseEvents. Unfortunately, there really isn't an accurate way to simulate the drag/drop experience in Flash. MouseEvents, when generated by the mouse, are handled in a very different way than regular events and while you could simulate actions by passing events into the handling functions, or by making the dispatcher fire a new DragEvent( DragEvent.DRAG_DROP..., it will not be the same as having the user interact with it. And for some functionality (like gaining access to the clipboard), nothing inside Flash will accomplish your goals.
To be honest, you're probably headed in the right direction -- using something which is not written in Flash to drive faked mouse events is probably your best bet.
I've never had to use it in Flex but i recently stumbled across some info on automation packages in the MS Surface SDK... after looking into it those classes automated user behavior which can be used for testing i.e. move a fake mouse to this point, perform this action. As you're using Flex mx.automation packages and classes. My guess (and hope) is that you'd be able to achieve what you want using these classes.
You could also try auto-hotkey - it is similarly a macro-editing program but it has proven to be very efficient and you can write scripts and set it up very easily.

Resources