// // Copyright (C) 2008 Jordi Mas i Hernandez, jmas@softcatala.org // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using Gdk; using Mono.Unix; using Mistelix.Transitions; using Mistelix.Core; using Mistelix.DataModel; using Mistelix.Backends.GStreamer; namespace Mistelix.Core { // // Container for a slideshow and all its images // public class SlideShow : SlideShowProjectElement { public SlideShow () { } public string Generate (Project project, ProgressEventHandler progress) { int total_frames = 0; int frames_sec = project.Details.FramesPerSecond; ProgressEventArgs args = new ProgressEventArgs (); for (int i = 0; i < images.Count - 1; i++) { total_frames += (frames_sec * images[i].ShowTime) + (images[i].TransitionTime * frames_sec); ((SlideImage) images[i]).Project = project; } ((SlideImage) images[images.Count - 1]).Project = project; total_frames += frames_sec * images[images.Count - 1].ShowTime; args.Total = images.Count; Logger.Debug ("SlideShow.Generate. Generating MPEG for " + images.Count + " images " + "total frames " + total_frames + " at " + filename); string outfile; if (filename == null) outfile = GetOutputFile (project.Details.Type); else outfile = filename; Backends.GStreamer.SlideShow.CreateStream (project.FileToFullPath (outfile), project.Details.Type, (uint) project.Details.Width, (uint) project.Details.Height, (uint) frames_sec, (uint) total_frames); if (AudioFile != null) { Logger.Debug ("SlideShow.Generate. Audiofile {0}", AudioFile); Backends.GStreamer.SlideShow.AddAudio (AudioFile); } Transition transition; Logger.Debug ("SlideShow.Generate. Images.Count {0}", images.Count); // We need to make sure that source and target slides are loaded. Here we make sure that source is loaded ((SlideImage) images[0]).LoadSlide (); for (int i = 0; i < images.Count - 1; i++) { if (progress != null) { args.Progress = args.Progress + 1; progress (this, args); } Logger.Debug ("SlideShow.Generate. Send Fixed image {0}, time {1} (frames)", i, (uint) (frames_sec * images[i].ShowTime)); transition = TransitionManager.CreateFromName (images[i].Transition); Backends.GStreamer.SlideShow.AddImageFixed (((SlideImage)images[i]), (uint) (frames_sec * images[i].ShowTime)); // Transition between two images Logger.Debug ("SlideShow.Generate. Generate transition for frames_sec {0} and time {1}", frames_sec, images[i].TransitionTime); // We need to make sure that source and target slides are loaded. Here we make sure that target is loaded ((SlideImage) images[i + 1]).LoadSlide (); // Here we do target transition.Source = (SlideImage) images[i]; transition.Target = (SlideImage) images[i + 1]; transition.Frames = frames_sec * images[i].TransitionTime; foreach (SlideImage img in transition) Backends.GStreamer.SlideShow.AddImage (img); Logger.Debug ("Sending subimage completed"); ((SlideImage) images[i]).ReleasePixels (); } Logger.Debug ("SlideShow.Generate. Send fixed image time {0} (frames)", (uint) (frames_sec * images[images.Count -1].ShowTime)); Backends.GStreamer.SlideShow.AddImageFixed (((SlideImage)images[images.Count - 1]), (uint) (frames_sec * images[images.Count -1].ShowTime)); ((SlideImage) images[images.Count - 1]).ReleasePixels (); if (progress != null) { args.Progress = args.Progress + 1; progress (this, args); } // This a blocking call. It does not return until the pipeline sends an EOS Backends.GStreamer.SlideShow.Close (); Logger.Debug ("SlideShow.Generate. Finished generation"); return project.FileToFullPath (outfile); } public override ThumbnailCollection GetThumbnailRepresentations (int width, int height) { ThumbnailCollection collection = new ThumbnailCollection (); int idx = 0; foreach (SlideImage image in images) { ThumbnailCollection.ItemTask task = new ThumbnailCollection.ItemTask (image); task.ThumbnailIndex = idx++; task.DoEventHandler += delegate (object obj, EventArgs args) { ThumbnailCollection.ItemTask item = (ThumbnailCollection.ItemTask) obj; SlideImage img = (SlideImage) item.Data; Gdk.Pixbuf im = Backends.ThumbnailCache.Factory.Provider.GetThumbnail (img.image, width, height); if (im == null) im = new Gdk.Pixbuf (img.image); int max = Math.Max (im.Width, im.Height); Gdk.Pixbuf scaled = im.ScaleSimple (width * im.Width / max, height * im.Height / max, InterpType.Nearest); item.Pixbuf = scaled; im.Dispose (); }; collection.AddItem (task); } return collection; } // Check if the audio uses a supported format public bool AudioSupportedFormat (out string msg) { Dependencies dependencies; string format; format = Backends.GStreamer.DetectMedia.GetType (AudioFile); Logger.Debug ("SlideShow.SupportedFormat. Filename {0} is {1}", AudioFile, format); dependencies = new Dependencies (); if (String.Compare (format, "application/x-id3", StringComparison.OrdinalIgnoreCase) == 0) { if (dependencies.MP3Support == false) { msg = String.Format (Catalog.GetString ("The file '{0}' is encoded in MP3 but you do not have the right codec installed."), AudioFile); return false; } } msg = string.Empty; return true; } } }