Пример #1
0
        // 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);
        }
Пример #2
0
        /// <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());
            }
        }
Пример #3
0
 private void AddImpressionLog(ChannelAssetAssociation channelAssetAssociation)
 {
     // reminder: LogEntriesRawSingleton is thread safe. No need to lock again.
     if (_bLogImpressions || _bErrorOnSetup)
     {
         _logSingletonAccessor.AddImpressionLog(channelAssetAssociation);
     }
 }
Пример #4
0
        /// <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
        }
Пример #5
0
        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);
            }
        }
Пример #6
0
        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);
        }
Пример #7
0
        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);
            }
        }
Пример #8
0
        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);
        }
Пример #9
0
        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");
        }
Пример #10
0
        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();
            }
        }
Пример #11
0
        /// <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());
            }
        }