Come si salva la cornice corrente dell’elemento multimediale?

Sto sviluppando un lettore multimediale come vlc. Una delle sue funzioni è il salvataggio dell’istantanea durante la riproduzione. Sono in grado di salvare l’istantanea di qualsiasi elemento con la class rendertargetbitmap, utilizzando il seguente codice c #.

RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(); await renderTargetBitmap.RenderAsync(RenderedGrid, width, height); RenderedImage.Source = renderTargetBitmap; 

Ma non consente di catturare elementi multimediali. Per favore aiutami con una soluzione. Immagino, non sono sicuro, potrebbe essere ansible estraendo una miniatura da una posizione specifica usando la posizione di StorageItemThumbnail Class. Se è così, sarà una miniatura e non un’immagine della cornice attuale. Qualcuno aiuta per favore. È una caratteristica essenziale della mia app!

in un’app uwp di digital signage che ho sviluppato avevo anche un requisito simile. Cercando sul Web come posso fare ho scoperto che in UWP non è ansible eseguire direttamente uno screenshot di un elemento multimediale a causa di un criterio di protezione (ad esempio, è ansible creare una piccola app che cattura tutti i fotogrammi di un file video senza DRM gestione).

Ho trovato una soluzione: ho localmente il file video in modo da poter estrarre un singolo frame in un determinato punto e salvarlo su disco con le stesse dimensioni del video renderizzato sullo schermo (in questo modo ho avuto un’immagine completa del frame da utilizzare in seguito). Per fare questo ho scritto questa funzione:

 private async Task Capture(StorageFile file, TimeSpan timeOfFrame, Size imageDimension) { if (file == null) { return null; } //Get FrameWidth & FrameHeight List encodingPropertiesToRetrieve = new List(); encodingPropertiesToRetrieve.Add("System.Video.FrameHeight"); encodingPropertiesToRetrieve.Add("System.Video.FrameWidth"); IDictionary encodingProperties = await file.Properties.RetrievePropertiesAsync(encodingPropertiesToRetrieve); uint frameHeight = (uint)encodingProperties["System.Video.FrameHeight"]; uint frameWidth = (uint)encodingProperties["System.Video.FrameWidth"]; //Get image stream var clip = await MediaClip.CreateFromFileAsync(file); var composition = new MediaComposition(); composition.Clips.Add(clip); var imageStream = await composition.GetThumbnailAsync(timeOfFrame, (int)frameWidth, (int)frameHeight, VideoFramePrecision.NearestFrame); //Create BMP var writableBitmap = new WriteableBitmap((int)frameWidth, (int)frameHeight); writableBitmap.SetSource(imageStream); //Get stream from BMP string mediaCaptureFileName = "IMG" + Guid.NewGuid().ToString().Substring(0, 4) + ".jpg"; var saveAsTarget = await CreateMediaFile(mediaCaptureFileName); Stream stream = writableBitmap.PixelBuffer.AsStream(); byte[] pixels = new byte[(uint)stream.Length]; await stream.ReadAsync(pixels, 0, pixels.Length); using (var writeStream = await saveAsTarget.OpenAsync(FileAccessMode.ReadWrite)) { var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, writeStream); encoder.SetPixelData( BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, (uint)writableBitmap.PixelWidth, (uint)writableBitmap.PixelHeight, 96, 96, pixels); await encoder.FlushAsync(); using (var outputStream = writeStream.GetOutputStreamAt(0)) { await outputStream.FlushAsync(); } } return saveAsTarget.Name; } 

Questa funzione salva il frame su disco come immagine e restituisce il suo nome file. Nella mia applicazione ho avuto più “widget” (alcuni di quelli con immagini, alcuni con video) quindi ho usato questa funzione per ottenere i frame video e mettere una nuova immagine sopra l’elemento multimediale con le stesse dimensioni e un Canvas Z più alto -Indice per utilizzare RenderTargetBitmap per lo screenshot finale. Non è una soluzione pulita, ma è stata una soluzione alternativa per RenderTargetBitmap non considera MediaElement.

Modifica: ho dimenticato un riferimento a una funzione interna nella mia applicazione, quindi ho risolto il codice precedente e la riga var file = await _mediaEngine.CreateMediaFile($"{Guid.NewGuid().ToString()}.jpg"); è ora var file = await CreateMediaFile($"{Guid.NewGuid().ToString()}.jpg");

La funzione async CreateMediaFile (string fileName) crea semplicemente un nuovo file sul disco:

 public async Task CreateMediaFile(string filename) { StorageFolder _mediaFolder = KnownFolders.PicturesLibrary; return await _mediaFolder.CreateFileAsync(filename); }