99// %BANNER_END%
1010
1111using System ;
12+ using System . Collections ;
13+ using System . Collections . Generic ;
1214using MagicLeap . Core ;
1315using UnityEngine ;
1416using UnityEngine . UI ;
@@ -59,6 +61,21 @@ public class MediaPlayerControls : MonoBehaviour
5961 [ SerializeField , Tooltip ( "Text for captions" ) ]
6062 private Text captionsText = null ;
6163
64+ [ SerializeField , Tooltip ( "Dropdown for the language track for captions" ) ]
65+ private Dropdown captionsTracksDropdown = null ;
66+
67+ [ SerializeField , Tooltip ( "Duration in seconds to delay before displaying a caption" ) ]
68+ private float captionsDelayDuration = 1 ;
69+
70+ [ SerializeField , Tooltip ( "Duration in seconds for a caption to stay on screen" ) ]
71+ private float captionsStayDuration = 4 ;
72+
73+ private IEnumerator captionsCoroutine ;
74+ private List < MLMedia . Player . Track > tracks = new List < MLMedia . Player . Track > ( ) ;
75+ private List < string > trackLanguages = new List < string > ( ) ;
76+ private MLMedia . Player . Track currentTrack ;
77+ private float currentElapsedTimeMS ;
78+
6279 void Awake ( )
6380 {
6481 if ( mediaPlayerBehavior == null )
@@ -79,6 +96,37 @@ void OnDisable()
7996 UnregisterCallbacks ( ) ;
8097 }
8198
99+ public void OnTrackDropdownValueChanged ( int value )
100+ {
101+ mediaPlayerBehavior . UnselectTrack ( currentTrack ) ;
102+
103+ if ( captionsCoroutine != null )
104+ StopCoroutine ( captionsCoroutine ) ;
105+
106+ bool wasPlaying = mediaPlayerBehavior . IsPlaying ;
107+
108+ // seek current position in the timeline to trigger the track to change if not stopped
109+ if ( currentElapsedTimeMS > 0 )
110+ {
111+ mediaPlayerBehavior . SeekTo ( currentElapsedTimeMS ) ;
112+
113+ // ensure that if it was already paused that it will remain paused
114+ if ( ! wasPlaying )
115+ {
116+ StartCoroutine ( PauseAfterSeeking ( ) ) ;
117+ }
118+ }
119+
120+ currentTrack = tracks [ value ] ;
121+ mediaPlayerBehavior . SelectTrack ( currentTrack ) ;
122+ }
123+
124+ private IEnumerator PauseAfterSeeking ( )
125+ {
126+ yield return new WaitUntil ( ( ) => mediaPlayerBehavior . IsPlaying ) ;
127+ mediaPlayerBehavior . MediaPlayer . Pause ( ) ;
128+ }
129+
82130 private void RegisterCallbacks ( )
83131 {
84132 mediaPlayerBehavior . OnPrepared += HandleOnPrepared ;
@@ -89,6 +137,7 @@ private void RegisterCallbacks()
89137 mediaPlayerBehavior . OnSeekComplete += HandleOnSeekComplete ;
90138 mediaPlayerBehavior . OnCaptionsText += OnCaptionsText ;
91139 mediaPlayerBehavior . OnTrackSelected += OnTrackSelected ;
140+ mediaPlayerBehavior . OnTrackFound += OnTrackFound ;
92141 mediaPlayerBehavior . OnUpdateTimeline += HandleOnTimelineChanged ;
93142 mediaPlayerBehavior . OnUpdateElapsedTime += HandleOnElapsedTimeChanged ;
94143 mediaPlayerBehavior . OnIsBufferingChanged += HandleOnIsBufferingChanged ;
@@ -113,6 +162,7 @@ private void UnregisterCallbacks()
113162 mediaPlayerBehavior . OnSeekComplete -= HandleOnSeekComplete ;
114163 mediaPlayerBehavior . OnCaptionsText -= OnCaptionsText ;
115164 mediaPlayerBehavior . OnTrackSelected -= OnTrackSelected ;
165+ mediaPlayerBehavior . OnTrackFound -= OnTrackFound ;
116166 mediaPlayerBehavior . OnUpdateTimeline -= HandleOnTimelineChanged ;
117167 mediaPlayerBehavior . OnUpdateElapsedTime -= HandleOnElapsedTimeChanged ;
118168 mediaPlayerBehavior . OnIsBufferingChanged -= HandleOnIsBufferingChanged ;
@@ -148,6 +198,7 @@ private void PlayPause()
148198 /// </summary>
149199 private void Stop ( )
150200 {
201+ currentElapsedTimeMS = 0 ;
151202 mediaPlayerBehavior . StopMLMediaPlayer ( ) ;
152203 }
153204
@@ -337,12 +388,46 @@ private void HandleOnSeekComplete()
337388 }
338389 }
339390
391+ /// <summary>
392+ /// Callback handler on track found.
393+ /// </summary>
394+ /// <param name="track"></param>
395+ private void OnTrackFound ( MLMedia . Player . Track track )
396+ {
397+ if ( track . TrackType == MLMedia . Player . Track . Type . TimedText )
398+ {
399+ captionsTracksDropdown . gameObject . SetActive ( true ) ;
400+
401+ tracks . Add ( track ) ;
402+ string languageType = GetTrackLanguage ( track ) ;
403+ trackLanguages . Add ( languageType ) ;
404+ captionsTracksDropdown . ClearOptions ( ) ;
405+ captionsTracksDropdown . AddOptions ( trackLanguages ) ;
406+
407+ // default to English when starting
408+ if ( trackLanguages . Contains ( "English" ) )
409+ captionsTracksDropdown . value = trackLanguages . IndexOf ( "English" ) ;
410+
411+ if ( currentTrack == null || track . Language == "en" )
412+ {
413+ if ( currentTrack != null )
414+ mediaPlayerBehavior . UnselectTrack ( currentTrack ) ;
415+
416+ currentTrack = track ;
417+
418+ mediaPlayerBehavior . SelectTrack ( currentTrack ) ;
419+ }
420+ }
421+ }
422+
340423 /// <summary>
341424 /// Callback handler on track selected.
342425 /// </summary>
343426 /// <param name="track"></param>
344427 void OnTrackSelected ( MLMedia . Player . Track track )
345428 {
429+ currentTrack = track ;
430+
346431 if ( track . TrackType == MLMedia . Player . Track . Type . TimedText || track . TrackType == MLMedia . Player . Track . Type . Subtitle )
347432 captionsText . text = string . Empty ;
348433 }
@@ -353,7 +438,11 @@ void OnTrackSelected(MLMedia.Player.Track track)
353438 /// <param name="text"></param>
354439 void OnCaptionsText ( string text )
355440 {
356- captionsText . text = text ;
441+ if ( captionsCoroutine != null )
442+ StopCoroutine ( captionsCoroutine ) ;
443+
444+ captionsCoroutine = DisplayCaption ( text ) ;
445+ StartCoroutine ( captionsCoroutine ) ;
357446 }
358447
359448 /// <summary>
@@ -362,9 +451,36 @@ void OnCaptionsText(string text)
362451 /// <param name="elapsedTimeMs">Elapsed time in milliseconds</param>
363452 private void UpdateElapsedTime ( long elapsedTimeMs )
364453 {
454+ currentElapsedTimeMS = elapsedTimeMs ;
455+
365456 TimeSpan timeSpan = new TimeSpan ( elapsedTimeMs * TimeSpan . TicksPerMillisecond ) ;
366457 elapsedTime . text = $ "{ timeSpan . Hours } :{ timeSpan . Minutes : 00} :{ timeSpan . Seconds : 00} ";
367458 }
459+
460+
461+ private IEnumerator DisplayCaption ( string text )
462+ {
463+ yield return new WaitForSeconds ( captionsDelayDuration ) ;
464+ captionsText . text = text ;
465+ yield return new WaitForSeconds ( captionsStayDuration ) ;
466+ captionsText . text = "" ;
467+ captionsCoroutine = null ;
468+ }
469+
470+ private string GetTrackLanguage ( MLMedia . Player . Track track )
471+ {
472+ // TODO: Add support for more captions track languages
473+ if ( track . Language == "en" )
474+ return "English" ;
475+ else if ( track . Language == "es" )
476+ return "Español" ;
477+ else if ( track . Language == "fr" )
478+ return "Français" ;
479+ else if ( track . Language == "de" )
480+ return "Deutsch" ;
481+ else
482+ return track . Language . ToString ( ) ;
483+ }
368484 }
369485}
370486
0 commit comments