Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Player Simple Con Directshow

Iniciado por infiniter, 27 de Julio de 2003, 07:05:56 PM

« anterior - próximo »

infiniter

 Hay un ejemplo llamado PlayWnd del Directshow en el SDK del DirectX. El problema que tengo es que no puedo correrlo debido a que parece no encontrar el tipo IVideoFrameStep, que se encuentra en el strmif.h, y además tampoco encuentra el tipo LONG_PRT ni el WORD_PTR.  

Esto lo he corrido en varias máquinas, pero en ninguna me ha funcionado :( .  

El asunto es que necesito hacer un player simplísimo para un vídeo introductorio (formato mpeg y en pantalla completa), por lo que me estoy basando en ese ejemplo que no sé como arreglar. (nooo)

Si alguien me puede ayudar con esto o proporcionar alguno por ahí, bienvenido sea.


infiniter

 ¿alguien me puede contestar?

La insistencia se debe a que lo necesito para ayer. :(


[Over]

 Hola.
Aqui te pego las clases que yo uso para reproducir videos:



/*********************************************************************************
Nombre:      Video.cpp
Descripción: Clase que lleva el control de un video
/*********************************************************************************/

#include "Pch_Base.h"

#include "Video.h"

//----------------------------------------------------------------------
//  Uso:            
//  Retorno:        
//  Parametros:    
//----------------------------------------------------------------------
CVideo::CVideo()
{
 m_bOk = false;
}

//----------------------------------------------------------------------
//  Uso:            
//  Retorno:        
//  Parametros:    
//----------------------------------------------------------------------
CVideo::~CVideo()
{
 End();
}

//----------------------------------------------------------------------
//  Uso:            
//  Retorno:        
//  Parametros:    
//----------------------------------------------------------------------
void CVideo::BorraVars()
{
 m_bOk             = false;
 m_bVideoActivo    = false;
 m_bFullScreen     = false;
 m_bLoad           = false;

 m_hwnd            = NULL;

 m_dwGraphRegister = 0;

 m_tVideoState     = VS_STOP;

 m_pGraphBuilder   = NULL;
 m_pMediaControl   = NULL;
 m_pMediaEvent     = NULL;
 m_pVideoWindow    = NULL;

 ZeroMemory(m_sToken,sizeof(m_sToken));
 ZeroMemory(m_sFileVideo,sizeof(m_sFileVideo));
}

//----------------------------------------------------------------------
//  Uso:            
//  Retorno:        
//  Parametros:    
//----------------------------------------------------------------------
void CVideo::LiberaVars()
{
 
 if (m_pVideoWindow)
 {
   m_pVideoWindow -> put_Visible(OAFALSE);
   m_pVideoWindow -> put_Owner(NULL);
 }

 //if (m_pMediaEvent)
   //m_pMediaEvent->SetNotifyWindow((OAHWND)NULL, 0, 0);


 #ifdef REGISTER_FILTERGRAPH

   if (m_dwGraphRegister)
   {
     RemoveGraphFromRot(m_dwGraphRegister);
     m_dwGraphRegister = 0;
   }
 
 #endif // REGISTER_FILTERGRAPH

 RELEASE (m_pMediaControl);
 RELEASE (m_pVideoWindow);
 RELEASE (m_pMediaEvent);
 RELEASE (m_pGraphBuilder);
}

//----------------------------------------------------------------------
//  Uso:            
//  Retorno:        
//  Parametros:    
//----------------------------------------------------------------------
void CVideo::End()
{
 if (m_bOk)
 {
   LiberaVars();
   CoUninitialize();
   m_bLoad = false;
   m_bOk = false;
 }
}

//----------------------------------------------------------------------
//  Uso:            
//  Retorno:        
//  Parametros:    
//----------------------------------------------------------------------
bool CVideo::Init(HWND hwnd,char *sFileVideo,char *sTokenVideo,bool bFullScreen)
{
 End();
 BorraVars();

 if (sTokenVideo[0]) strcpy(m_sToken,sTokenVideo);
 if (sFileVideo[0])  strcpy(m_sFileVideo,sFileVideo);

 m_hwnd = hwnd;
 m_bFullScreen = bFullScreen;
 
 m_bOk = true;
 return (m_bOk);
}

//----------------------------------------------------------------------
//  Uso:            
//  Retorno:        
//  Parametros:    
//----------------------------------------------------------------------
void CVideo::InitInterfaces()
{
 /* -- Interface: Filter Graph" -- */
 CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC,
                  IID_IGraphBuilder,(void**)&m_pGraphBuilder);

 /* -- Interfaces: PlayBack & ScreenSize & Control de eventos -- */
 m_pGraphBuilder -> QueryInterface (IID_IMediaControl,  (void**) &m_pMediaControl);
 m_pGraphBuilder -> QueryInterface (IID_IVideoWindow,   (void**) &m_pVideoWindow );
 m_pGraphBuilder -> QueryInterface (IID_IMediaEventEx,  (void**) &m_pMediaEvent  );

}

//----------------------------------------------------------------------
//  Uso:            
//  Retorno:        
//  Parametros:    
//----------------------------------------------------------------------
void CVideo::LoadVideo(char *sFileVideo)
{
 WCHAR wstrFileName[MAX_PATH];
 RECT area_ventana;
 
 GetClientRect(m_hwnd,&area_ventana);
 MultiByteToWideChar(CP_ACP, 0, sFileVideo, -1, wstrFileName, MAX_PATH);

 CoInitialize(NULL);
 InitInterfaces();
 
 m_pGraphBuilder->RenderFile(wstrFileName,NULL);

 m_pVideoWindow->put_MessageDrain((OAHWND)m_hwnd);

 if ((m_pVideoWindow->put_Owner((OAHWND)m_hwnd)) == S_OK)
 {
     //m_pVideoWindow -> put_Visible  (OAFALSE);
     //m_pVideoWindow -> put_AutoShow (OAFALSE);
     m_pVideoWindow -> put_WindowStyle   (WS_CHILD | WS_CLIPSIBLINGS);
     m_pVideoWindow -> SetWindowPosition (area_ventana.left,area_ventana.top,area_ventana.right,area_ventana.bottom);
 }

 m_bLoad = true;
}

//----------------------------------------------------------------------
//  Uso:            
//  Retorno:        
//  Parametros:    
//----------------------------------------------------------------------
void CVideo::SetFullScreen()
{
 LONG lMode;
 
 if (m_pVideoWindow)
 {
   m_pVideoWindow->get_FullScreenMode(&lMode);
   if (lMode == 0) /* -- No fullscreen -- */
   {
     m_pVideoWindow->put_MessageDrain((OAHWND)m_hwnd);
     
     lMode = -1; /* -- FullScreen mode -- */
     m_pVideoWindow->put_FullScreenMode(lMode);
   }
 }
   
}

//----------------------------------------------------------------------
//  Uso:            
//  Retorno:        
//  Parametros:    
//----------------------------------------------------------------------
void CVideo::Play()
{
 if (!m_bLoad)
   LoadVideo();

 if (m_bFullScreen)
   SetFullScreen();

 m_pMediaControl->Run();
 m_tVideoState = VS_PLAY;

 /* -- Loop principal mientras el video se reproduce... -- */
 while (m_tVideoState == VS_PLAY)
 {
   MSG msg;
   long lEventCode, lParam1, lParam2;

   if(E_ABORT != m_pMediaEvent->GetEvent(&lEventCode, (LONG_PTR *) &lParam1,
                             (LONG_PTR *) &lParam2, 0))
   {
   
     m_pMediaEvent->FreeEventParams(lEventCode, lParam1, lParam2);
           
     if (lEventCode == EC_COMPLETE)
       m_tVideoState = VS_STOP;
   }

   while (PeekMessage (&msg, m_hwnd, 0, 0, PM_REMOVE))
   {
     TranslateMessage(&msg);
     DispatchMessage(&msg);
   }
 }
 
 m_pMediaControl->Stop();
 End();
}

//----------------------------------------------------------------------
//  Uso:            
//  Retorno:        
//  Parametros:    
//----------------------------------------------------------------------
void CVideo::Run()
{
 LONG code;

 if (m_pMediaControl)
 {
   m_bVideoActivo  = true;
   m_pVideoWindow  ->  put_Visible(OATRUE);
   m_pMediaControl ->  Run();
   m_pMediaEvent   ->  WaitForCompletion (INFINITE,&code);
   m_pVideoWindow  ->  put_Visible(OAFALSE);

 }
}

#ifdef REGISTER_FILTERGRAPH

//----------------------------------------------------------------------
//  Uso:            
//  Retorno:        
//  Parametros:    
//----------------------------------------------------------------------

HRESULT CVideo::AddGraphToRot(IUnknown *pUnkGraph, DWORD *pdwRegister)
{
   IMoniker * pMoniker;
   IRunningObjectTable *pROT;
   if (FAILED(GetRunningObjectTable(0, &pROT)))
   {
       return E_FAIL;
   }

   WCHAR wsz[128];
   wsprintfW(wsz, L"FilterGraph %08x pid %08x", (DWORD_PTR)pUnkGraph,
             GetCurrentProcessId());

   HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker);
   if (SUCCEEDED(hr))
   {
       hr = pROT->Register(0, pUnkGraph, pMoniker, pdwRegister);
       pMoniker->Release();
   }

   pROT->Release();
   return hr;
}

