Flash ActiveX: как загрузить фильм из памяти, ресурса или потока? - PullRequest
1 голос
/ 08 января 2009

Я встраиваю элемент управления Flash ActiveX в свое приложение C ++ (Flash.ocx, Flash10a.ocx и т. Д. В зависимости от вашей версии Flash).

Я могу загрузить SWF-файл, вызвав LoadMovie (0, имя файла), но файл должен физически находиться на диске. Как загрузить SWF из памяти (или ресурса, или потока)? Я уверен, что должен быть способ, потому что коммерческие решения, такие как функция f-in-box Загрузка флэш-фильмов из памяти напрямую также использует Flash ActiveX control.

Ответы [ 6 ]

2 голосов
/ 26 января 2009

Похоже, мне нужно будет предоставить детали для голосования "вверх" .. Хорошо.

Внутренний флэш-буфер при первом инициализации указывает, загружен ли фильм или содержит ли буфер в свойствах буфера первые четыре байта.

gUfU - фильм не загружен. свойства для подражания ....

fUfU - .. [4 байта] размер как целое число.

тогда несжатый фильм или SWF как бы. Напишите класс IStream. заполните выше. сохранить как szFile

TFlashStream *fStream = new TFlashStream(szFile);
// QI flash player

IPersistStreamInit * psStreamInit = 0;
shock->QueryInterface(::IID_IPersistStreamInit,  
                     (LPVOID*)&psStreamInit);
if(psStreamInit)
{
    psStreamInit->InitNew();
    psStreamInit->Load(fStream);
    psStreamInit->Release();
}
delete fStream;

Что следует отметить: Когда psStreamInit-> Load (fStream); вызовет IStream :: Read, ища заголовок 'fUfU'.

Если возвращение верное, psStreamInit вызывает IStream :: Read для размера буфера.

Если что-то пока выглядит хорошо, psStreamInit затем читает 1024-байтовые куски, пока чтение не будет исчерпано. Тем не мение. для заголовка и размера файла.

STDMETHOD(Read)(void *pv, ULONG cb, ULONG *pcbRead)

pcbRead недействителен. Вы можете использовать что-то вроде IsBadReadPtr

-

Michael

1 голос
/ 25 апреля 2010

Чтобы избавить вас от набора текста. У меня это работает таким образом (просто работает, не проверено):

void flash_load_memory(FlashWidget* w, void* data, ULONG size) {
        FlashMemoryStream fStream = FlashMemoryStream(data, size);
        IPersistStreamInit* psStreamInit = NULL;
        w->mFlashInterface->QueryInterface(IID_IPersistStreamInit,(LPVOID*) &psStreamInit);
        if(psStreamInit) {
            psStreamInit->InitNew();
            psStreamInit->Load((LPSTREAM)&fStream);
            psStreamInit->Release();
        }
    }

class FlashMemoryStream : IStream {
    public:
        FlashMemoryStream(void* data,ULONG size) {
            this->data = data;
            this->size = size;
            this->pos = 0;
        }

        HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID* ppv) {
            return E_NOTIMPL;
        }

        ULONG STDMETHODCALLTYPE AddRef() {  
            return E_NOTIMPL;
        }

        ULONG STDMETHODCALLTYPE Release() {  
            return E_NOTIMPL;
        }

        // IStream methods
        STDMETHOD(Read) (void *pv,ULONG cb,ULONG *pcbRead) {
            if(pos == 0 && cb == 4) {
                memcpy(pv,"fUfU",4);
                pos += 4;
                return S_OK;
            }
            else if(pos == 4 && cb == 4) {
                memcpy(pv,&size,4);
                size += 8;
                pos += 4;
                return S_OK;
            }
            else {
                if(pos + cb > size) cb = size - pos;
                if(cb == 0) return S_FALSE;
                memcpy(pv,(char*)data + pos - 8,cb);
                if(pcbRead) (*pcbRead) = cb;
                pos += cb;
                return S_OK;
            }
        }

        STDMETHOD(Write) (void const *pv,ULONG cb,ULONG *pcbWritten) { return E_NOTIMPL; }
        STDMETHOD(Seek) (LARGE_INTEGER dlibMove,DWORD dwOrigin,ULARGE_INTEGER *plibNewPosition) { return E_NOTIMPL; }
        STDMETHOD(SetSize) (ULARGE_INTEGER libNewSize) { return E_NOTIMPL; }
        STDMETHOD(CopyTo) (IStream *pstm,ULARGE_INTEGER cb,ULARGE_INTEGER *pcbRead,ULARGE_INTEGER *pcbWritten) { return E_NOTIMPL; }
        STDMETHOD(Commit) (DWORD grfCommitFlags) { return E_NOTIMPL; }
        STDMETHOD(Revert) (void) { return E_NOTIMPL; }
        STDMETHOD(LockRegion) (ULARGE_INTEGER libOffset,ULARGE_INTEGER cb,DWORD dwLockType) { return E_NOTIMPL; }
        STDMETHOD(UnlockRegion) (ULARGE_INTEGER libOffset,ULARGE_INTEGER cb,DWORD dwLockType) { return E_NOTIMPL; }
        STDMETHOD(Stat) (STATSTG *pstatstg,DWORD grfStatFlag) { return E_NOTIMPL; }
        STDMETHOD(Clone) (IStream **ppstm) { return E_NOTIMPL; }

        void* data;
        ULONG size;
        ULONG pos;
    };
