void generatePreview(MediaFileItem item) { ItemProgressMax = 100; ItemProgress = 0; ItemInfo = "Creating video preview image for: " + System.IO.Path.GetFileName(item.Location); FileStream outputFile = null; RenderTargetBitmap bitmap = null; mediaProbe.open(item.Location, CancellationToken); try { int nrFrames = 0; if (asyncState.IsCaptureIntervalSecondsEnabled == false) { nrFrames = asyncState.NrRows * asyncState.NrColumns; } else { nrFrames = mediaProbe.DurationSeconds / asyncState.CaptureIntervalSeconds; nrFrames = calcNrRowsNrColumns(nrFrames); } int thumbWidth = asyncState.MaxPreviewImageWidth / asyncState.NrColumns; ItemProgressMax = nrFrames; double captureIntervalSeconds = asyncState.IsCaptureIntervalSecondsEnabled ? asyncState.CaptureIntervalSeconds : 0; List <MediaThumb> thumbs = mediaProbe.grabThumbnails(thumbWidth, 0, captureIntervalSeconds , nrFrames, 0.01, CancellationToken, 0, grabThumbnails_UpdateProgressCallback); if (thumbs.Count == 0 || CancellationToken.IsCancellationRequested) { return; } nrFrames = Math.Min(thumbs.Count, nrFrames); if (asyncState.IsCaptureIntervalSecondsEnabled == true) { nrFrames = calcNrRowsNrColumns(nrFrames); } JpegBitmapEncoder encoder = new JpegBitmapEncoder(); BitmapMetadata metaData = new BitmapMetadata("jpg"); metaData.ApplicationName = App.getAppInfoString(); metaData.DateTaken = DateTime.Now.ToString("R"); if (item.Metadata.Tags.Count > 0) { List <String> tags = new List <string>(); foreach (Tag tag in item.Metadata.Tags) { tags.Add(tag.Name); } metaData.Keywords = new ReadOnlyCollection <string>(tags); } if (item.Metadata.Title != null) { metaData.Title = item.Metadata.Title; } if (item.Metadata.Copyright != null) { metaData.Copyright = item.Metadata.Copyright; } if (item.Metadata.Description != null) { metaData.Subject = item.Metadata.Description; } if (item.Metadata.Author != null) { List <String> author = new List <string>(); author.Add(item.Metadata.Author); metaData.Author = new ReadOnlyCollection <string>(author); } if (item.Metadata.Rating != null) { metaData.Rating = (int)item.Metadata.Rating.Value; } // rendertargetbitmap has to be executed on the UI thread // if it's run on a non-UI thread there will be a memory leak App.Current.Dispatcher.Invoke(() => { VideoGridImage gridImage = new VideoGridImage(item.Metadata as VideoMetadata, asyncState, thumbs); bitmap = gridImage.createGridImage(asyncState.MaxPreviewImageWidth); }); BitmapFrame frame = BitmapFrame.Create(bitmap, null, metaData, null); encoder.Frames.Add(frame); String outputFileName = Path.GetFileNameWithoutExtension(item.Location) + ".jpg"; outputFile = new FileStream(asyncState.OutputPath + "/" + outputFileName, FileMode.Create); encoder.QualityLevel = asyncState.JpegQuality; encoder.Save(outputFile); ItemProgressMax = nrFrames; ItemProgress = nrFrames; InfoMessages.Add("Finished video preview image: " + asyncState.OutputPath + "/" + outputFileName); } catch (Exception e) { InfoMessages.Add("Error creating video preview image for: " + item.Location + " " + e.Message); Logger.Log.Error("Error creating preview image for: " + item.Location, e); } finally { if (bitmap != null) { bitmap.Clear(); bitmap = null; } if (outputFile != null) { outputFile.Close(); outputFile.Dispose(); } mediaProbe.close(); // because of the extreme amount of memory used by rendertargetbitmap // make sure we have it all back before moving on to prevent out of memory spikes GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); } }
void generatePreview(MediaFileItem item) { ItemProgressMax = 100; ItemProgress = 0; ItemInfo = "Creating video preview image for: " + System.IO.Path.GetFileName(item.Location); FileStream outputFile = null; RenderTargetBitmap bitmap = null; mediaProbe.open(item.Location, CancellationToken); try { int nrFrames = 0; if (asyncState.IsCaptureIntervalSecondsEnabled == false) { nrFrames = asyncState.NrRows * asyncState.NrColumns; } else { nrFrames = mediaProbe.DurationSeconds / asyncState.CaptureIntervalSeconds; nrFrames = calcNrRowsNrColumns(nrFrames); } int thumbWidth = asyncState.MaxPreviewImageWidth / asyncState.NrColumns; ItemProgressMax = nrFrames; double captureIntervalSeconds = asyncState.IsCaptureIntervalSecondsEnabled ? asyncState.CaptureIntervalSeconds : 0; List<MediaThumb> thumbs = mediaProbe.grabThumbnails(thumbWidth, 0, captureIntervalSeconds ,nrFrames, 0.01, CancellationToken, 0, grabThumbnails_UpdateProgressCallback); if (thumbs.Count == 0 || CancellationToken.IsCancellationRequested) return; nrFrames = Math.Min(thumbs.Count, nrFrames); if (asyncState.IsCaptureIntervalSecondsEnabled == true) { nrFrames = calcNrRowsNrColumns(nrFrames); } JpegBitmapEncoder encoder = new JpegBitmapEncoder(); BitmapMetadata metaData = new BitmapMetadata("jpg"); metaData.ApplicationName = App.getAppInfoString(); metaData.DateTaken = DateTime.Now.ToString("R"); if (item.Metadata.Tags.Count > 0) { List<String> tags = new List<string>(); foreach (Tag tag in item.Metadata.Tags) { tags.Add(tag.Name); } metaData.Keywords = new ReadOnlyCollection<string>(tags); } if (item.Metadata.Title != null) { metaData.Title = item.Metadata.Title; } if (item.Metadata.Copyright != null) { metaData.Copyright = item.Metadata.Copyright; } if (item.Metadata.Description != null) { metaData.Subject = item.Metadata.Description; } if (item.Metadata.Author != null) { List<String> author = new List<string>(); author.Add(item.Metadata.Author); metaData.Author = new ReadOnlyCollection<string>(author); } if (item.Metadata.Rating != null) { metaData.Rating = (int)item.Metadata.Rating.Value; } // rendertargetbitmap has to be executed on the UI thread // if it's run on a non-UI thread there will be a memory leak App.Current.Dispatcher.Invoke(() => { VideoGridImage gridImage = new VideoGridImage(item.Metadata as VideoMetadata, asyncState, thumbs); bitmap = gridImage.createGridImage(asyncState.MaxPreviewImageWidth); }); BitmapFrame frame = BitmapFrame.Create(bitmap, null, metaData, null); encoder.Frames.Add(frame); String outputFileName = Path.GetFileNameWithoutExtension(item.Location) + ".jpg"; outputFile = new FileStream(asyncState.OutputPath + "/" + outputFileName, FileMode.Create); encoder.QualityLevel = asyncState.JpegQuality; encoder.Save(outputFile); ItemProgressMax = nrFrames; ItemProgress = nrFrames; InfoMessages.Add("Finished video preview image: " + asyncState.OutputPath + "/" + outputFileName); } catch (Exception e) { InfoMessages.Add("Error creating video preview image for: " + item.Location + " " + e.Message); Logger.Log.Error("Error creating preview image for: " + item.Location, e); } finally { if (bitmap != null) { bitmap.Clear(); bitmap = null; } if (outputFile != null) { outputFile.Close(); outputFile.Dispose(); } mediaProbe.close(); // because of the extreme amount of memory used by rendertargetbitmap // make sure we have it all back before moving on to prevent out of memory spikes GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); } }