/// <summary>
        /// Renders the shortcode contents to the writer.
        /// </summary>
        /// <param name="parms">The parameters that will be used to construct the content.</param>
        /// <param name="currentPerson">The current person.</param>
        /// <param name="result">The writer that output should be written to.</param>
        internal static void RenderToWriter(Dictionary <string, string> parms, Person currentPerson, TextWriter result)
        {
            var options = new MediaPlayerOptions
            {
                Autoplay            = parms[ParameterKeys.AutoPlay].AsBoolean(),
                Autopause           = parms[ParameterKeys.AutoPause].AsBoolean(true),
                ClickToPlay         = parms[ParameterKeys.ClickToPlay].AsBoolean(true),
                Controls            = parms[ParameterKeys.Controls],
                Debug               = parms[ParameterKeys.Debug].AsBoolean(),
                HideControls        = parms[ParameterKeys.HideControls].AsBoolean(true),
                MediaUrl            = parms[ParameterKeys.Source],
                Muted               = parms[ParameterKeys.Muted].AsBoolean(),
                PosterUrl           = parms[ParameterKeys.Thumbnail],
                RelatedEntityId     = parms[ParameterKeys.RelatedEntityId].AsIntegerOrNull(),
                RelatedEntityTypeId = parms[ParameterKeys.RelatedEntityTypeId].AsIntegerOrNull(),
                SeekTime            = parms[ParameterKeys.SeekTime].AsIntegerOrNull() ?? 10,
                TrackProgress       = true,
                Type             = parms[ParameterKeys.Type],
                Volume           = parms[ParameterKeys.Volume].AsDoubleOrNull() ?? 1.0,
                WriteInteraction = currentPerson != null
                    ? parms[ParameterKeys.TrackSession].AsBoolean(true)
                    : parms[ParameterKeys.TrackAnonymousSession].AsBoolean(true)
            };

            // Get the rest of the parameters in easy to access variables.
            var mediaId                     = parms[ParameterKeys.Media].AsIntegerOrNull();
            var mediaGuid                   = parms[ParameterKeys.Media].AsGuidOrNull();
            var autoResumeInDays            = parms[ParameterKeys.AutoResumeInDays].AsIntegerOrNull() ?? 7;
            var combinePlayStatisticsInDays = parms[ParameterKeys.CombinePlayStatisticsInDays].AsIntegerOrNull() ?? 7;
            var primaryColor                = parms[ParameterKeys.PrimaryColor];
            var width = parms[ParameterKeys.Width];

            options.UpdateValuesFromMedia(mediaId, mediaGuid, autoResumeInDays, combinePlayStatisticsInDays, currentPerson);

            var elementId = $"mediaplayer_{Guid.NewGuid()}";

            // Construct the CSS style for this media player.
            var style = $"--plyr-color-main: {( primaryColor.IsNotNullOrWhiteSpace() ? primaryColor : "var(--brand-primary)" )};";

            style += (width.IsNotNullOrWhiteSpace() ? $" width:{width}" : "");

            // Construct the JavaScript to initialize the player.
            var script = $@"<script>
(function() {{
    new Rock.UI.MediaPlayer(""#{elementId}"", {options.ToJson( indentOutput: false )});
}})();
</script>";

            result.WriteLine($"<div id=\"{elementId}\" style=\"{style}\"></div>");
            result.WriteLine(script);

            // If we have a RockPage related to the current request then
            // register all the JS and CSS links we need.
            if (HttpContext.Current != null && HttpContext.Current.Handler is System.Web.UI.Page page)
            {
                Rock.Web.UI.Controls.MediaPlayer.AddLinksForMediaToPage(options.MediaUrl, page);
            }
        }
Esempio n. 2
0
            internal static unsafe bool Invoke(IntPtr obj, MediaSource MediaSource, MediaPlayerOptions Options)
            {
                long *p = stackalloc long[] { 0L, 0L, 0L, 0L, 0L, 0L };
                byte *b = (byte *)p;

                *((IntPtr *)(b + 0))             = MediaSource;
                *((MediaPlayerOptions *)(b + 8)) = Options;
                Main.GetProcessEvent(obj, OpenSourceWithOptions_ptr, new IntPtr(p));;
                return(*((bool *)(b + 36)));
            }
        }
