Video aus dem Speicher abspielen



  • Sounds abspielen ist AFAIK in den FAQ beschrieben...
    Ich poste einfach mal ein Sample für Video das ich irgendwo mal gefunden habe. Ist aber nicht der beste Code. Hab auch keine Ahnung wer den geschrieben hat:

    // mplayerwnd.h : header file
    //
    #if !defined(MPLAYERWND_H_INCLUDED)
    #define MPLAYERWND_H_INCLUDED
    
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    
    #include <mmsystem.h>
    
    // Definitionen
    #define MPW_PLAY   10
    #define MPW_HOME   11
    #define MPW_END    12
    #define MPW_STEP   13
    #define MPW_RSTEP  14
    #define MPW_RPLAY  15
    
    /////////////////////////////////////////////////////////////////////////////
    // CMediaPlayerWnd window
    
    class CMediaPlayerWnd : public CWnd
    {
    // Construction
    public:
        CMediaPlayerWnd();
    
    // Overrides
        // ClassWizard generated virtual function overrides
        //{{AFX_VIRTUAL(CMediaPlayerWndo)
        public:
        virtual void OnFinalRelease();
        //}}AFX_VIRTUAL
    
    // Implementation
    public:
        void CenterMediaPlayerWnd(HWND);
        void Open(HWND hWnd, LPCTSTR szFilter);
        void Open(LPSTR sVPath, HWND hWnd);
        void Close(HWND);
        void Play(HWND, int);
        void Seek(HWND, int);
        void Step(HWND, int);
        virtual ~CMediaPlayerWnd();
    
    protected:
        MCIERROR GetLastError() const;
        MCIDEVICEID m_wDeviceID, m_mciDeviceID;
        HWND m_hwnd;
        BOOL m_bPlaying, m_bOpened;
    
    private:
        MCIERROR m_dwLastError;
        BOOL m_bReportErrors;
    
        // Generated message map functions
    protected:
        //{{AFX_MSG(CMediaPlayerWnd)
            // NOTE - the ClassWizard will add and remove member functions here.
        //}}AFX_MSG
        DECLARE_MESSAGE_MAP()
        // Generated OLE dispatch map functions
        //{{AFX_DISPATCH(CMediaPlayerWnd)
            // NOTE - the ClassWizard will add and remove member functions here.
        //}}AFX_DISPATCH
        DECLARE_DISPATCH_MAP()
        afx_msg LONG OnMciNotify(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
        DECLARE_INTERFACE_MAP()
    };
    
    /////////////////////////////////////////////////////////////////////////////
    
    //{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
    
    #endif // !defined(MPLAYERWND_H_INCLUDED)
    
    // mplayerwnd.cpp : implementation file
    // Fensterklasse zum Abspielen von Mediadateien
    // winmm.lib muss mitkompiliert werden...
    //
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
    
    #include "stdafx.h"
    #include "mplayerwnd.h"
    #include <digitalv.h>     
    
    //////////////////////////////////////////////////////////////////////////
    // CMediaPlayerWnd
    
    CMediaPlayerWnd::CMediaPlayerWnd()
    {
        m_mciDeviceID = 0;
        m_bPlaying = FALSE;
        m_bOpened = FALSE;
    
        EnableAutomation();
    }
    
    CMediaPlayerWnd::~CMediaPlayerWnd()
    {
    }
    
    void CMediaPlayerWnd::OnFinalRelease()
    {
        CWnd::OnFinalRelease();
    }
    
    LONG CMediaPlayerWnd::OnMciNotify(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
    {
        m_bPlaying = FALSE;
        mciSendCommand(m_mciDeviceID, MCI_SEEK, MCI_SEEK_TO_START, (DWORD)(LPVOID)NULL);
        Close(hWnd);
    
        return 0L;
    }
    
    BEGIN_MESSAGE_MAP(CMediaPlayerWnd, CWnd)
        //{{AFX_MSG_MAP(CMediaPlayerWnd)
            // NOTE - the ClassWizard will add and remove mapping macros here.
        ON_MESSAGE(MM_MCINOTIFY, OnMciNotify)
        //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    
    BEGIN_DISPATCH_MAP(CMediaPlayerWnd, CWnd)
        //{{AFX_DISPATCH_MAP(CMediaPlayerWnd)
            // NOTE - the ClassWizard will add and remove mapping macros here.
        //}}AFX_DISPATCH_MAP
    END_DISPATCH_MAP()
    
    // {F3E179A1-476B-11D4-A880-00E029302FE0}
    static const IID IID_IVideo = {0xf3e179a1, 0x476b, 0x11d4, { 0xa8, 0x80, 0x0, 0xe0, 0x29, 0x30, 0x2f, 0xe0 }};
    
    BEGIN_INTERFACE_MAP(CMediaPlayerWnd, CWnd)
        INTERFACE_PART(CMediaPlayerWnd, IID_IVideo, Dispatch)
    END_INTERFACE_MAP()
    
    //////////////////////////////////////////////////////////////////////////
    // CenterMediaPlayerWnd - Zentriert das Video in seinem Fenster
    void CMediaPlayerWnd::CenterMediaPlayerWnd(HWND hWnd)
    {
        RECT rcMovie;
        RECT rcClient, rcMovieBounds;
        MCI_DGV_RECT_PARMS  mciRect;
    
        // Wenn noch keins geöffnet ist rausgehen
        if(!m_bOpened) return;
    
        // Rechteck des Parents holen
        ::GetClientRect(hWnd, &rcClient);   
    
        // Originalgröße holen
        mciSendCommand(m_mciDeviceID, MCI_WHERE, (DWORD)(MCI_DGV_WHERE_SOURCE), (DWORD)(LPMCI_DGV_RECT_PARMS)&mciRect);
    
        // Kopieren
        CopyRect(&rcMovieBounds, &mciRect.rc);
    
        rcMovie.left = (rcClient.right/2) - (rcMovieBounds.right / 2);
        rcMovie.top = (rcClient.bottom/2) - (rcMovieBounds.bottom / 2);
        rcMovie.right = rcMovie.left + rcMovieBounds.right;
        rcMovie.bottom = rcMovie.top + rcMovieBounds.bottom;
    
        // Neu positionieren
        ::MoveWindow(m_hwnd, rcClient.left, rcClient.top, rcClient.right, rcClient.bottom, TRUE);
    }
    
    //////////////////////////////////////////////////////////////////////////
    // Open - Mediadatei mit Datei-Öffnen Dialog öffnen
    void CMediaPlayerWnd::Open(HWND hWnd, LPCTSTR szFilter)
    {
        CFileDialog dlg(1, 0, 0, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter);
    
        // Dateinamen holen
        if(dlg.DoModal() == IDOK)
            Open(dlg.m_ofn.lpstrFile, hWnd);
    }
    
    //////////////////////////////////////////////////////////////////////////
    // Open - Mediadatei mit angegebenem Pfad öffnen
    void CMediaPlayerWnd::Open(LPSTR sVPath, HWND hWnd)
    {
        MCI_DGV_OPEN_PARMS mciOpen;
        MCI_DGV_WINDOW_PARMS mciWindow;
        MCI_DGV_STATUS_PARMS mciStatus;
    
        // Altes schließen
        if(m_bOpened) Close(hWnd);  
    
        // MCI-Parameter einstellen
        mciOpen.wDeviceID = 0;
        mciOpen.lpstrDeviceType = NULL;
        mciOpen.lpstrElementName = sVPath;
        mciOpen.lpstrAlias = NULL;
        mciOpen.dwStyle = WS_CHILD;
        mciOpen.hWndParent = hWnd;
    
        // Versuchen die Datei zu öffnen
        if(mciSendCommand(0, MCI_OPEN, (DWORD)(MCI_OPEN_ELEMENT|MCI_DGV_OPEN_PARENT|
            MCI_DGV_OPEN_WS|MCI_OVLY_WINDOW_ENABLE_STRETCH ),   (DWORD)(LPMCI_DGV_OPEN_PARMS)&mciOpen) == 0)
        {
            // Abspielen
            m_mciDeviceID = mciOpen.wDeviceID;
            m_bOpened = TRUE;
    
            // Wiedergabefenster zeigen
            mciWindow.hWnd = NULL;
            mciWindow.nCmdShow = SW_SHOW;
            mciWindow.lpstrText = (LPSTR)NULL;
            mciSendCommand(m_mciDeviceID, MCI_WINDOW, MCI_DGV_WINDOW_STATE| MCI_OVLY_WINDOW_ENABLE_STRETCH,
                (DWORD)(LPMCI_DGV_WINDOW_PARMS)&mciWindow);
    
            // Fenster-Handle holen
            mciStatus.dwItem = MCI_DGV_STATUS_HWND;
            mciSendCommand(m_mciDeviceID, MCI_STATUS, MCI_STATUS_ITEM, (DWORD)(LPMCI_STATUS_PARMS)&mciStatus);
            m_hwnd = (HWND)mciStatus.dwReturn;
    
            // Zentrieren
            CenterMediaPlayerWnd(hWnd);
        }
        else m_bOpened = FALSE; // Nicht geöffnet
    
        // Neuzeichnen und aktualisieren
        ::InvalidateRect(hWnd, NULL, FALSE);
        ::UpdateWindow(hWnd);
    }
    
    //////////////////////////////////////////////////////////////////////////
    // Close - Mediadatei schließen
    void CMediaPlayerWnd::Close(HWND hWnd)
    {
        MCI_GENERIC_PARMS  mciGeneric;
        mciSendCommand(m_mciDeviceID, MCI_CLOSE, 0L, (DWORD)(LPMCI_GENERIC_PARMS)&mciGeneric);
    
        m_bPlaying = FALSE;
        m_bOpened = FALSE;
    
        // Komplett neuzeichnen
        ::InvalidateRect(hWnd, NULL, TRUE);
        ::UpdateWindow(hWnd);
    }
    
    //////////////////////////////////////////////////////////////////////////
    // Play - Abspielen/Pause-Funktion
    void CMediaPlayerWnd::Play(HWND hWnd,int nDirection)
    {
        m_bPlaying = !m_bPlaying;
        if(!nDirection)
            m_bPlaying = FALSE;
    
        if(m_bPlaying)
        {
            DWORD dwFlags;
            MCI_DGV_PLAY_PARMS mciPlay;
    
            // Initialisieren 
            mciPlay.dwFrom = mciPlay.dwTo = 0;
            dwFlags = MCI_NOTIFY;
            if(nDirection == MPW_RPLAY)
                dwFlags |= MCI_DGV_PLAY_REVERSE;   
    
            // Abspielen
            mciSendCommand(m_mciDeviceID, MCI_PLAY, dwFlags, (DWORD)(LPMCI_DGV_PLAY_PARMS)&mciPlay);
        }
        else
        {
            MCI_DGV_PAUSE_PARMS mciPause;
    
            // Pausieren
            mciSendCommand(m_mciDeviceID,MCI_PAUSE,0L, (DWORD)(LPMCI_DGV_PAUSE_PARMS)&mciPause);
        }
    }
    
    //////////////////////////////////////////////////////////////////////////
    // Seek - Springt an den Anfang oder an das Ende der Mediadatei
    void CMediaPlayerWnd::Seek(HWND hWnd, int nAction)
    {
        // Anhalten
        if(m_bPlaying) Play(hWnd, 0);   
    
        if(nAction == MPW_HOME) // An den Anfang gehen
            mciSendCommand(m_mciDeviceID, MCI_SEEK, MCI_SEEK_TO_START, (DWORD)(LPVOID)NULL);
        else if (nAction == MPW_END) // Ans Ende gehen
            mciSendCommand(m_mciDeviceID, MCI_SEEK, MCI_SEEK_TO_END, (DWORD)(LPVOID)NULL);
    }
    
    //////////////////////////////////////////////////////////////////////////
    // Step - Einen Schritt in die gewünschte Richtung machen
    void CMediaPlayerWnd::Step(HWND hWnd, int nDirection)
    {
        MCI_DGV_STEP_PARMS  mciStep;
    
        // Anhalten
        if(m_bPlaying) Play(hWnd, 0);
    
        mciStep.dwFrames = 1L;
    
        if(nDirection == MPW_STEP) // Nach vorne
            mciSendCommand(m_mciDeviceID, MCI_STEP, MCI_DGV_STEP_FRAMES,(DWORD)(LPMCI_DGV_STEP_PARMS)&mciStep);
        else // Nach hinten
            mciSendCommand(m_mciDeviceID, MCI_STEP, MCI_DGV_STEP_FRAMES|MCI_DGV_STEP_REVERSE, (DWORD)(LPMCI_DGV_STEP_PARMS)&mciStep);
    }
    


  • PlaySound kann nicht aus dem Speicher abspielen, sondern nur aus Resourcen, von Platte oder Systemsounds...

    ach ja? und warum gibt es dann bei PlaySound die Option SND_MEMORY :o



  • Sorry, jetzt sehe ich es... 🙄 Und der LPCSTR soll auf die Speicheradresse zeigen??? Was für ein Krampf...



  • Hi, können die Video-Abpsiel-Beispiele, denn auch die Videos vom Speicher abspielen ?



  • Wie gesagt, weiß ich nicht. Willst du die nicht von Platte abspielen???



  • Ja, ich würde die Dateien gerne direkt aus dem Speicehr abspielen wollen.
    Wo kann ich mich denn da erkundigen, wie man das machen kann ?
    Ich meien, wenn ihr es unbdingt realiersieren wolltet, wie würdet ihr vorgehen ?

    Gruß Nervenbündel !

    P.S. Danke für eure Antworten.



  • Warum musst du die Dateien denn erst in den Speicher lesen??? Naja, im Zweifelsfall kannst du dir auch ein Tempfile machen und den Speicher da reinschreiben. Ist aber sehr langsam



  • Ja, das ist es ja gerade. Ich will einfach ne kleien Video datei in den Speicher laden und abspielen, das ist mit sound ja auch nicht schwer, mit video dürfte es dann auch ekein Probleme geben. 😡 😡 😡 😡 😡 😡



  • Immer mit der Ruhe 😡 . DU brauchst den doch nicht selber in den SPeicher zu lesen. Das macht das Interface. Es reicht wenn du einen Pfad auf der Platte angibst...



  • Ich möchte doch aus dem Speicher abspielen.
    Nicht von der HD (also ohne Pfad), sodnern einfach die BYTE Variable angeben können wo dasVideo drinsteckt und dann abpsielen.
    So wie bei PlaySound.

    Weiß da jemand was ?

    Ich bin schon halb am Verzweifeln.

    Gruß Nervenbündel



  • So ohne weiteres geht das nicht. Beschäftige dich mal mit der MCI-Schnittstelle und sieh nach ob du dazu etwas findest. ICh sehe aber eigentlich relativ schwarz... Wofür brauchst du das eigentlich???



  • @MaSTaH
    Naja, ich will es halt für ein Spiel nutzen.
    Ist doch ganz praktisch.
    Bist du dir sicher, dass es nicht geht ? Bei WAV dateien geht es doch auch.
    Das dürfte doch kein Prblem sein.



  • Ja, aber warum soll das MCI es nicht in den Speicher laden. Brauchst dich dann doch garnicht darum zu kümmern, dass es in den Buffer kommt



  • Ich will dateien in den Speicehr laden können und dann nach belieben abspielen können.



  • @Nervenbündel: Du machst deinem Namen alle Ehre. Sei erstmal dankbar, dass MaSTaH dir überhaupt hilft. Außerdem: Wo liegt der Sinn, das File erst selber in den Speicher zu laden und dann irgendwie abzuspielen, wenn es für diesen Vorgang bereits ein Interface gibt?! Gib dich mit dem zufrieden, was MaSTaH dir gegeben hat und nerv nicht.



  • Wenn's interessiert (eigentlich ist er ja schon outdated 🙂 )

    char *lpData; // pointer auf buffer mit AVI!-Data
    int fileSize; // dateigröße der AVI-Datei

    LRESULT CALLBACK IOProc(LPMMIOINFO lpMMIOInfo, UINT uMessage, LPARAM lParam1,
    LPARAM lParam2);

    void main(void)
    {
    mmioInstallIOProc(mmioFOURCC('M','E','Y',' '),(LPMMIOPROC)
    IOProc,MMIO_INSTALLPROC | MMIO_GLOBALPROC); // installiert eigene ioProc

    myPlayAvi( WINDOWHANDLE, ".MEY+", 0); // extension MEY+ teilt MCI mit eigene ioProc aufzurufen

    myStopAvi();

    mmioInstallIOProc(mmioFOURCC('M', 'E', 'Y', ' '), NULL,
    MMIO_REMOVEPROC); // deinstalliert eigene ioProc

    }

    LRESULT CALLBACK IOProc(LPMMIOINFO lpMMIOInfo, UINT uMessage, LPARAM lParam1, LPARAM lParam2)
    { switch (uMessage)
    { case MMIOM_OPEN:
    { if (alreadyOpened) return 0;
    alreadyOpened = true;
    lpMMIOInfo->lDiskOffset = 0;
    return 0;
    }
    case MMIOM_CLOSE: return 0;
    case MMIOM_READ:
    { memcpy((void *)lParam1,lpData+lpMMIOInfo->lDiskOffset,lParam2);
    lpMMIOInfo->lDiskOffset += lParam2;
    return (lParam2);
    }
    case MMIOM_SEEK:
    { switch (lParam2)
    { case 0: lpMMIOInfo->lDiskOffset = lParam1; break;
    case 1: lpMMIOInfo->lDiskOffset += lParam1; break;
    case 2: lpMMIOInfo->lDiskOffset = fileSize - 1 - lParam1; break;
    }
    return lpMMIOInfo->lDiskOffset;
    }
    default: return -1;
    }
    }

    int myPlayAvi (HWND hWnd, char *filename, int loop)
    {
    char cmd[300];
    // MPEGVideo geht nicht.... type AVIVideo!
    wsprintf(cmd, "open \"%s\" alias mympeg type AVIVideo style child", filename);
    if (mciSendString(cmd, 0, 0, 0) != 0)
    {
    MessageBox(NULL, "MCI-Error: Kann Datei nicht öffnen!", "Fehler", 0);
    return -1;
    }

    wsprintf(cmd, "window mympeg handle %lu", hWnd);
    if (mciSendString(cmd, 0, 0, 0) != 0)
    {
    wsprintf(cmd, "MCI-Error: Kann window handle %ld nicht setzen", hWnd);
    MessageBox(NULL, cmd, "Fehler", 0);
    return -1;
    }

    wsprintf(cmd, "play mympeg from 0");
    if (loop) wsprintf(cmd, "%s repeat", cmd);
    if (mciSendString(cmd, 0, 0, 0) != 0)
    {
    MessageBox(NULL, "MCI-Error: Kann Datei nicht absielen!", "Fehler", 0);
    return -1;
    }
    return 0;
    }

    int myStopAvi (void)
    {
    char cmd[300];
    wsprintf(cmd, "close mympeg");
    if (mciSendString(cmd, 0, 0, 0) != 0)
    {
    MessageBox(NULL, "MCI-Error: Kann Datei nicht schließen!", "Fehler", 0);
    return -1;
    }
    return 0;
    }

    Quelle:
    MSDN : http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q155/3/60.asp&NoWebContent=1
    thx 2 DocJunior's AVI-Code

    Soweit ich festellen konnte, wird die eigene ioProc bloß beim type AVIVideo gecallt....
    MPEGVideo hab ich nicht hinbekommen 😞 ob type WAVAudio hab ich jetzt nicht getestet

    gruß nameless


Anmelden zum Antworten