0 голосов
/ 20 июня 2012

Образец MS VC ATL (собран с VS 2010 SP1 + Windows SDK 7.1 и протестирован в 64-разрядной версии Windows 7 SP1 с Flash64_11_3_300_257.ocx / Flash32_11_3_300_257.ocx и 32-разрядной в Windows XP SP3 с Flash32_11_3_300_257.ocx):

#pragma pack(push, 1)

typedef struct _FLASH_STREAM_HEADER
{
    DWORD m_dwSignature;
    DWORD m_dwDataSize;
} FLASH_STREAM_HEADER, *PFLASH_STREAM_HEADER;

#pragma pack(pop)

static HRESULT LoadFlashMovieFromResource(ATL::CComPtr<IShockwaveFlash>& spShockwaveFlash,
    UINT nResourceID, LPCTSTR pszResourceType = RT_RCDATA)
{
    HMODULE hModule = ATL::_AtlBaseModule.GetModuleInstance();
    ATLASSUME(hModule != NULL);

    //HINSTANCE hResourceInstance = ATL::AtlFindResourceInstance(nResourceID, pszResourceType);
    //HRSRC hResource = ::FindResource(hResourceInstance, MAKEINTRESOURCE(nResourceID),
    //  pszResourceType);

    HRSRC hResource = ::FindResource(hModule, MAKEINTRESOURCE(nResourceID), pszResourceType);

    if (hResource == NULL)
        return HRESULT_FROM_WIN32(::GetLastError());

    DWORD dwResourceDataSize = ::SizeofResource(hModule, hResource);

    if (dwResourceDataSize == 0)
        return HRESULT_FROM_WIN32(::GetLastError());

    HGLOBAL hResourceLoaded = ::LoadResource(hModule, hResource);

    if (hResourceLoaded == NULL)
        return HRESULT_FROM_WIN32(::GetLastError());

    ATL::CComPtr<IStream> spStream;

    HRESULT hResult = ::CreateStreamOnHGlobal(NULL, TRUE, &spStream);

    if (FAILED(hResult))
        return hResult;

    FLASH_STREAM_HEADER fsh = {0x55665566, dwResourceDataSize};

    ULARGE_INTEGER uli = {sizeof (fsh) + dwResourceDataSize};

    hResult = spStream->SetSize(uli);

    if (FAILED(hResult))
        return hResult;

    hResult = spStream->Write(&fsh, sizeof (fsh), NULL);

    if (FAILED(hResult))
        return hResult;

    hResult = spStream->Write(reinterpret_cast<void*>(hResourceLoaded), dwResourceDataSize, NULL);

    if (FAILED(hResult))
        return hResult;

    uli.QuadPart = 0;

    hResult = spStream->Seek(*reinterpret_cast<PLARGE_INTEGER>(&uli), STREAM_SEEK_SET, NULL);

    if (FAILED(hResult))
        return hResult;

    ATL::CComPtr<IPersistStreamInit> spPersistStreamInit;

    hResult = spShockwaveFlash.QueryInterface(&spPersistStreamInit);

    if (SUCCEEDED(hResult))
        hResult = spPersistStreamInit->Load(spStream);

    return hResult;
}
0 голосов
/ 30 августа 2009

Этот метод не работает, когда вы пытаетесь загрузить фильм через MovieclipLoader или LoadMovie из другого фильма !!!

Результатом является замена вызывающего SWF-файла !! ... так что этот метод работает только для загрузки базового файла.

Кто-нибудь знает лучший метод, который работает также с MovieClipLoader и LoadMovie? Спасибо.

0 голосов
/ 21 января 2009

в дополнение .... Флеш-плеер продвигает IPersistStorage. flash.QI IPersistStorage pStorage.load (mystorage_as_stream)

.. в теории.

Извините за вышесказанное. Флеш-плеер продвигает IPersistStreamInit. flash.QI IPersistStreamInit pStream.load (my_stream)

Michael

0 голосов
/ 08 января 2009

Будучи флеш-парнем, я не знаю каких-либо подробностей на стороне C ++, но если вы сделали запрос на стороне Flash о поддельном протоколе, на стороне C вы можете перехватить этот запрос и ответить на него потоком данных. ? Я имею в виду что-то вроде:

var mc:MovieClip = createEmptyMovieClip( "mc", 0 );
mc.loadMovie( "fakeprotocol://"+filename )

Пока ответ выглядит (для Flash) как поток HTTP, это должно работать. (Заранее извиняюсь, если «перехватить запрос и вернуть поток данных» - это та часть, с которой вы обращаетесь за помощью.)

...