// Selects the next asset from the playlist, if temporal scheduling allows it and current date is within specified date bounds. // Decides if the next asset must be an advert or a content. // If the next asset is an advert and there is no advert available at this time, it attempts to select a content. // If no asset was found, a "no assets" asset is created. private ChannelAssetAssociation SelectAsset() { ChannelAssetAssociation channelAssetAssociation = null; if (!_bErrorOnSetup) { channelAssetAssociation = _playlistAssetPicker.SelectAsset(_totalDisplayTime, _totalAdvertDisplayTime, _protectedContentTime, _advertDisplayThreshold, Resources.NoAssets, "app://ContentExchanger"); if (channelAssetAssociation.PlaylistAsset.DisplayLength == -1F) { channelAssetAssociation.PlaylistAsset.DisplayLength = _defaultDisplayLength; } if (!_players.Exists(channelAssetAssociation.PlaylistAsset.PlayerType)) { _logger.WriteMessage(channelAssetAssociation.PlaylistAsset.PlayerType + " does not exist."); PlayerNotExistsResponse response = PlayerContainer.PlayerNotExistResponses[channelAssetAssociation.PlaylistAsset.PlayerType]; channelAssetAssociation = new ChannelAssetAssociation(0, new ContentPlaylistAsset(_displayMessageAssetDisplayLength, response.Message, response.Link)); } else { _logger.WriteMessage(channelAssetAssociation.PlaylistAsset.PlayerType + " exists."); } return(channelAssetAssociation); } channelAssetAssociation = _playlistAssetPicker.SelectAsset(_totalDisplayTime, _totalAdvertDisplayTime, _protectedContentTime, _advertDisplayThreshold, _displayMessage, _appToRun); return(channelAssetAssociation); }
/// <summary> /// Adds click log to log file /// </summary> /// <param name="ChannelAssetAssociation">the pair of channelID - asset for which to keep an click log</param> public void AddClickLog(ChannelAssetAssociation channelAssetAssociation) { // playlist asset can be null if screensaver has just started and no asset // had had the time to load yet. if (channelAssetAssociation == null) { return; } // declare the string builder as local to make it thread safe StringBuilder logSb = new StringBuilder(); DateTime now = DateTime.Now; logSb.Append(channelAssetAssociation.ChannelID); logSb.Append("|"); logSb.Append(channelAssetAssociation.PlaylistAsset.AssetID); logSb.Append("|"); logSb.Append(MakeDateToString(now)); logSb.Append("|"); logSb.Append(now.ToLongTimeString()); if (channelAssetAssociation.PlaylistAsset is AdvertPlaylistAsset) { LogEntriesRawSingleton.Instance.AdvertClickLogEntries.Add(logSb.ToString()); } else // content or "no assets" { LogEntriesRawSingleton.Instance.ContentClickLogEntries.Add(logSb.ToString()); } }
private void AddImpressionLog(ChannelAssetAssociation channelAssetAssociation) { // reminder: LogEntriesRawSingleton is thread safe. No need to lock again. if (_bLogImpressions || _bErrorOnSetup) { _logSingletonAccessor.AddImpressionLog(channelAssetAssociation); } }
/// <summary> /// Picks a random asset from the content exchanger-generated Playlist /// </summary> /// <param name="playlist">The content exchanger-generated Playlist</param> /// <param name="assetScheduler">Asset Scheduler object that determines which assets are temporally capable of being played</param> /// <returns>The information on the content playlist asset, null if no available asset found</returns> private ChannelAssetAssociation PickRandomContentPlaylistAsset() { // this counts the number of buckets we have already tried and have not found any content in. int noConsumedChannelBuckets = _consumedChannelBuckets.Count; _logger.WriteMessage("Attempted Channel Buckets: " + noConsumedChannelBuckets); // if user has not subscribed to any channels or if all channel buckets have been searched, return null // clear consumed buckets to search again on the next run if (_noChannelBuckets == 0 || _noChannelBuckets == noConsumedChannelBuckets) { _consumedChannelBuckets.Clear(); _consumedContentPlaylistAssets.Clear(); if (_noChannelBuckets > 0) { _logger.WriteMessage("All channel buckets searched. No content asset can be played at this time."); } else { _logger.WriteMessage("No channel buckets in playlist. No content asset can be played at this time."); } return(null); } ChannelBucket cb = GetRandomChannelBucket(_playlist); _logger.WriteMessage("channel bucket selected successfully"); ChannelAssetAssociation caa = GetRandomContentPlaylistAsset(cb); if (caa == null) { _consumedChannelBuckets.Add(cb); _logger.WriteMessage("no content in this channel was selected. Channel bucket will not be attempted again in this run. Attempting another channel bucket."); caa = PickRandomContentPlaylistAsset(); } else { _logger.WriteMessage("content asset selected: " + caa.PlaylistAsset.AssetID + " in channel: " + caa.ChannelID); } // at this point the algorithm has succeeded or has processed all buckets and assets and found no content available // clear consumed _consumedChannelBuckets.Clear(); _consumedContentPlaylistAssets.Clear(); // next pick will include content web assets if due to network/website unavailability those were excluded _bIncludeContentWebAssets = true; return(caa); // if this is null, there is no content asset available for playing }
private void LoadAsset(ChannelAssetAssociation channelAssetAssociation, IPlayer player) { PlaylistAsset playlistAsset = channelAssetAssociation.PlaylistAsset; AddPlayTimes(playlistAsset); _logger.WriteMessage("PlayerType: " + playlistAsset.PlayerType); if (player is IStreamLoader) { _logger.WriteMessage("Decrypting"); IStreamLoader streamLoader = (IStreamLoader)player; using ( MemoryStream stream = channelAssetAssociation.PlaylistAsset.DecryptAssetFile( _assetPath + channelAssetAssociation.PlaylistAsset.GetAssetFilenameGUIDSuffix() + "\\" + channelAssetAssociation.PlaylistAsset.AssetFilename, "password")) { //if (_count > 1) Thread.Sleep(5000); _logger.WriteMessage("Loading"); if (!_runScreenSaver) { _previousSlide.NewContentRequired(); return; } streamLoader.Load(stream); } } else if (player is IURLLoader) { IURLLoader urlLoader = (IURLLoader)player; urlLoader.Load(channelAssetAssociation.PlaylistAsset.AssetWebSite); } else if (player is IFileLoader) { _logger.WriteMessage("Decrypting"); // if (_count > 1) Thread.Sleep(15000); string decryptedFilePath = DecryptToTemp(channelAssetAssociation); _logger.WriteMessage("Decrypting Finished"); IFileLoader fileLoader = (IFileLoader)player; if (!_runScreenSaver) { File.Delete(decryptedFilePath); _previousSlide.NewContentRequired(); return; } fileLoader.Load(decryptedFilePath); _logger.WriteMessage("Finished loading"); } else if (player is INoAssetsLoader) { ((INoAssetsLoader)player).Load(((ContentPlaylistAsset)channelAssetAssociation.PlaylistAsset).Message); } }
public ChannelAssetAssociation SelectAsset(float totalDisplayTime, float totalAdvertDisplayTime, float protectedContentTime, float advertDisplayThreshold, string displayMessage, string appToRun) { ChannelAssetAssociation channelAssetAssociation = null; if (_bErrorOnSetup) { PlaylistAsset playlistAsset = new ContentPlaylistAsset(_displayMessageAssetDisplayLength, displayMessage, appToRun); _logger.WriteError("There was an error on initial setup; \"No Assets\" asset selected."); return(new ChannelAssetAssociation(0, playlistAsset)); } // is the next asset content or advert? _logger.WriteMessage("Deciding whether the next asset will be a content or an advert."); bool bIsNextAssetAdvert = IsNextAssetAdvert(totalDisplayTime, totalAdvertDisplayTime, protectedContentTime, advertDisplayThreshold); _logger.WriteMessage("will the next asset be an advert: " + bIsNextAssetAdvert); if (bIsNextAssetAdvert) { channelAssetAssociation = PickRandomAdvertPlaylistAsset(); } else { channelAssetAssociation = PickRandomContentPlaylistAsset(); } if (bIsNextAssetAdvert && channelAssetAssociation == null) { _logger.WriteMessage("Next asset is an advert but an advert could not be selected at this time. Attempting to select a content."); channelAssetAssociation = PickRandomContentPlaylistAsset(); if (channelAssetAssociation != null) { _logger.WriteMessage("playlist asset " + channelAssetAssociation.PlaylistAsset.AssetID + " was selected."); } } // if no asset was found, create a "No assets" asset if (channelAssetAssociation == null) { channelAssetAssociation = CreateNoAssetsChannelAssetAssociation(); _logger.WriteMessage("no asset was found, \"No Assets\" asset selected."); } return(channelAssetAssociation); }
private void SafelyReleaseAssetForTransition(ChannelAssetAssociation channelAssetAssociationAssetToHide, Dictionary <PlayerType, IPlayer> players) { var player = players[channelAssetAssociationAssetToHide.PlaylistAsset.PlayerType]; try { player.ReleaseAssetForTransition(); _logger.WriteTimestampedMessage("successfully deleted previous asset."); } //TODO: do we need this here?? catch (Exception ex) { _logger.WriteError(ex); } }
private string DecryptToTemp(ChannelAssetAssociation ca) { string assetTempPath = _tempDecryptPath + Guid.NewGuid() + Path.GetExtension(ca.PlaylistAsset.AssetFilename); MemoryStream ms = ca.PlaylistAsset.DecryptAssetFile(_assetPath + ca.PlaylistAsset.GetAssetFilenameGUIDSuffix() + "\\" + ca.PlaylistAsset.AssetFilename, "password"); FileStream fs = new FileStream(assetTempPath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None); ms.WriteTo(fs); ms.Dispose(); fs.Dispose(); return(assetTempPath); }
private void Transit(ChannelAssetAssociation channelAssetAssociationAssetToShow, ChannelAssetAssociation channelAssetAssociationAssetToHide, Dictionary <PlayerType, IPlayer> playersToShow, Dictionary <PlayerType, IPlayer> playersToHide) { if (channelAssetAssociationAssetToHide != null) { FadeToBlack(); playersToHide[channelAssetAssociationAssetToHide.PlaylistAsset.PlayerType].Stop(); AddImpressionLog(channelAssetAssociationAssetToHide); } IPlayer player = playersToShow[channelAssetAssociationAssetToShow.PlaylistAsset.PlayerType]; Controls.SetChildIndex(player.Control, 0); // Some players need to be refreshed before call to play so their display changes immediately player.Control.Refresh(); _logger.WriteMessage("Player " + channelAssetAssociationAssetToShow.PlaylistAsset.PlayerType + ", channelAssetAssociationAssetToShow.PlaylistAsset " + channelAssetAssociationAssetToShow.PlaylistAsset.AssetID + " index changed to 0."); player.Play(_bPrimaryMonitor); // Some players need to be refreshed after call to play so their display changes immediately player.Control.Refresh(); // release previously played streamed asset from player // and delete temp file if (channelAssetAssociationAssetToHide != null) { SafelyReleaseAssetForTransition(channelAssetAssociationAssetToHide, playersToHide); } _logger.WriteTimestampedMessage("successfully kept reference to asset that was just flipped on."); Thread.Sleep(_fadeSleep); _logSingletonAccessor.AssetImpressionStartDateTime = DateTime.Now; _assetDisplayLength = _currentSlide.ChannelAssetAssociation.PlaylistAsset.DisplayLength; // restart stopwatch after revealing appropriate control _stopwatch.Reset(); _stopwatch.Start(); _logger.WriteTimestampedMessage("Fading to transparency"); FadeToTransparantcy(); _logger.WriteTimestampedMessage("Faded to transparency"); }
private void SelectAndLoadAsset(object state) { _count++; try { CultureInfo ci = new CultureInfo("en-GB"); Thread.CurrentThread.CurrentCulture = ci; Thread.CurrentThread.CurrentUICulture = ci; ChannelAssetAssociation channelAssetAssociation = SelectAsset(); //if (_count > 1) Thread.Sleep(5000); if (!_runScreenSaver) { _previousSlide.NewContentRequired(); return; } _logger.WriteTimestampedMessage("successfully selected asset: " + channelAssetAssociation.PlaylistAsset.AssetID + " from channel " + channelAssetAssociation.ChannelID); _previousSlide.ChannelAssetAssociation = channelAssetAssociation; try { LoadAsset(channelAssetAssociation, _previousSlide.Players[channelAssetAssociation.PlaylistAsset.PlayerType]); } catch (IOException ex) { _logger.WriteError(ex + " -- Will select \"No Assets\"."); channelAssetAssociation = _playlistAssetPicker.CreateNoAssetsChannelAssetAssociation(); _previousSlide.ChannelAssetAssociation = channelAssetAssociation; LoadAsset(channelAssetAssociation, _previousSlide.Players[PlayerType.NoAssetsAnimator]); } _previousSlide.ReadyForDisplay(); } catch (Exception ex) { _logger.WriteError(ex + " - Primary monitor : " + _bPrimaryMonitor); _previousSlide.NewContentRequired(); } }
/// <summary> /// Adds an impression log entry for the last played asset. Calculates the time at invocation then subtracts to find the duration /// </summary> /// <param name="channelAssetAssociation">the pair of channelID - asset for which to keep an impression log</param> public void AddImpressionLog(ChannelAssetAssociation channelAssetAssociation) { // if this is a content asset check if it's premium content (error/no assets asset is premium content) if (channelAssetAssociation.PlaylistAsset is ContentPlaylistAsset && ((ContentPlaylistAsset)channelAssetAssociation.PlaylistAsset).AssetLevel != PlaylistAssetLevel.Premium) { return; } // playlist asset can be null if screensaver has just started and no asset // had had the time to load yet. if (channelAssetAssociation == null) { return; } // declare the string builder as local to make it thread safe StringBuilder logSb = new StringBuilder(); logSb.Append(channelAssetAssociation.ChannelID); logSb.Append("|"); logSb.Append(channelAssetAssociation.PlaylistAsset.AssetID); logSb.Append("|"); logSb.Append(MakeDateToString(_assetImpressionStartDateTime)); logSb.Append("|"); logSb.Append(_assetImpressionStartDateTime.ToLongTimeString()); logSb.Append("|"); logSb.Append(GetDurationInSeconds()); if (channelAssetAssociation.PlaylistAsset is AdvertPlaylistAsset) { LogEntriesRawSingleton.Instance.AdvertImpressionLogEntries.Add(logSb.ToString()); } else // premium content or error/no assets asset { LogEntriesRawSingleton.Instance.ContentImpressionLogEntries.Add(logSb.ToString()); } }