void PlayAd(Advertisement ad, TimeSpan?syncToPosition)
 {
     HandledAds.Add(ad);
     PlayAdAsync(ad, cts.Token);
     if (syncToPosition.HasValue)
     {
         SyncMainContent(syncToPosition.Value);
     }
 }
 /// <summary>
 /// Called when the media has opened.
 /// Responsible for skipping ads before the startup position.
 /// </summary>
 protected virtual void OnMediaOpened()
 {
     // remove all ads before the start position
     if (MediaPlayer.StartupPosition.HasValue)
     {
         HandledAds.AddRange(Advertisements.OfType <PrerollAdvertisement>().Cast <Advertisement>());
         HandledAds.AddRange(Advertisements.OfType <MidrollAdvertisement>().Where(a => a.Time < MediaPlayer.StartupPosition.Value).Cast <Advertisement>());
     }
 }
        async Task PlayAdsOfType <T>(CancellationToken cancellationToken) where T : Advertisement
        {
            var adsToPlay = EligableAds.OfType <T>().Where(a => a.Source != null).ToList();

            HandledAds.AddRange(adsToPlay.Cast <Advertisement>());
            if (adsToPlay.Any())
            {
                await PlayAds(adsToPlay.Cast <Advertisement>(), cancellationToken);
            }
        }
        void MediaPlayer_MediaOpened(object sender, RoutedEventArgs e)
        {
            HandledAds.Clear();
            InitializeAdvertisements();

            OnMediaOpened();

            if (PreloadTime.HasValue)
            {
                // schedule the first postroll for preloading (x seconds before the duration)
                var postroll = Advertisements.FirstOrDefault(a => a is PostrollAdvertisement);
                if (postroll != null)
                {
                    MediaPlayer.Markers.Add(new TimelineMarker()
                    {
                        Type = MarkerType_Preload, Text = postroll.Id, Time = TimeSpanExtensions.Max(TimeSpan.FromMilliseconds(1), MediaPlayer.Duration.Subtract(PreloadTime.Value))
                    });                                                                                                                                                                                                             // clamp to 1 ms
                }
            }
        }
        internal async Task PlayStartupAds(CancellationToken c)
        {
            if (MediaPlayer.AllowMediaStartingDeferrals)
            {
                IList <Advertisement> startupAds;
                if (MediaPlayer.StartupPosition.HasValue)
                {
                    startupAds = EligableAds
                                 .OfType <MidrollAdvertisement>()
                                 .Where(a => a.Source != null && a.Time == MediaPlayer.StartupPosition.Value)
                                 .Cast <Advertisement>()
                                 .ToList();
                }
                else
                {
                    startupAds = EligableAds
                                 .OfType <PrerollAdvertisement>()
                                 .Where(a => a.Source != null)
                                 .Cast <Advertisement>()
                                 .ToList();
                }


                if (startupAds.Any())
                {
                    try
                    {
                        using (var adCts = CancellationTokenSource.CreateLinkedTokenSource(c, cts.Token))
                        {
                            HandledAds.AddRange(startupAds);
                            await PlayAds(startupAds, adCts.Token);
                        }
                    }
                    catch { /* ignore */ }
                }
            }
        }
 void MediaPlayer_MediaClosed(object sender, RoutedEventArgs e)
 {
     Advertisements.Clear();
     HandledAds.Clear();
 }