dcsimg
A Flash Developer Resource Site

Results 1 to 10 of 10

Thread: Converting video to bitmapdata sequence woes

  1. #1
    Junior Member
    Join Date
    Oct 2009
    Location
    UK
    Posts
    13

    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 ****?

  2. #2
    Senior Member
    Join Date
    Nov 2001
    Posts
    1,145
    The capturing flv (or any) video is a complex issue. You have to understand that you'll have to learn a lot of code and other complex stuff.

    You can set up an swf to do screen capture but it's a big optimization issue - weak computers won't do it well, lots of storage issues - you don't have access to the person's computer to save anything so you'll be uploading huge amounts.

    You should look at Adobe server software. You can probably get flv converted to screens on the server. I know you can if it's mp4.

    crossdomain.xml is for the xml only. Basically, you can't put an swf on domainA.com that loads an xml from domainB.com (security issue) unless there's a crossdomain.xml that says it's ok for other domains to consume my xml files.

    Security.loadPolicyFile("url to server crossdomain.xml"); This is to load a crossdomain.xml. You have it loading ""url to server crossdomain.xml" Is that file there?
    Last edited by moot; 04-11-2014 at 03:48 PM.

  3. #3
    Tim (Super Moderator) Northcode's Avatar
    Join Date
    Dec 2000
    Location
    Whitehorse YT
    Posts
    3,766
    You can also use FFMPEG to convert a video to a sequence of bitmap images. Would that help? It will generate a lot of images but you could pre-convert all the videos to JPG sequences and when asked to load the video as frames, you could load the JPG images. I have quite a bit of experience working with FFMPEG (the library and the command line tool) if you want to bounce any ideas off me.
    When your swf2exe tool just HAS to work
    there's only one choice... SWF Studio

  4. #4
    Junior Member
    Join Date
    Oct 2009
    Location
    UK
    Posts
    13
    Quote Originally Posted by moot View Post
    The capturing flv (or any) video is a complex issue. You have to understand that you'll have to learn a lot of code and other complex stuff.

    You can set up an swf to do screen capture but it's a big optimization issue - weak computers won't do it well, lots of storage issues - you don't have access to the person's computer to save anything so you'll be uploading huge amounts.

    You should look at Adobe server software. You can probably get flv converted to screens on the server. I know you can if it's mp4.

    crossdomain.xml is for the xml only. Basically, you can't put an swf on domainA.com that loads an xml from domainB.com (security issue) unless there's a crossdomain.xml that says it's ok for other domains to consume my xml files.

    Security.loadPolicyFile("url to server crossdomain.xml"); This is to load a crossdomain.xml. You have it loading ""url to server crossdomain.xml" Is that file there?
    Could you explain Adobe Media Server to me? I really don't understand what it's for, and if it's at all useful to my situation.

    I have a working crossdomain xml on my server, I just didnt want to post the url so I replaced it with "url to server crossdomain.xml". It's been tested and used a lot and I know it's working properly.

    Quote Originally Posted by Northcode View Post
    You can also use FFMPEG to convert a video to a sequence of bitmap images. Would that help? It will generate a lot of images but you could pre-convert all the videos to JPG sequences and when asked to load the video as frames, you could load the JPG images. I have quite a bit of experience working with FFMPEG (the library and the command line tool) if you want to bounce any ideas off me.
    I've considered this but it would make a really huge filesize for a single video.
    I should mention this is a going towards a game I would like to market, so it needs to be loaded by many individuals regularly. To cut down on server costs I need to keep these files fairly small. FLV does this for, jpeg sequences don't unfortunately.

  5. #5
    Senior Member
    Join Date
    Nov 2001
    Posts
    1,145
    I don't know much about backend softwares but I know that what you want to do is done often. Most often, it's just one capture used for thumbs. All video players have thumbs, many use regularly captured thumbs for their scrolling. The user uploads their video and their video is processed into multiple speeds and thumbnails.

    This is a complicated application. You're dealing with video, gpu processing power, huge filesizes, image sizes, image optimization, etc. Be sure to check your hosting on this.

    You can use Air (so you have access to store files on user's computer) to do the screen capturing. The user can load their video, do the capturing, and manage the captured files all clientside before uploading. Just be sure to keep eye on user's cpu, if your app is loading it, stop it. You can crash a weak user's computer all the way to blue screen in a heartbeat doing stuff like this.

  6. #6
    Mod cancerinform's Avatar
    Join Date
    Mar 2002
    Location
    press the picture...
    Posts
    13,448
    Everything can be done in Flash. I made an application, where a video is analyzed. Check lesson 6 "Video analysis". You need to use a timer and take Bitmaps of the Video as if you draw a new Bitmap from an image.
    http://www.flashscript.biz/AIR/image...o/Lessons.html
    - The right of the People to create Flash movies shall not be infringed. -
    | www.Flashscript.biz | Flashscript Biz Classes/Components |

  7. #7
    Junior Member
    Join Date
    Oct 2009
    Location
    UK
    Posts
    13
    I'm happy to report that I found the solution to my problem a few days ago
    I found a useful binary called hxswfml (essentially SWFMill but written in Haxe and primarily for AS3).
    There's no documentation about this, but by looking at the examples I saw you could define an FLV as a sprite like so:

    input.xml:

    <swf width="100" height="100" fps="1" version="10" compressed="true" frameCount="1" >
    <FileAttributes actionscript3="true" useNetwork="true" />
    <DefineSprite id="?" file="path/to/file/video.flv" />
    <DefineABC file="path/to/file/compiledDocumentClass.swf" isBoot="true" />
    </swf>

    compiledDocumentClass.swf consisted of a compiled .as containing:

    [SWF(backgroundColor = "#FFFFFF", width = "100", height = "100", frameRate = "30")]
    public class ImageRoot extends MovieClip
    {
    public function ImageRoot()
    {
    if (Security.sandboxType != Security.APPLICATION) {
    Security.allowDomain("*");
    Security.allowInsecureDomain("*");
    }
    }
    }

    Then you just run:
    hxswfml xml2swf input.xml output.swf

    All I had to do was change the path of the video in the xml between each compile.
    Now all I have to do is double click a batch file and within a minute it's compiled 100 security error free swfs!

    When I first tried this method it didn't work, but then I changed the useNetwork attribute to "true" and that did the trick! (it might be that my earlier methods which used embed tags might have worked if I made sure -useNetwork=true in the compiler arguments, but this method is faster so I didn't bother to check)

    Needless to say I was elated when I finally got this **** working. I was just about ready to give up, so this came as a great relief.

    I hope this helps someone with a similar problem. Videos in flash are just an absolute nightmare, but at least I've found a way to work with the FLV kind...

  8. #8
    Senior Member
    Join Date
    Nov 2001
    Posts
    1,145
    Won't you have cpu/ram issues trying to capture 1080p or 4k videos that are over a couple minutes on a regular computer (non gaming gpu)?

  9. #9
    Junior Member
    Join Date
    Oct 2009
    Location
    UK
    Posts
    13
    Lucky for me they're only about 80 frames long.

  10. #10
    Senior Member
    Join Date
    Nov 2001
    Posts
    1,145
    Yeah, I wasn't arguing, I was asking. I take some screens of a normal video and I'm seeing huge numbers.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center