Come ottenere frame, frame rate e altri attributi del clip video Se si ha esperienza con la scrittura di applicazioni in Servizi di modifica Microsoft DirectShow (nome in codice Dexter), questo risulterà molto familiare. Nell'ambiente Windows, la tradizionale acquisizione di fotogrammi è stata effettuata utilizzando C++ e Dexter Type Library per accedere agli oggetti COM di DirectShow. Per fare ciò in .NET Framework, è possibile creare un assembly Interop di DexterLib che è elencato in Riferimenti COM in VS 2005. Tuttavia richiede una buona quantità di lavoro per capire come convertire il codice da C++ a C# .NET. Il problema si verifica quando è necessario passare un riferimento del puntatore come argomento a una funzione nativa, CLR non supporta direttamente i puntatori poiché la posizione della memoria può cambiare dopo ogni ciclo di garbage collection. Puoi trovare molti articoli su come utilizzare DirectShow sul CodeProject o altri luoghi e cerchiamo di mantenerlo semplice. Qui il nostro obiettivo è convertire un file video in una serie di bitmap e ho cercato di mantenerlo il più breve possibile, ovviamente puoi scrivere il tuo codice per estrarre le bitmap da un live streaming e bufferarle poco prima di inviarle .
Fondamentalmente abbiamo due possibilità per l'utilizzo del DirectShow per la conversione del nostro file video in fotogrammi in .NET:
Modifica di interoperabilità e modificare i riferimenti di tipo di puntatore a C# .NET tipi. Utilizzare i puntatori con una parola chiave non sicura. Abbiamo scelto il metodo non sicuro (leggi veloce). Significa che estraiamo i nostri frame al di fuori dell'ambito gestito .NET. È importante menzionare che gestito non sempre significa migliore e pericoloso non significa in realtà pericoloso!
MediaDetClass mediaClass = new MediaDetClass(); _AMMediaType mediaType; ... // carica il file video int outputStreams = mediaClass.OutputStreams; outFrameRate = 0.0; per (int i = 0; i < outputStreams; i ++) { mediaClass.CurrentStream = i; prova { // Se è possibile ottenere il framerate, è sufficiente, // accettiamo il file video altrimenti esso genera un'eccezione qui outFrameRate = mediaClass.FrameRate; ....... // ottenere gli attributi qui .....
}catch
{ // Not a valid meddia type? go to the next outputstream }
} // No frame rate? if (outFrameRate == 0.0) lanciare NotSupportedException ("Il programma non riesce" + "per leggere il file video."); // abbiamo un framerate? andare avanti ... ... // Crea un array per contenere le bitmap e intilize // altri oggetti per memorizzare le informazioni ...
insicuro { ... // Crea un puntatore di byte per memorizzare le BitmapBits
... while (currentStreamPos < endPosition) { mediaClass.GetBitmapBits (currentStreamPos, bufferSize ref, ref * ptrRefFramesBuffer, outClipSize.Width, outClipSize.Height); ...
// aggiungere una cornice Bitmap alla frameArray ... }} ...
di trasferimento dati estratti oltre HTTP Finora abbiamo convertito il nostro video per una serie di fotogrammi bitmap. Il prossimo passo è trasferire i nostri frame su HTTP fino al browser del cliente. Sarebbe bello se potessimo semplicemente inviare i bit Bitmap al client, ma non possiamo. HTTP è progettato per trasportare caratteri di testo, il che significa che il tuo browser legge solo caratteri definiti nel set di caratteri della pagina HTML. Tutto il resto fuori da questa codifica non può essere visualizzato direttamente.
Per completare questo passaggio, utilizziamo la codifica Base64 per convertire i nostri bitmap in caratteri ASCII. Tradizionalmente, la codifica Base64 è stata utilizzata per incorporare oggetti nelle e-mail. Quasi tutti i browser moderni inclusi i browser Gecko, Opera, Safari e KDE (non IE!) Supportano i dati: schema standard URI per visualizzare le immagini codificate Base64. Grande! Ora, abbiamo i nostri frame pronti per essere trasferiti su HTTP.
Memoria System.IO.MemoryStream = new System.IO.MemoryStream(); mentre (currentStreamPos < endPosition) { ... // Salvare le Bitmpas da qualche parte nel (gestito) di memoria vdeoBitmaps.Save (memoria, System.Drawing.Imaging.ImageFormat.Jpeg); // Converti in Base64 strFrameArray [frameCount] = System.Convert.ToBase64String (memory.ToArray()); // Preparati per il prossimo memory.Seek (0, System.IO.SeekOrigin.Begin); } memory.Close(); ...
Ma non possiamo semplicemente inviare i frame codificati come una stringa gigante. Creiamo un documento XML che contiene i nostri frame e altre informazioni sul video e quindi lo invia al client. In questo modo il browser può ricevere i nostri frame come un oggetto DOM XML e navigare facilmente attraverso di essi. Provate a immaginare come sia facile modificare un video che è memorizzato in formato XML:
14,9850224700412 {width = 160, Height = 120} 6,4731,334 mila /9 J/4AAQSkZJRgABAQEAYAB .... ....
Questo formato ha anche i suoi svantaggi. I video convertiti in file XML codificati Base64 vanno da qualche parte tra il 10% (per lo più file AVI) al 300% o più (alcuni file WMV) più grandi del loro equivalente binario.
Se si utilizza un file XML, non è nemmeno necessario un server Web, è possibile aprire l'HTML da una directory locale e dovrebbe funzionare! Ho incluso un eseguibile nel file di download dell'articolo che può convertire il tuo file video in documento XML che può essere mostrato successivamente nel browser. Tuttavia, l'utilizzo di file di grandi dimensioni e video ad alta risoluzione non è una buona idea!
OK, ora possiamo inviare il nostro documento XML encBase64 video codificato come faremmo con qualsiasi altro tipo di file XML. Chi dice che i file XML devono essere sempre record noiosi comunque
ti sto leggendo correttamente che si sta tentando di scrivere un'applicazione che intercetta l'audio in fase di trasferimento tra due applicazioni flash (nessuno dei quali è collegato alla propria applicazione)? – bta