/// <summary> /// Create the next media node based on the provided options /// </summary> /// <param name="options"></param> /// <returns></returns> private Media CreateNextMediaNode(RegionOptions options) { Media media; Trace.WriteLine(new LogMessage("Region - CreateNextMediaNode", string.Format("Creating new media: {0}, {1}", options.type, options.mediaid)), LogType.Audit.ToString()); if (options.render == "html") { media = new IeWebMedia(options); } else { // We've set our next media node in options already // this includes checking that file based media is valid. switch (options.type) { case "image": options.uri = ApplicationSettings.Default.LibraryPath + @"\" + options.uri; media = new ImagePosition(options); break; case "powerpoint": options.uri = ApplicationSettings.Default.LibraryPath + @"\" + options.uri; media = new PowerPoint(options); break; case "video": options.uri = ApplicationSettings.Default.LibraryPath + @"\" + options.uri; // Which video engine are we using? if (ApplicationSettings.Default.VideoRenderingEngine == "DirectShow") { media = new VideoDS(options); } else { media = new Video(options); } break; case "localvideo": // Which video engine are we using? if (ApplicationSettings.Default.VideoRenderingEngine == "DirectShow") { media = new VideoDS(options); } else { media = new Video(options); } break; case "audio": options.uri = ApplicationSettings.Default.LibraryPath + @"\" + options.uri; media = new Audio(options); break; case "datasetview": case "embedded": case "ticker": case "text": case "webpage": media = new IeWebMedia(options); break; case "flash": options.uri = ApplicationSettings.Default.LibraryPath + @"\" + options.uri; media = new Flash(options); break; case "shellcommand": media = new ShellCommand(options); break; default: throw new InvalidOperationException("Not a valid media node type: " + options.type); } } // Sets up the timer for this media, if it hasn't already been set if (media.Duration == 0) { media.Duration = options.duration; } // Add event handler for when this completes media.DurationElapsedEvent += new Media.DurationElapsedDelegate(media_DurationElapsedEvent); return(media); }
/// <summary> /// Parse options for the media node /// </summary> /// <param name="mediaNode"></param> /// <param name="nodeAttributes"></param> private void ParseOptionsForMediaNode(XmlNode mediaNode, XmlAttributeCollection nodeAttributes) { // New version has a different schema - the right way to do it would be to pass the <options> and <raw> nodes to // the relevant media class - however I dont feel like engineering such a change so the alternative is to // parse all the possible media type nodes here. // Type and Duration will always be on the media node _options.type = nodeAttributes["type"].Value; // Render as if (nodeAttributes["render"] != null) { _options.render = nodeAttributes["render"].Value; } //TODO: Check the type of node we have, and make sure it is supported. if (nodeAttributes["duration"].Value != "") { _options.duration = int.Parse(nodeAttributes["duration"].Value); } else { _options.duration = 60; Trace.WriteLine("Duration is Empty, using a default of 60.", "Region - SetNextMediaNode"); } // We cannot have a 0 duration here... not sure why we would... but if (_options.duration == 0 && _options.type != "video" && _options.type != "localvideo") { int emptyLayoutDuration = int.Parse(ApplicationSettings.Default.EmptyLayoutDuration.ToString()); _options.duration = (emptyLayoutDuration == 0) ? 10 : emptyLayoutDuration; } // There will be some stuff on option nodes XmlNode optionNode = mediaNode.SelectSingleNode("options"); // Track if an update interval has been provided in the XLF bool updateIntervalProvided = false; // Loop through each option node foreach (XmlNode option in optionNode.ChildNodes) { if (option.Name == "direction") { _options.direction = option.InnerText; } else if (option.Name == "uri") { _options.uri = option.InnerText; } else if (option.Name == "copyright") { _options.copyrightNotice = option.InnerText; } else if (option.Name == "scrollSpeed") { try { _options.scrollSpeed = int.Parse(option.InnerText); } catch { System.Diagnostics.Trace.WriteLine("Non integer scrollSpeed in XLF", "Region - SetNextMediaNode"); } } else if (option.Name == "updateInterval") { updateIntervalProvided = true; try { _options.updateInterval = int.Parse(option.InnerText); } catch { // Update interval not defined, so assume a high value _options.updateInterval = 3600; Trace.WriteLine("Non integer updateInterval in XLF", "Region - SetNextMediaNode"); } } // Add this to the options object _options.Dictionary.Add(option.Name, option.InnerText); } // And some stuff on Raw nodes XmlNode rawNode = mediaNode.SelectSingleNode("raw"); if (rawNode != null) { foreach (XmlNode raw in rawNode.ChildNodes) { if (raw.Name == "text") { _options.text = raw.InnerText; } else if (raw.Name == "template") { _options.documentTemplate = raw.InnerText; } else if (raw.Name == "embedHtml") { _options.text = raw.InnerText; } else if (raw.Name == "embedScript") { _options.javaScript = raw.InnerText; } } } // Audio Nodes? XmlNode audio = mediaNode.SelectSingleNode("audio"); if (audio != null) { foreach (XmlNode audioNode in audio.ChildNodes) { RegionOptions options = new RegionOptions(); options.Dictionary = new MediaDictionary(); options.duration = 0; options.uri = ApplicationSettings.Default.LibraryPath + @"\" + audioNode.InnerText; if (audioNode.Attributes["loop"] != null) { options.Dictionary.Add("loop", audioNode.Attributes["loop"].Value); if (options.Dictionary.Get("loop", 0) == 1) { // Set the media duration to be equal to the duration of the parent media options.duration = (_options.duration == 0) ? int.MaxValue : _options.duration; } } if (audioNode.Attributes["volume"] != null) { options.Dictionary.Add("volume", audioNode.Attributes["volume"].Value); } Media audioMedia = new Audio(options); // Bind to the media complete event audioMedia.DurationElapsedEvent += audio_DurationElapsedEvent; _options.Audio.Add(audioMedia); } } // Media Types without an update interval should have a sensible default (xibosignage/xibo#404) // This means that items which do not provide an update interval will still refresh. if (!updateIntervalProvided) { // Special handling for text/webpages because we know they should never have a default update interval applied if (_options.type == "webpage" || _options.type == "text") { // Very high (will expire eventually, but shouldn't cause a routine request for a new resource _options.updateInterval = int.MaxValue; } else { // Default to 5 minutes for those items that do not provide an update interval _options.updateInterval = 5; } } }