/// <summary> /// Filter the contents of the existing tempdir using the specified /// difference threshold. Rewrite tempdir, metadata and differenceMetrics. /// </summary> /// <param name="threshold"></param> internal void Refilter(double threshold) { //Make an imageFilter instance and configure with the new threshold. ImageFilter.ImageFilter imgFilter = null; try { imgFilter = new ImageFilter.ImageFilter(); imgFilter.DifferenceThreshold = threshold; } catch { return; } Console.WriteLine("Refiltering framegrabs using threshold: " + threshold.ToString()); List <double> newDifferenceMetrics = new List <double>(); List <PresentationMgr.DataItem> newMetadata = new List <PresentationMgr.DataItem>(); RTUpdate rtu = new RTUpdate(); this.deckGuid = Guid.NewGuid(); rtu.DeckGuid = this.deckGuid; rtu.SlideSize = 1.0; rtu.DeckType = (Int32)DeckTypeEnum.Presentation; string filebase = "slide"; string extent = ".jpg"; int fileindex = 1; try { string newDir = Utility.GetTempDir(); Directory.CreateDirectory(newDir); string[] files = Directory.GetFiles(this.tempdir, "*.jpg"); Array.Sort(files, new PMPComparer()); string previous = null; for (int i = 0; i < files.Length; i++) { string file = files[i]; string msg; bool error = false; double metric; if (imgFilter.ImagesDiffer(previous, file, out msg, out error, out metric)) { string newFilename = filebase + fileindex.ToString() + extent; File.Copy(file, Path.Combine(newDir, newFilename)); rtu.SlideIndex = fileindex - 1; // This is a zero-based index newMetadata.Add(new PresentationMgr.DataItem(metadata[i].Timestamp, PresentationMgr.CopyRTUpdate(rtu))); newDifferenceMetrics.Add(metric); DateTime t = new DateTime(metadata[i].Timestamp); Console.WriteLine("Refilter keeping old index: " + (i + 1).ToString() + "; new index: " + fileindex.ToString() + "; difference: " + metric.ToString() + "; time: " + t.ToString()); fileindex++; previous = file; } } this.metadata = newMetadata; this.differenceMetrics = newDifferenceMetrics; Directory.Delete(this.tempdir, true); this.tempdir = newDir; } catch (Exception) { return; } }
/// <summary> /// Capture stills from the video stream. Create a temporary directory and save the images there. /// Compile a list of DataItem objects to indicate when the slide transitions should take place. /// </summary> /// <returns></returns> public string Process() { ImageFilter.ImageFilter imgFilter = null; try { imgFilter = new ImageFilter.ImageFilter(); imgFilter.DifferenceThreshold = this.differenceThreshold; } catch { this.errorLog.Append("Video capture images in the presentation will not be filtered probably " + "because ImageMagick is not available in the configuration.\r\n"); } this.differenceMetrics = new List <double>(); metadata = new List <PresentationMgr.DataItem>(); RTUpdate rtu = new RTUpdate(); this.deckGuid = Guid.NewGuid(); rtu.DeckGuid = this.deckGuid; rtu.SlideSize = 1.0; rtu.DeckType = (Int32)DeckTypeEnum.Presentation; this.videoStream = new StreamMgr(videoDescriptor.VideoCname, videoDescriptor.VideoName, new DateTime(this.start), new DateTime(this.end), false, PayloadType.dynamicVideo); this.videoStream.ToRawWMFile(this.progressTracker); MediaTypeVideoInfo mtvi = videoStream.GetUncompressedVideoMediaType(); this.tempdir = Utility.GetTempDir(); Directory.CreateDirectory(this.tempdir); string filebase = "slide"; string extent = ".jpg"; int fileindex = 1; BufferChunk bc; long time; bool newStream; string previousFile = null; this.stopNow = false; while ((!stopNow) && (videoStream.GetNextSample(out bc, out time, out newStream))) { if ((time - lastFramegrab) >= (long)(this.frameGrabIntervalMs * Constants.TicksPerMs)) { DateTime dt = new DateTime(time); Debug.WriteLine("time=" + dt.ToString() + ";length=" + bc.Length.ToString()); lastFramegrab = time; string filepath = Path.Combine(tempdir, filebase + fileindex.ToString() + extent); PixelFormat pixelFormat = subtypeToPixelFormat(mtvi.SubType); Bitmap bm = new Bitmap(mtvi.VideoInfo.BitmapInfo.Width, mtvi.VideoInfo.BitmapInfo.Height, pixelFormat); BitmapData bd = bm.LockBits(new Rectangle(0, 0, mtvi.VideoInfo.BitmapInfo.Width, mtvi.VideoInfo.BitmapInfo.Height), ImageLockMode.ReadWrite, pixelFormat); Marshal.Copy(bc.Buffer, 0, bd.Scan0, bc.Length); bm.UnlockBits(bd); bm.RotateFlip(RotateFlipType.RotateNoneFlipY); if ((SCALE) && (mtvi.VideoInfo.BitmapInfo.Width >= 1280)) { int w = mtvi.VideoInfo.BitmapInfo.Width / 2; int h = mtvi.VideoInfo.BitmapInfo.Height / 2; Bitmap scaled = new Bitmap(bm, new Size(w, h)); scaled.Save(filepath, ImageFormat.Jpeg); } else { bm.Save(filepath, ImageFormat.Jpeg); } if (imgFilter != null) { string filterMsg; bool filterError; double metric; bool differ = imgFilter.ImagesDiffer(filepath, previousFile, out filterMsg, out filterError, out metric); if (filterError) { //this.errorLog.Append(filterMsg); Console.WriteLine(filterMsg); } if (!differ) { continue; } this.differenceMetrics.Add(metric); Console.WriteLine("Framegrab slide index: " + fileindex.ToString() + "; difference: " + metric.ToString() + "; time: " + dt.ToString()); } rtu.SlideIndex = fileindex - 1; // This is a zero-based index metadata.Add(new PresentationMgr.DataItem(time - this.offset, PresentationMgr.CopyRTUpdate(rtu))); fileindex++; previousFile = filepath; } } return(null); }