//----------------------------------------------------------------------
//  Uso:            
//  Retorno:        
//  Parametros:    
//----------------------------------------------------------------------
void CVideo::RemoveGraphFromRot(DWORD pdwRegister)
{
   IRunningObjectTable *pROT;

   if (SUCCEEDED(GetRunningObjectTable(0, &pROT)))
   {
       pROT->Revoke(pdwRegister);
       pROT->Release();
   }
}

#endif // REGISTER_FILTERGRAPH

-----------------------------------------------------------------------------
/*********************************************************************************
Nombre:      Video.h
Descripción: Clase que lleva el control de un video                          
/*********************************************************************************/

#ifndef _Video_H
#define _Video_H

#include <DShow.h>

//#define REGISTER_FILTERGRAPH

class CVideo
{

public:

 enum TVideoState
 {
   VS_PLAY  = 1,
   VS_PAUSE = 2,
   VS_STOP  = 3,
 };

                   CVideo              ();
                  ~CVideo              ();

 bool              Init                (HWND hwnd,char *sFileVideo,char *sTokenVideo,bool bFullScreen);
 void              End                 ();

 void              Run                 ();
 void              Play                ();

 void              SetFullScreen       ();

 HRESULT           RunMensajesDelVideo ();

 bool              IsVideoActivo       ()                    { return (m_bVideoActivo);  }
 bool              IsOk                ()                    { return (m_bOk);           }

