//<SnippetDataCueEntered> private void MetadataTrack_DataCueEntered(TimedMetadataTrack sender, MediaCueEventArgs args) { DataCue cue = (DataCue)args.Cue; string data = System.Text.Encoding.Unicode.GetString(cue.Data.ToArray()); System.Diagnostics.Debug.WriteLine("Cue entered: " + data); }
private void metadata_id3_CueEntered(TimedMetadataTrack timedMetadataTrack, MediaCueEventArgs args) { StringBuilder logMsg = new StringBuilder(); object customValue = null; timedMetadataTrack.PlaybackItem.Source.CustomProperties.TryGetValue("contentId", out customValue); string contentId = (string)customValue; logMsg.AppendLine($"{contentId} ID3 DataCue CueEntered raised."); var dataCue = args.Cue as DataCue; if (dataCue != null && dataCue.Data != null && dataCue.Data.Length >= 10) { // The payload is the raw ID3 bytes found in a TS stream // Ref: http://id3.org/id3v2.4.0-structure var dr = DataReader.FromBuffer(dataCue.Data); var header_ID3 = dr.ReadString(3); var header_version_major = dr.ReadByte(); var header_version_minor = dr.ReadByte(); var header_flags = dr.ReadByte(); var header_tagSize = dr.ReadUInt32(); // TODO: Use the ID3 bytes for something useful. logMsg.AppendLine($"Label: {timedMetadataTrack.Label}, Id: {dataCue.Id}, StartTime: {dataCue.StartTime}, Duration: {dataCue.Duration}"); logMsg.Append($"{header_ID3}, {header_version_major}.{header_version_minor}, {header_flags}, {header_tagSize}"); } Log(logMsg.ToString()); }
private void TimedText_CueEntered(TimedMetadataTrack sender, MediaCueEventArgs args) { Debug.WriteLine("Cue Entered"); Debug.WriteLine("Cue start time was " + args.Cue.StartTime + " " + args.Cue.Duration); start += args.Cue.StartTime; args.Cue.StartTime = start; Debug.WriteLine("Cue start time is " + args.Cue.StartTime + " " + args.Cue.Duration); }
private void MetadataTrack_DataCueEntered(TimedMetadataTrack sender, MediaCueEventArgs args) { var playbackList = _mediaPlayer.Source as MediaPlaybackList; DataCue cue = (DataCue)args.Cue; OnPlaybackCueTriggered(new PlaybackCueTriggeredEventArgs() { Segment = (int)playbackList.CurrentItemIndex, EventId = Convert.ToInt32(cue.Id), Time = cue.StartTime }); }
/// <summary> /// This function executes when a SpeechCue is hit and calls then <see cref="EhSpeechProgress(int)"/> in UI context. /// </summary> /// <param name="timedMetadataTrack">The timedMetadataTrack associated with the event.</param> /// <param name="args">the arguments associated with the event.</param> private async void EhCueReceived(TimedMetadataTrack timedMetadataTrack, MediaCueEventArgs args) { // Check in case there are different tracks and the handler was used for more tracks if (timedMetadataTrack.TimedMetadataKind == TimedMetadataKind.Speech) { var cue = args.Cue as SpeechCue; if (cue != null) { // System.Diagnostics.Debug.WriteLine($"Cue text:[{cue.Text}], Access={Dispatcher.CheckAccess()}"); Dispatcher.BeginInvoke( new Action <int>(EhSpeechProgress), DispatcherPriority.Background, cue.StartPositionInInput ); } } }
// </SnippetRegisterMetadataHandlerForID3Cues> // <SnippetID3CueEntered> private void metadata_ID3CueEntered(TimedMetadataTrack timedMetadataTrack, MediaCueEventArgs args) { var dataCue = args.Cue as DataCue; if (dataCue != null && dataCue.Data != null) { // The payload is the raw ID3 bytes found in a TS stream // Ref: http://id3.org/id3v2.4.0-structure var dr = Windows.Storage.Streams.DataReader.FromBuffer(dataCue.Data); var header_ID3 = dr.ReadString(3); var header_version_major = dr.ReadByte(); var header_version_minor = dr.ReadByte(); var header_flags = dr.ReadByte(); var header_tagSize = dr.ReadUInt32(); System.Diagnostics.Debug.WriteLine($"ID3 tag data: major {header_version_major}, minor: {header_version_minor}"); } }
//<SnippetTextCueEntered> private void MetadataTrack_TextCueEntered(TimedMetadataTrack sender, MediaCueEventArgs args) { TimedTextCue cue = (TimedTextCue)args.Cue; System.Diagnostics.Debug.WriteLine("Cue entered: " + cue.Id + " " + cue.Lines[0].Text); }
/// <summary> /// This function executes when a SpeechCue is hit and calls the functions to update the UI /// </summary> /// <param name="timedMetadataTrack">The timedMetadataTrack associated with the event.</param> /// <param name="args">the arguments associated with the event.</param> private async void metadata_MarkCueEntered(TimedMetadataTrack timedMetadataTrack, MediaCueEventArgs args) { // Check in case there are different tracks and the handler was used for more tracks if (timedMetadataTrack.TimedMetadataKind == TimedMetadataKind.Speech) { var cue = args.Cue as SpeechCue; if (cue != null) { System.Diagnostics.Debug.WriteLine("Cue text:[" + cue.Text + "]"); // Do something with the cue await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { // Your UI update code goes here! FillTextBox(cue); }); } } }
private void MetadataTrack_CueExited(TimedMetadataTrack sender, MediaCueEventArgs args) { }
// <SnippetLastProcessedAdId> // <SnippetEmsgCueEntered> private void metadata_EmsgCueEntered(TimedMetadataTrack timedMetadataTrack, MediaCueEventArgs args) { var dataCue = args.Cue as DataCue; if (dataCue != null) { string scheme_id_uri = string.Empty; string value = string.Empty; UInt32 timescale = (UInt32)TimeSpan.TicksPerSecond; UInt32 presentation_time_delta = (UInt32)dataCue.StartTime.Ticks; UInt32 event_duration = (UInt32)dataCue.Duration.Ticks; UInt32 id = 0; Byte[] message_data = null; const string scheme_id_uri_key = "emsg:scheme_id_uri"; object propValue = null; dataCue.Properties.TryGetValue(scheme_id_uri_key, out propValue); scheme_id_uri = propValue != null ? (string)propValue : ""; const string value_key = "emsg:value"; propValue = null; dataCue.Properties.TryGetValue(value_key, out propValue); value = propValue != null ? (string)propValue : ""; const string timescale_key = "emsg:timescale"; propValue = null; dataCue.Properties.TryGetValue(timescale_key, out propValue); timescale = propValue != null ? (UInt32)propValue : timescale; const string presentation_time_delta_key = "emsg:presentation_time_delta"; propValue = null; dataCue.Properties.TryGetValue(presentation_time_delta_key, out propValue); presentation_time_delta = propValue != null ? (UInt32)propValue : presentation_time_delta; const string event_duration_key = "emsg:event_duration"; propValue = null; dataCue.Properties.TryGetValue(event_duration_key, out propValue); event_duration = propValue != null ? (UInt32)propValue : event_duration; const string id_key = "emsg:id"; propValue = null; dataCue.Properties.TryGetValue(id_key, out propValue); id = propValue != null ? (UInt32)propValue : 0; System.Diagnostics.Debug.WriteLine($"Label: {timedMetadataTrack.Label}, Id: {dataCue.Id}, StartTime: {dataCue.StartTime}, Duration: {dataCue.Duration}"); System.Diagnostics.Debug.WriteLine($"scheme_id_uri: {scheme_id_uri}, value: {value}, timescale: {timescale}, presentation_time_delta: {presentation_time_delta}, event_duration: {event_duration}, id: {id}"); if (dataCue.Data != null) { var dr = Windows.Storage.Streams.DataReader.FromBuffer(dataCue.Data); // Check if this is a SCTE ad message: // Ref: http://dashif.org/identifiers/event-schemes/ if (scheme_id_uri.ToLower() == "urn:scte:scte35:2013:xml") { // SCTE recommends publishing emsg more than once, so we avoid reprocessing the same message id: if (!processedAdIds.Contains(id)) { processedAdIds.Add(id); dr.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8; var scte35payload = dr.ReadString(dataCue.Data.Length); System.Diagnostics.Debug.WriteLine($", message_data: {scte35payload}"); // TODO: ScheduleAdFromScte35Payload(timedMetadataTrack, presentation_time_delta, timescale, event_duration, scte35payload); } else { System.Diagnostics.Debug.WriteLine($"This emsg.Id, {id}, has already been processed."); } } else { message_data = new byte[dataCue.Data.Length]; dr.ReadBytes(message_data); // TODO: Use the 'emsg' bytes for something useful. System.Diagnostics.Debug.WriteLine($", message_data.Length: {message_data.Length}"); } } } }
// </SnippetRegisterMetadataHandlerForEXTM3UCues> // <SnippetEXTM3UCueEntered> private void metadata_EXTM3UCueEntered(TimedMetadataTrack timedMetadataTrack, MediaCueEventArgs args) { var dataCue = args.Cue as DataCue; if (dataCue != null && dataCue.Data != null) { // The payload is a UTF-16 Little Endian null-terminated string. // It is any comment line in a manifest that is not part of the HLS spec. var dr = Windows.Storage.Streams.DataReader.FromBuffer(dataCue.Data); dr.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf16LE; var m3uComment = dr.ReadString(dataCue.Data.Length / 2 - 1); System.Diagnostics.Debug.WriteLine(m3uComment); } }
// </SnippetImageSubtitleCueEntered> private void metadata_ImageSubtitleCueExited(TimedMetadataTrack timedMetadataTrack, MediaCueEventArgs args) { }
/// <summary> /// This function executes when a SpeechCue is hit and calls the functions to update the UI /// </summary> /// <param name="timedMetadataTrack">The timedMetadataTrack associated with the event.</param> /// <param name="args">the arguments associated with the event.</param> private async void metadata_SpeechCueEntered(TimedMetadataTrack timedMetadataTrack, MediaCueEventArgs args) { // Check in case there are different tracks and the handler was used for more tracks if (timedMetadataTrack.TimedMetadataKind == TimedMetadataKind.Speech) { var cue = args.Cue as SpeechCue; if (cue != null) { SpeakProgress?.Invoke((int)cue.StartPositionInInput, (int)cue.EndPositionInInput - (int)cue.StartPositionInInput + 1); } } }
/// <summary> /// This function executes when a SpeechCue is hit and calls the functions to update the UI /// </summary> /// <param name="timedMetadataTrack">The timedMetadataTrack associated with the event.</param> /// <param name="args">the arguments associated with the event.</param> private async void metadata_SpeechCueEntered(TimedMetadataTrack timedMetadataTrack, MediaCueEventArgs args) { // Check in case there are different tracks and the handler was used for more tracks if (timedMetadataTrack.TimedMetadataKind == TimedMetadataKind.Speech) { var cue = args.Cue as SpeechCue; if (cue != null) { System.Diagnostics.Debug.WriteLine("Hit Cue with start:" + cue.StartPositionInInput + " and end:" + cue.EndPositionInInput); System.Diagnostics.Debug.WriteLine("Cue text:[" + cue.Text + "]"); // Do something with the cue await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { // Your UI update code goes here! HighlightTextOnScreen(cue.StartPositionInInput, cue.EndPositionInInput); FillTextBoxes(cue, timedMetadataTrack); }); } } }
private void metadata_TrackingEvents_CueExited(TimedMetadataTrack timedMetadataTrack, MediaCueEventArgs args) { StringBuilder logMsg = new StringBuilder(); var contentId = (Guid)timedMetadataTrack.PlaybackItem.Source.CustomProperties["contentId"]; logMsg.AppendLine($"{contentId} TrackingEventCue CueExited raised."); var trackingEventCue = args.Cue as TrackingEventCue; if (trackingEventCue != null) { logMsg.AppendLine($"Label: {timedMetadataTrack.Label}, Id: {trackingEventCue.Id}, StartTime: {trackingEventCue.StartTime}, Duration: {trackingEventCue.Duration}"); logMsg.Append($"{trackingEventCue.TrackingEventUri}"); } Log(logMsg.ToString()); }
private void metadata_id3_CueEntered(TimedMetadataTrack timedMetadataTrack, MediaCueEventArgs args) { StringBuilder logMsg = new StringBuilder(); var contentId = (Guid)timedMetadataTrack.PlaybackItem.Source.CustomProperties["contentId"]; logMsg.AppendLine($"{contentId} ID3 DataCue CueEntered raised."); var dataCue = args.Cue as DataCue; if (dataCue != null && dataCue.Data != null && dataCue.Data.Length >= 10) { // The payload is the raw ID3 bytes found in a TS stream // Ref: http://id3.org/id3v2.4.0-structure var dr = DataReader.FromBuffer(dataCue.Data); var header_ID3 = dr.ReadString(3); var header_version_major = dr.ReadByte(); var header_version_minor = dr.ReadByte(); var header_flags = dr.ReadByte(); var header_tagSize = dr.ReadUInt32(); // TODO: Use the ID3 bytes. logMsg.AppendLine($"Label: {timedMetadataTrack.Label}, Id: {dataCue.Id}, StartTime: {dataCue.StartTime}, Duration: {dataCue.Duration}"); logMsg.Append($"{header_ID3}, {header_version_major}.{header_version_minor}, {header_flags}, {header_tagSize}"); } Log(logMsg.ToString()); }
private void metadata_extm3u_CueEntered(TimedMetadataTrack timedMetadataTrack, MediaCueEventArgs args) { StringBuilder logMsg = new StringBuilder(); var contentId = (Guid)timedMetadataTrack.PlaybackItem.Source.CustomProperties["contentId"]; logMsg.AppendLine($"{contentId} M3U8 DataCue CueEntered raised."); var dataCue = args.Cue as DataCue; if (dataCue != null && dataCue.Data != null) { // The payload is a UTF-16 Little Endian null-terminated string. // It is any comment line in a manifest that is not part of the HLS spec. var dr = DataReader.FromBuffer(dataCue.Data); dr.UnicodeEncoding = UnicodeEncoding.Utf16LE; var m3u8Comment = dr.ReadString(dataCue.Data.Length / 2 - 1); logMsg.AppendLine($"Label: {timedMetadataTrack.Label}, Id: {dataCue.Id}, StartTime: {dataCue.StartTime}, Duration: {dataCue.Duration}"); logMsg.Append(m3u8Comment); // TODO: Use the m3u8Comment string. } Log(logMsg.ToString()); }
private void metadata_TrackingEvents_CueEntered(TimedMetadataTrack timedMetadataTrack, MediaCueEventArgs args) { StringBuilder logMsg = new StringBuilder(); var contentId = (Guid)timedMetadataTrack.PlaybackItem.Source.CustomProperties["contentId"]; logMsg.AppendLine($"{contentId} TrackingEventCue CueEntered raised."); var trackingEventCue = args.Cue as TrackingEventCue; if (trackingEventCue != null) { logMsg.AppendLine($"Label: {timedMetadataTrack.Label}, Id: {trackingEventCue.Id}, StartTime: {trackingEventCue.StartTime}, Duration: {trackingEventCue.Duration}"); logMsg.Append($"{trackingEventCue.TrackingEventUri}"); // TODO: Use the reporing Uri. } Log(logMsg.ToString()); }
// </SnippetRegisterMetadataHandlerForWords> // <SnippetSpeechWordCueEntered> private void metadata_SpeechCueEntered(TimedMetadataTrack timedMetadataTrack, MediaCueEventArgs args) { // Check in case there are different tracks and the handler was used for more tracks if (timedMetadataTrack.TimedMetadataKind == TimedMetadataKind.Speech) { var cue = args.Cue as SpeechCue; if (cue != null) { if (timedMetadataTrack.Label == "SpeechWord") { // Do something with the cue System.Diagnostics.Debug.WriteLine($"{cue.StartPositionInInput} - {cue.EndPositionInInput}: {inputText.Substring((int)cue.StartPositionInInput, ((int)cue.EndPositionInInput - (int)cue.StartPositionInInput) + 1)}"); } } } }
// </SnippetRegisterMetadataHandlerForImageSubtitles> // <SnippetImageSubtitleCueEntered> private async void metadata_ImageSubtitleCueEntered(TimedMetadataTrack timedMetadataTrack, MediaCueEventArgs args) { // Check in case there are different tracks and the handler was used for more tracks if (timedMetadataTrack.TimedMetadataKind == TimedMetadataKind.ImageSubtitle) { var cue = args.Cue as ImageCue; if (cue != null) { await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async() => { var source = new SoftwareBitmapSource(); await source.SetBitmapAsync(cue.SoftwareBitmap); SubtitleImage.Source = source; SubtitleImage.Width = cue.Extent.Width; SubtitleImage.Height = cue.Extent.Height; SubtitleImage.SetValue(Canvas.LeftProperty, cue.Position.X); SubtitleImage.SetValue(Canvas.TopProperty, cue.Position.Y); }); } } }
private void metadata_extm3u_CueEntered(TimedMetadataTrack timedMetadataTrack, MediaCueEventArgs args) { StringBuilder logMsg = new StringBuilder(); object customValue = null; timedMetadataTrack.PlaybackItem.Source.CustomProperties.TryGetValue("contentId", out customValue); string contentId = (string)customValue; logMsg.AppendLine($"{contentId} M3U8 DataCue CueEntered raised."); var dataCue = args.Cue as DataCue; if (dataCue != null && dataCue.Data != null) { // The payload is a UTF-16 Little Endian null-terminated string. // It is any comment line in a manifest that is not part of the HLS spec. var dr = DataReader.FromBuffer(dataCue.Data); dr.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf16LE; var m3u8Comment = dr.ReadString(dataCue.Data.Length / 2 - 1); logMsg.AppendLine($"Label: {timedMetadataTrack.Label}, Id: {dataCue.Id}, StartTime: {dataCue.StartTime}, Duration: {dataCue.Duration}"); logMsg.Append(m3u8Comment); // TODO: Use the m3u8Comment string for something useful. } Log(logMsg.ToString()); }
// </SnippetRegisterMetadataHandlerForChapterCues> // <SnippetChapterCueEntered> private async void metadata_ChapterCueEntered(TimedMetadataTrack timedMetadataTrack, MediaCueEventArgs args) { // Check in case there are different tracks and the handler was used for more tracks if (timedMetadataTrack.TimedMetadataKind == TimedMetadataKind.Chapter) { var cue = args.Cue as ChapterCue; if (cue != null) { await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { ChapterTitleTextBlock.Text = cue.Title; }); } } }
private void TimedText_CueExited(TimedMetadataTrack sender, MediaCueEventArgs args) { Debug.WriteLine("Cue Exited"); }
private void metadata_emsg_mp4_CueEntered(TimedMetadataTrack timedMetadataTrack, MediaCueEventArgs args) { StringBuilder logMsg = new StringBuilder(); object customValue = null; timedMetadataTrack.PlaybackItem.Source.CustomProperties.TryGetValue("contentId", out customValue); string contentId = (string)customValue; logMsg.AppendLine($"{contentId} mp4 emsg DataCue CueEntered raised."); var dataCue = args.Cue as DataCue; if (dataCue != null) { // Ref: ISO/IEC 20009-1, Section 5.10.3.3.2 Definition of Box Type: 'emsg' string scheme_id_uri = string.Empty; string value = string.Empty; UInt32 timescale = (UInt32)TimeSpan.TicksPerSecond; UInt32 presentation_time_delta = (UInt32)dataCue.StartTime.Ticks; UInt32 event_duration = (UInt32)dataCue.Duration.Ticks; UInt32 id = 0; Byte[] message_data = null; const string scheme_id_uri_key = "emsg:scheme_id_uri"; object propValue = null; dataCue.Properties.TryGetValue(scheme_id_uri_key, out propValue); scheme_id_uri = propValue != null ? (string)propValue : ""; const string value_key = "emsg:value"; propValue = null; dataCue.Properties.TryGetValue(value_key, out propValue); value = propValue != null ? (string)propValue : ""; const string timescale_key = "emsg:timescale"; propValue = null; dataCue.Properties.TryGetValue(timescale_key, out propValue); timescale = propValue != null ? (UInt32)propValue : timescale; const string presentation_time_delta_key = "emsg:presentation_time_delta"; propValue = null; dataCue.Properties.TryGetValue(presentation_time_delta_key, out propValue); presentation_time_delta = propValue != null ? (UInt32)propValue : presentation_time_delta; const string event_duration_key = "emsg:event_duration"; propValue = null; dataCue.Properties.TryGetValue(event_duration_key, out propValue); event_duration = propValue != null ? (UInt32)propValue : event_duration; const string id_key = "emsg:id"; propValue = null; dataCue.Properties.TryGetValue(id_key, out propValue); id = propValue != null ? (UInt32)propValue : 0; logMsg.AppendLine($"Label: {timedMetadataTrack.Label}, Id: {dataCue.Id}, StartTime: {dataCue.StartTime}, Duration: {dataCue.Duration}"); logMsg.Append($"scheme_id_uri: {scheme_id_uri}, value: {value}, timescale: {timescale}, presentation_time_delta: {presentation_time_delta}, event_duration: {event_duration}, id: {id}"); if (dataCue.Data != null) { var dr = DataReader.FromBuffer(dataCue.Data); // Check if this is a SCTE ad message: // Ref: http://dashif.org/identifiers/event-schemes/ if (scheme_id_uri.ToLower() == "urn:scte:scte35:2013:xml") { // SCTE recommends publishing emsg more than once, so we avoid reprocessing the same message id: if (lastProcessedAdId != id) { lastProcessedAdId = id; // TODO: Requires robustness. Messages may be out of order, which would break this sample's logic. dr.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8; var scte35payload = dr.ReadString(dataCue.Data.Length); logMsg.Append($", message_data: {scte35payload}"); ScheduleAdFromScte35Payload(timedMetadataTrack, presentation_time_delta, timescale, event_duration, scte35payload); } else { logMsg.AppendLine($"This emsg.Id, {id}, has already been processed."); } } else { message_data = new byte[dataCue.Data.Length]; dr.ReadBytes(message_data); // TODO: Use the 'emsg' bytes for something useful. logMsg.Append($", message_data.Length: {message_data.Length}"); } } } Log(logMsg.ToString()); }
private void metadata_TrackingEvents_CueExited(TimedMetadataTrack timedMetadataTrack, MediaCueEventArgs args) { StringBuilder logMsg = new StringBuilder(); object customValue = null; timedMetadataTrack.PlaybackItem.Source.CustomProperties.TryGetValue("contentId", out customValue); string contentId = (string)customValue; logMsg.AppendLine($"{contentId} TrackingEventCue CueExited raised."); var trackingEventCue = args.Cue as TrackingEventCue; if (trackingEventCue != null) { logMsg.AppendLine($"Label: {timedMetadataTrack.Label}, Id: {trackingEventCue.Id}, StartTime: {trackingEventCue.StartTime}, Duration: {trackingEventCue.Duration}"); logMsg.Append($"{trackingEventCue.TrackingEventUri}"); } Log(logMsg.ToString()); }
// </SnippetEmsgCueEntered> private void metadata_EmsgCueExited(TimedMetadataTrack timedMetadataTrack, MediaCueEventArgs args) { }
/// <summary> /// This function executes when a SpeechCue is hit and calls the functions to update the UI /// </summary> /// <param name="timedMetadataTrack">The timedMetadataTrack associated with the event.</param> /// <param name="args">the arguments associated with the event.</param> private async void metadata_SpeechCueEntered(TimedMetadataTrack timedMetadataTrack, MediaCueEventArgs args) { // Check in case there are different tracks and the handler was used for more tracks if (timedMetadataTrack.TimedMetadataKind == TimedMetadataKind.Speech) { var cue = args.Cue as SpeechCue; if (cue != null) { await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { if (timedMetadataTrack.Id == "SpeechSentence" || timedMetadataTrack.Id == "SpeechWord") { SpeechCueType type = timedMetadataTrack.Id == "SpeechSentence" ? SpeechCueType.Sentence : SpeechCueType.Word; var arg = new SpeechCueEventArgs(cue, type); SpeechCueChanged?.Invoke(this, arg); } }); } } }