Экспорт фрейма из внешнего SWF в Javascript - PullRequest
3 голосов
/ 11 августа 2011

Я пытаюсь захватить неподвижный кадр из (любого) внешнего SWF-файла, используя свой собственный флэш-фильм в качестве прокси-сервера, чтобы загрузить его и передать информацию о рабочей области в javascript.Я хочу, чтобы он был как можно более совместимым, поэтому я остановился на AS2 / Flash 8.

Скрипт отлично работает в отладчике Flash, т.е.

trace(flash2canvasScreenshot.getPixel(w, h).toString(16));

возвращаетправильный цвет пикселя, где:

ExternalInterface.call("sendToJS",flash2canvasScreenshot.getPixel(w, h).toString(16));

в опубликованном фильме - нет.

Этот метод, очевидно, может быть довольно медленным для фильмов с большой флэш-памятью (по размерам), поскольку он повторяет каждыйодин пиксель.Если кто-то имеет в виду какие-то более совершенные методы, не стесняйтесь делиться, но, как уже было сказано, проблема, с которой я сталкиваюсь, заключается в том, что я получаю дифференцированные результаты при отладке и публикации, при этом информация о пикселях не извлекается при публикации.

import flash.display.BitmapData;
import flash.external.*;

var myLoader:MovieClipLoader = new MovieClipLoader();
var mclListener:Object = new Object();

mclListener.onLoadInit = function(target_mc:MovieClip)
{

        var stageW = Stage.width;
        var flash2canvasScreenshot:BitmapData = new BitmapData(stageW, Stage.height, false, 0x00000000);
        var pixels:Array = new Array();
        flash2canvasScreenshot.draw(element);

        for (w = 0; w <= stageW; w++)
        {
            trace(flash2canvasScreenshot.getPixel(w, h).toString(16)); // this gives correct color value for the pixels in the debugger
            ExternalInterface.call("sendToJS",flash2canvasScreenshot.getPixel(w, h).toString(16)); // this just returns the bitmap default color, 0 in this case.
            /*
            for (h = 0; h <= Stage.height; h++)
            {
                var pixel = flash2canvasScreenshot.getPixel(w, h).toString(16);
                pixels.push(pixel);
            }
            */
        }

        //ExternalInterface.call("sendToJS",pixels.toString());*/



};


myLoader.addListener(mclListener);

myLoader.loadClip("http://i.cdn.turner.com/cnn/cnnintl_adspaces/2.0/creatives/2010/6/9/21017300x250-03.swf", 0);
//myLoader.loadClip("https://s.ytimg.com/yt/swfbin/watch_as3-vflJjAza6.swf", 0);

//myLoader.loadClip(_level0.flash2canvasurl, _root.mc);

Ответы [ 2 ]

10 голосов
/ 15 августа 2011

Есть немного проблем с размещенным вами фрагментом:

  1. , как тот, о котором упоминал Джои, но с моей точки зрения выделяется переменная element, которая не определенав любом месте, так что это либо тип o, либо вы пытаетесь нарисовать объект undefined.
  2. Вы рисуете, как только загрузка заканчивается, но загружаемая анимация может начатьсячуть позже.Возможно, сделайте снимок немного после завершения загрузки.
  3. Не обращались к as2 в течение некоторого времени и не помните, как обрабатывается проблема безопасности, но если вы swf загружаете другой swf из другогодомен, то домен, на котором находится загружаемый SWF-файл, также должен иметь файл политики crossdomain.xml, позволяющий получить доступ к содержимому загруженного SWF-файла.Если вы просто загрузите и отобразите swf из другого домена, это нормально.Однако, если вы пытаетесь нарисовать SWF-файл с помощью BitmapData, вы фактически пытаетесь получить доступ к пиксельным данным из содержимого этого SWF-файла, поэтому вам потребуются разрешения.Если у вас нет контроля над файлом междоменной политики, вам может потребоваться использовать серверный сценарий для копирования / прокси-файла в домен, который может предоставить доступ к загруженному SWF-файлу.

Вот упрощенныйверсия вашего сниппета, которая работает (без части внешнего интерфейса / значения пикселей):

var myLoader:MovieClipLoader = new MovieClipLoader();
var mclListener:Object = new Object();
mclListener.onLoadInit = function(target_mc:MovieClip)
{
    var pixels:Array = new Array();
    setTimeout(takeSnapshot,2000,target_mc);
}

myLoader.addListener(mclListener);
myLoader.loadClip("http://www.bbc.co.uk/science/humanbody/sleep/sheep/reaction_version5.swf",1);
//myLoader.loadClip("http://i.cdn.turner.com/cnn/cnnintl_adspaces/2.0/creatives/2010/6/9/21017300x250-03.swf", 1);
//myLoader.loadClip("https://s.ytimg.com/yt/swfbin/watch_as3-vflJjAza6.swf", 0);

function takeSnapshot(target:MovieClip):Void {
    var flash2canvasScreenshot:BitmapData = new BitmapData(150, 150, false, 0x00000000);//tiny sample
    flash2canvasScreenshot.draw(target);
    _level1._alpha = 20;//fade the loaded content
    _level0.attachBitmap(flash2canvasScreenshot,0);//show the snapshop. sorry about using _root
}

Вот краткий предварительный просмотр снимка 150x150: preview

Вот фрагмент as3 дляпроиллюстрировать проблему обработки изолированной программной среды безопасности:

var swf:Loader = new Loader();
swf.contentLoaderInfo.addEventListener(Event.COMPLETE,loaderComplete);
swf.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR,loaderSecurityError);
swf.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,loaderIOError);
swf.load(new URLRequest("http://i.cdn.turner.com/cnn/cnnintl_adspaces/2.0/creatives/2010/6/9/21017300x250-03.swf"),new LoaderContext(true));

function loaderComplete(event:Event):void{
    setTimeout(takeSWFSnapshot,2000);
}
function loaderSecurityError(event:SecurityErrorEvent):void {
    trace('caught security error',event.errorID,event.text);
}
function loaderIOError(event:IOErrorEvent):void{
    trace('caught I/O error',event.errorID,event.text,'\tattempting to load\t',swf.contentLoaderInfo.url);
}
function takeSWFSnapshot():void{
    var clone:BitmapData = new BitmapData(swf.content.width,swf.content.height,false,0);
    try{
        clone.draw(swf.content);
    }catch(e:SecurityError){
        trace(e.name,e.message,e.getStackTrace());
    }
    addChild(new Bitmap(clone));
}

HTH

2 голосов
/ 20 августа 2011

Мой подход к этому был бы:

-Используйте AS3 по той причине, что Лукеванин прокомментировал:

Просто помните, что AS3 может загрузить AS2 SWF, но AS2 SWF не может загрузить AS3 SWF, так что вы на самом деле добиться большей совместимости (с вашим содержание), если вы публикуете AS3

-Используйте прокси-файл для извлечения файла SWF, чтобы обойти проблемы нарушения песочницы (хотя, если SWF-файл загружает внешние ресурсы и использует относительные пути, он может быть немного сложнее)

-Снимок кадра (см. Решение Джорджа Профенца)

-Кодировать изображение с помощью base64 и отправить его ** в метод JS , а затем декодировать, чтобы получить изображение.

** Я почти уверен, что нет ограничений по размеру ...

...