Converting video to bitmapdata sequence woes
I have been struggling with a problem for a few days now. I feel like I've exhausted every possible means of achieveing my goal.
This is going to be long. I apologize.
Here's what I want:
I have 50-80 FLV videos (the total for the end product is undecided) that are on an external server. I want my application (when requested) to download an FLV, go through it frame by frame and convert each frame into a bitmapdata.
The result I need is exactly this, it is set in stone and vital for my project.
My first method was as follows:
I used netstream.appendBytes with my FLV bytearray but the problem with this is that believe it or not, it is IMPOSSIBLE to step through an FLV frame by frame. The best I can do is draw the video object to a bitmapdata every frame at the enterFrame framerate. The problem with this is that for large videos (1920 x 1080 for example) it will almost certainly take longer than 1/30th of a second, so the next frame might be missed. In testing this I was unhappy with the results and also found that it used more ram than it needed (frames would often get recorded twice).
In summation, this method was very messy and not at all elegant, especially considering that all I need is a step function that actually works! (netstream has a step() function but ONLY for content on Aodbe Media Server for some bizarre reason)
My next method was this:
Using Flash, I tried embedding an FLV in the timeline and exported it as an SWF. This worked just fine. I can step through it precisely and at my own pace - perfect... but unforunately I have to then repeat that process 50-80 times with each FLV, and also note that these videos are likely to change every now and then when the product is finished.
I tried to automate the process with a jsfl, but - as if Adobe were purposely trying to make it harder on me - that was impossible. You'll notice you get a wizard style window when you import an FLV into Flash, which is not possible to control with jsfl.
So I went searching for another solution.
Another method:
I found that I could convert FLVs to SWF with FFMPEG, so then I wrote a batch file (later converted to python because of my unfamiliarity of windows batch code) which did this automatically for me and considerably quicker than the last method (around 10 seconds to do 20 FLVs).
Then I uploaded them to the server and gave it a try.
Despite having a fully working crossdomain that allowed everything else, I was getting a security error whenever I tried to access the Loader.content.
Then I remembered, swf communication needs Security.allowDomain()............. which is impossible to do with FFMPEG
I was really REALLY starting to lose my patience by this point.
THE NEXT F**KING METHOD:
I now had 50 swfs which couldn't do **** but spew errors at me. I figured all I want to do is give them a document class with Security.allowDomain("*"), but how exactly do I go about doing that?
So I wrote this class:
Code:
package
{
import flash.display.Sprite;
import flash.system.Security;
import flash.text.TextField;
[SWF(backgroundColor = "#FFFFFF", width = "100", height = "100", frameRate = "30")]
public class test extends Sprite
{
[Embed(source="EXAMPLE.swf")]
static private const DATA:Class;
public function test()
{
Security.allowDomain("*");
addChild(new DATA());
}
}
}
(EXAMPLE.swf is a converted FLV from FFMPEG.)
Right. So I compile this with mxmlc.exe like so:
mxmlc test.as -static-link-runtime-shared-libraries=true
I upload the outputted test.swf to my server.
I then wrote the following code :
Code:
...
Security.loadPolicyFile("url to server crossdomain.xml");
var context : LoaderContext = new LoaderContext();
context.allowCodeImport = true;
context.checkPolicyFile = true
var loader:Loader = new Loader ();
loader.load(new URLRequest("url to my swf"), context);
...
Followed by a listener to grab the content and all that stuff that goes without saying.
But guess what... It didn't work. Again.
I get the incredibly helpful error of: SecurityError: Error #2121: Security sandbox violation: BitmapData.draw: <local path to swf> cannot access <url to swf> FORWARD SLASH / DYNAMIC / 1. This may be worked around by calling Security.allowDomain.
Let me repeat that - it told me "This may be worked around by calling Security.allowDomain"
I ALREADY DID THAT YOU IDIOT!
Finally, I tried the same thing but this time embedded the SWF as a bytearray in the document class above, and then using a loader with loadBytes. However - Same. Bloody. Result.
And then I wrote this as I can't think of any other way of converting these videos into bitmapdatas accurately.
I really don't want to do the first method, it's too innacurate.
The second method is a load of arse, even though it works. It takes a few minutes for each FLV (setting the framerate, doc class) and is prone to me making a mistake.
The method needs to be done in batch. When the product is finished and SWFs need to be changed, it needs to be quick and easy as it probably wont be me updating them and I don't wnat the hastle anyway. A simple batch / executable does the trick.
Obviously this would be a piece of piss if netstream worked (why doesn't it work?), or if the security functions applied to embedded SWFs (why don't they?)
I'm not expecting much help as I already have 2 ****ty solutions but neither of which I'm at all happy with.
Surely though there must be some way of converting an FLV to a perfect sequence of bitmapdatas. No missing frames, and will run the same on differently specced computers (currently if I run the first solution on a really slow computer it would only grab a fraction of the frames before the video ended)
Perhaps there is a SWF setting that will do the equivalent of Security.allowDomain("*")?
Any help would be nice. There has to be a solution in here somewhere.
...And I'm sorry to repeat myself but I just can't get over this point - why is netstream.step() such a deceitful piece of ****?