 char             *GetTokenVideo       ()                    { return (m_sToken);        }

 void              LoadVideo           ()                    { LoadVideo(m_sFileVideo); }
 void              LoadVideo           (char *sFileVideo);

private:

 void              BorraVars           ();
 void              LiberaVars          ();

 void              InitInterfaces      ();
 
 HRESULT           AddGraphToRot       (IUnknown *pUnkGraph, DWORD *pdwRegister);
 void              RemoveGraphFromRot  (DWORD pdwRegister);

 IGraphBuilder    *m_pGraphBuilder;
 IMediaControl    *m_pMediaControl;
 IMediaEventEx    *m_pMediaEvent;
 IVideoWindow     *m_pVideoWindow;

 HWND              m_hwnd;

 DWORD             m_dwGraphRegister;

 TVideoState       m_tVideoState;
 char              m_sToken[255];
 char           m_sFileVideo[255];

 bool              m_bLoad;
 bool              m_bFullScreen;
 bool              m_bVideoActivo;
 bool              m_bOk;
};

#endif // _VideDevice_H


Yo para "playear" un video uso PLAY, puedes usar Run, pero te recomiendo que uses Play, puedes pasar del Run.
Esto reproduce mpeg sin problemas (es el formato que yo uso). No está adaptado para videos con sonido, pero vamos, mirate el SDK que viene la interface que necesita la clase para videos con sonido y el fullscreen no esta muy testeado, miratelo. La clase que yo uso es más completa que esa, pero esta es más sencilla de entender. Suerte.

PD: Perdona que no esté tabulado, pero no se ponerlo.  :rolleyes:  :P

Modificado por Mars Attacks: ya está "encodado" ;)

ethernet

 usa las etiquetas de BBcode "code" o "LIST" para que te mantenga el formato

infiniter

 Over,  te agradezco montones. Voy a revisar el código.

infiniter

 Algunas cuestiones:

-Me puedes pasar el "Pch_Base.h" y su .cpp (si es que lo tiene), ya que yo no lo tengo

-¿Ese código es una aplicación Win32?

-¿Cómo se usa el  el método    "bool init (HWND hwnd,char *sFileVideo,char *sTokenVideo,bool bFullScreen)"
¿de donde saco el valor para el 1er parámetro?

-¿para qué es el m_sToken?, es que no veo donde se utiliza

synchrnzr

 ¿Y no sería más fácil meter un ActiveX roñoso?   O_O

sync

[Over]

 Hola.

El valor del HWND hwnd del Init, pues sacalo de la ventana que hayas creado para tu aplicación. Si es una aplicacion Direct3D (sin usar MFC, ni VCL) pues habras creado la ventana por tu cuenta (supongo), vamos el mismo handle a la ventana que necesitas para crear los controles de las Direct-X.
La funcion Init no es más que para iniciar, es una mania que tengo (que me enseño un amiguete) de usar Init,End,etc.. Asi primero hago asi:


CVideo *pVideo;
pVideo = NEW CVideo; // NEW es una macro :P
if (pVideo)
{
 if (!pVideo->Init(.......))
 {
   // controlas errores y demas :)
   return false;
 }
}
...




El m_sToken, olvidate de el ya que es algo que uso en mi código. Tengo en otra clase una lista ligada con todos los videos segun el token y asi en el script solo hago PlayVideo("TOKEN_VIDEO"); y me olvido de la ruta,etc..

Y sobre lo que dice ethernet sobre el ActiveX roñoso, pues no se, quizas sería más facil o quizas no, quizas sea mejor o quizas no, la verdad que a mi gusto contra menos cosas "externas" uses pienso que es mejor. Pero vamos, el uso de las DirectShow para playear videos y hacer 3 cosas no es dificil. Ademas, yo he implementado DirectX con las VCL (Builder) y el código de los videos no he tenido ni que retocarlo, lo cual me ha permitido reproducir videos en controles dentro de un formulario sin nada de complicaciones.

El pch.base.h no e snada más que un fichero que posee una serie de macros personales, esa clase solo usa (a simple vista -creo-) el RELEASE(...); <-- no es más que una macro para hacer "release" de los interfaces.

Espero que te sirva, chao.  :D


infiniter

 Ya casi lo tengo listo. (ole)
Hasta ahora estoy retomando C++,  es que lo había dejado para dedicarme a ciertos proyectos.  Ahora estoy interesado en el DirectX, y parece ser que C++ tiene la ventaja.

Muchísimas gracias por la ayuda.






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.