private void Source_OpenOperationCompleted(MediaSource sender, MediaSourceOpenOperationCompletedEventArgs args) { // Get the MediaPlaybackItem that corresponds to the MediaSource. MediaPlaybackItem item = MediaPlaybackItem.FindFromMediaSource(sender); if (item != null && item.AudioTracks.Count > 0) { // The MediaPlaybackItem contains additional information about the underlying media. string audioCodec = item.AudioTracks[item.AudioTracks.SelectedIndex].GetEncodingProperties().Subtype; // We can read values from the MediaSource.CustomProperties. object customValue = null; sender.CustomProperties.TryGetValue("uri", out customValue); string uri = (string)customValue; customValue = null; sender.CustomProperties.TryGetValue("contentId", out customValue); string contentId = (string)customValue; logView.Log($"Opened Media Source with Uri: {uri}, ContentId: {contentId}, Codec: {audioCodec}", LogViewLoggingLevel.Information); // This extension method in MediaPlaybackItemStringExtensions dumps all the properties from all the tracks. var allProperties = item.ToFormattedString(); logView.Log($"MediaPlaybackItem nested properties: {allProperties}", LogViewLoggingLevel.Verbose); // The AdaptiveMediaSource can manage multiple video tracks internally, // but only a single video track is exposed in the MediaPlaybackItem, not a collection. } }
private void Source_OpenOperationCompleted(MediaSource sender, MediaSourceOpenOperationCompletedEventArgs args) { // Get the MediaPlaybackItem that corresponds to the MediaSource. MediaPlaybackItem item = MediaPlaybackItem.FindFromMediaSource(sender); if (item != null && item.AudioTracks.Count > 0) { // The MediaPlaybackItem contains additional information about the underlying media. string audioCodec = item.AudioTracks[item.AudioTracks.SelectedIndex].GetEncodingProperties().Subtype; // We can read values from the MediaSource.CustomProperties. var uri = (string)sender.CustomProperties["uri"]; var contentId = (Guid)sender.CustomProperties["contentId"]; Log($"Opened Media Source with Uri: {uri}, ContentId: {contentId}, Codec: {audioCodec}"); // This extension method in MediaPlaybackItemStringExtensions dumps all the properties from all the tracks. var allProperties = item.ToFormattedString(); Log(allProperties); // The AdaptiveMediaSource can manage multiple video tracks internally, // but only a single video track is exposed in the MediaPlaybackItem, not a collection. } }
private void CreateMediaBreaksForItem(MediaPlaybackItem item) { if (item != null) { // We have two ads that will be repeated. var redSkyUri = new Uri("http://az29176.vo.msecnd.net/videocontent/RedSky_FoxRiverWisc_GettyImagesRF-499617760_1080_HD_EN-US.mp4"); var flowersUri = new Uri("http://az29176.vo.msecnd.net/videocontent/CrocusTL_FramePoolRM_688-580-676_1080_HD_EN-US.mp4"); // One option is to create a separate MediaPlaybackItem for each of your ads. // You might choose to do this if each ad needs different reporting information. // Another option is to re-use MediaPlaybackItems in different MediaBreaks. // This scenario demonstrates both patterns. var ad1 = new MediaPlaybackItem(MediaSource.CreateFromUri(redSkyUri)); ad1.Source.CustomProperties["contentId"] = "Ad1_ID"; ad1.Source.CustomProperties["description"] = "Red Sky"; ad1.Source.CustomProperties["uri"] = redSkyUri.ToString(); RegisterForMediaSourceEvents(ad1.Source); RegisterForMediaPlaybackItemEvents(ad1); var ad2 = new MediaPlaybackItem(MediaSource.CreateFromUri(flowersUri)); ad2.Source.CustomProperties["contentId"] = "Ad2_ID"; ad2.Source.CustomProperties["description"] = "Flowers"; ad2.Source.CustomProperties["uri"] = flowersUri.ToString(); RegisterForMediaSourceEvents(ad2.Source); RegisterForMediaPlaybackItemEvents(ad2); var ad3 = new MediaPlaybackItem(MediaSource.CreateFromUri(redSkyUri)); ad3.Source.CustomProperties["contentId"] = "Ad3_ID"; ad3.Source.CustomProperties["description"] = "Red Sky 2"; ad3.Source.CustomProperties["uri"] = redSkyUri.ToString(); RegisterForMediaSourceEvents(ad3.Source); RegisterForMediaPlaybackItemEvents(ad3); // Create a PrerollBreak on your main content. if (item.BreakSchedule.PrerollBreak == null) { item.BreakSchedule.PrerollBreak = new MediaBreak(MediaBreakInsertionMethod.Interrupt); } // Add the ads to the PrerollBreak in the order you want them played item.BreakSchedule.PrerollBreak.PlaybackList.Items.Add(ad1); item.BreakSchedule.PrerollBreak.PlaybackList.Items.Add(ad2); // Add the ads to the MidRoll break at 10% into the main content. // To do this, we need to wait until the main MediaPlaybackItem is fully loaded by the player // so that we know its Duration. This will happen on MediaSource.OpenOperationCompleted. item.Source.OpenOperationCompleted += (sender, args) => { var attachedItem = MediaPlaybackItem.FindFromMediaSource(sender); if (sender.Duration.HasValue) { // For live streaming, the duration will be TimeSpan.MaxValue, which won't work for this scenario, // so we'll assume the total duration is 2 minutes for the purpose of ad insertion. bool isLiveMediaSource = item.Source.AdaptiveMediaSource != null ? item.Source.AdaptiveMediaSource.IsLive : false; long sourceDurationTicks = isLiveMediaSource ? TimeSpan.FromMinutes(2).Ticks : sender.Duration.Value.Ticks; var positionAt10PercentOfMainContent = TimeSpan.FromTicks(sourceDurationTicks / 10); // If the content is live, then the ad break replaces the streaming content. // If the content is not live, then the content pauses for the ad, and then resumes // after the ad is complete. MediaBreakInsertionMethod insertionMethod = isLiveMediaSource ? MediaBreakInsertionMethod.Replace : MediaBreakInsertionMethod.Interrupt; var midRollBreak = new MediaBreak(insertionMethod, positionAt10PercentOfMainContent); midRollBreak.PlaybackList.Items.Add(ad2); midRollBreak.PlaybackList.Items.Add(ad1); attachedItem.BreakSchedule.InsertMidrollBreak(midRollBreak); Log($"Added MidRoll at {positionAt10PercentOfMainContent}"); } }; // Create a PostrollBreak: // Note: for Live content, it will only play once the presentation transitions to VOD. if (item.BreakSchedule.PostrollBreak == null) { item.BreakSchedule.PostrollBreak = new MediaBreak(MediaBreakInsertionMethod.Interrupt); } // Add the ads to the PostrollBreak in the order you want them played item.BreakSchedule.PostrollBreak.PlaybackList.Items.Add(ad3); } }