Esempio n. 3
0
 ///<summary>Open the specified media source with supplied options applied.</summary>
 ///<remarks>
 ///A return value of true indicates that the player will attempt to open
 ///the media, but it may fail to do so later for other reasons, i.e. if
 ///a connection to the media server timed out. Use the OnMediaOpened and
 ///OnMediaOpenFailed delegates to detect if and when the media is ready!
 ///
 ///@param MediaSource The media source to open.
 ///@param Options The media player options to apply.
 ///@return true if the source will be opened, false otherwise.
 ///@see Close, OpenFile, OpenPlaylist, OpenPlaylistIndex, OpenUrl, Reopen
 ///</remarks>
 public bool OpenSourceWithOptions(MediaSource MediaSource, MediaPlayerOptions Options) =>
 MediaPlayer_methods.OpenSourceWithOptions_method.Invoke(ObjPointer, MediaSource, Options);
        /// <summary>
        /// Updates the options from a <see cref="MediaElement"/>. If one is
        /// not found then no changes are made.
        /// </summary>
        /// <param name="options">The options to be updated.</param>
        /// <param name="mediaElementId">The media element identifier.</param>
        /// <param name="mediaElementGuid">The media element unique identifier.</param>
        /// <param name="autoResumeInDays">The number of days back to look for an existing watch map to auto-resume from. Pass -1 to mean forever or 0 to disable.</param>
        /// <param name="combinePlayStatisticsInDays">The number of days back to look for an existing interaction to be updated. Pass -1 to mean forever or 0 to disable.</param>
        /// <param name="currentPerson">The person to use when searching for existing interactions.</param>
        internal static void UpdateValuesFromMedia(this MediaPlayerOptions options, int?mediaElementId, Guid?mediaElementGuid, int autoResumeInDays, int combinePlayStatisticsInDays, Person currentPerson)
        {
            if (!mediaElementId.HasValue && !mediaElementGuid.HasValue)
            {
                return;
            }

            using (var rockContext = new RockContext())
            {
                var          mediaElementService    = new MediaElementService(rockContext);
                var          interactionService     = new InteractionService(rockContext);
                var          mediaEventsChannelGuid = Rock.SystemGuid.InteractionChannel.MEDIA_EVENTS.AsGuid();
                var          now          = RockDateTime.Now;
                MediaElement mediaElement = null;

                // Load the media element by either Id or Guid value.
                if (mediaElementId.HasValue)
                {
                    mediaElement = mediaElementService.Get(mediaElementId.Value);
                }
                else
                {
                    mediaElement = mediaElementService.Get(mediaElementGuid.Value);
                }

                // No media found means we don't have anything to do.
                if (mediaElement == null)
                {
                    return;
                }

                options.MediaUrl         = mediaElement.DefaultFileUrl;
                options.MediaElementGuid = mediaElement.Guid;

                // Let the users value override the default thumbnail.
                if (options.PosterUrl.IsNullOrWhiteSpace())
                {
                    options.PosterUrl = mediaElement.DefaultThumbnailUrl;
                }

                // Check if either autoResumeInDays or combinePlayStatisticsInDays
                // are enabled. If not we are done.
                if (autoResumeInDays == 0 && combinePlayStatisticsInDays == 0)
                {
                    return;
                }

                // If we don't have a person, then we can't get interactions.
                if (currentPerson == null)
                {
                    return;
                }

                // Build a query to find Interactions for this person having
                // previously watched this media element.
                var interactionQry = interactionService.Queryable()
                                     .Where(i => i.InteractionComponent.InteractionChannel.Guid == mediaEventsChannelGuid &&
                                            i.InteractionComponent.EntityId == mediaElement.Id &&
                                            i.PersonAlias.PersonId == currentPerson.Id);

                // A negative value means "forever".
                int daysBack = Math.Max(autoResumeInDays >= 0 ? autoResumeInDays : int.MaxValue,
                                        combinePlayStatisticsInDays >= 0 ? combinePlayStatisticsInDays : int.MaxValue);

                // A value of MaxValue means "forever" now so we don't need
                // to filter on it.
                if (daysBack != int.MaxValue)
                {
                    var limitDateTime = now.AddDays(-daysBack);

                    interactionQry = interactionQry.Where(i => i.InteractionDateTime >= limitDateTime);
                }

                // Look for the most recent Interaction.
                var interaction = interactionQry.OrderByDescending(i => i.InteractionDateTime)
                                  .Select(i => new
                {
                    i.Guid,
                    i.InteractionDateTime,
                    i.InteractionData
                })
                                  .FirstOrDefault();

                // If we didn't find any interaction then we are done.
                if (interaction == null)
                {
                    return;
                }

                // Check if this interaction is within our auto-resume window.
                if (autoResumeInDays != 0)
                {
                    if (autoResumeInDays < 0 || interaction.InteractionDateTime >= now.AddDays(-autoResumeInDays))
                    {
                        options.ResumePlaying = true;

                        var data = interaction.InteractionData.FromJsonOrNull <MediaWatchedInteractionData>();
                        options.Map = data?.WatchMap;
                    }
                }

                // Check if this interaction is within our combine window.
                if (combinePlayStatisticsInDays != 0)
                {
                    if (combinePlayStatisticsInDays < 0 || interaction.InteractionDateTime >= now.AddDays(-combinePlayStatisticsInDays))
                    {
                        options.InteractionGuid = interaction.Guid;
                    }
                }
            }
        }