Sorgenti custom per MediaElement di WPF

di Cristian Civera, in .NET 3.0,

L'elemento MediaElement è un gran bell'oggettino :-) Permette di mostrare e ascoltare video e audio, il tutto perfettamente integrato con WPF permettendoci di ridimensionarlo come ci pare, usarlo come brush, trasformarlo, applicare trasparenze, ecc...

L'unico problema è che al di là di file su disco o uri http, non si può andare. Per esempio può essere utile usare come sorgente la webcam, un tuner TV o una fonte analogica esterna. Per ottenere ciò ci sono vari modi:

  • Usare l'elemento HwndSource così da avere una finestra Win32. Tramite la proprietà Handle abbiamo il suo puntatore e possiamo quindi usare DirectShow effettuando il rendering puntando la finestra con l'interfaccia IVideoWindow. Se vi interessa è disponibile questo progetto pieno di classi interop per usare DirectShow in .NET.
    Questo approccio ha dei limiti dovuti al fatto che HwndSource è sì un elemento WPF, ma poiché contiene al suo interno una nuova finestra Win32 non permette di effettuare trasformazioni, trasparenze, ecc.
  • Costruire un protocol handler per un proprio schema (esempio webcam://qualcosa) che faccia uso di un source filter personalizzato per DirectShow. Questo è possibile perché MediaElement utilizza al suo interno Windows Media Player che a sua volta si basa su Windows Media Foundation che a sua volta usa (se necessario) DirectShow.

Ho provato entrambi le modalità e ovviamente la seconda è la migliore (esiste una terza che sto ancora sperimentando). Nella seconda ho scritto in C++ un source filter che implementa IFileSourceFilter, così da essere da essere chiamato per caricare il mio schema custom. Non entro troppo nei dettagli, ma è compito di WMP caricare il mio filtro e, una volta aggiunto al grafo DirectShow, renderizzare il pin video in uscita sfruttando l'Intelligent Connect. Questo sistema in pratica si mette a guardare i pin del filtro sorgente e prova le possibili combinazioni tra filtri di decodifica e di rendering fino a quando non riesce a mostrare il video e/o ad emettere il suono. In WPF il filtro sorgente quindi dipende dal protocol handler, mentre il rendering video viene effettuato mediante Enhanced Video Renderer: un filtro nuovo e più evoluto che permette l'integrazione in WPF.

Nella mia prova ho usato il tipico filtro Ball presente nel SDK, costituito da un pin che restituisce uno stream video che mostra una palla rimbalzare. Una volta pronto il filtro, va poi registrato sia come dll, sia mappando lo schema custom al filtro. Possiamo poi usarlo sia in WMP che in GraphEdit (un tool per testare i filtri). Ecco uno screenshot:

ball1

A questo punto possiamo usare il filtro anche in WPF:

<MediaElement Source="ball://test" />

E questo è il risultato che si ottiene applicandoci il tipico effetto riflesso, per far vedere che possiamo trattare il video come vogliamo:

ball2

Quindi in teoria possiamo fare un pin che prenda lo stream da un grafo interno oppure possiamo fare un filtro senza pin, ma che sul metodo Load inserisce nel grafo un nuovo filtro sorgente (webcam, tuner ecc). Ci pensa poi l'intelligent connect ad ignorare il nostro filtro custom, proseguendo sull'altro da noi creato. Questa variante è stilisticamente meno carina, ma più semplice.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Nella stessa categoria
I più letti del mese