public async Task TestInitializeSuceeds()
        {
            // Arrange
            var engineUnderTest = new MediaEngine();

            // Act
            var result = await engineUnderTest.InitializeAsync();

            // Assert
            Assert.IsTrue(MediaEngineInitializationResult.Success == result);
        }
        public async Task InitialzeAsync()
        {
            this.mediaEngine = new MediaEngine();
            var result = await this.mediaEngine.InitializeAsync();
            if (result == MediaEngineInitializationResult.Fail)
            {
                StartupTask.WriteTelemetryEvent("MediaEngine_FailedToInitialize");
                
            }

            this.mediaEngine.MediaStateChanged += MediaEngine_MediaStateChanged;
        }
        public async Task TestPlayWithInitializeSucceeds()
        {
            // Arrange
            var engineUnderTest = new MediaEngine();
            bool callbackOccurred = false;
            uint callbackTimeout = 10;

            // Act
            Assert.IsTrue(MediaEngineInitializationResult.Success == await engineUnderTest.InitializeAsync()
                , "Failed to initialize MediaEngine");

            engineUnderTest.MediaStateChanged += ((MediaState newState) => 
            {
                if (MediaState.Playing == newState)
                    callbackOccurred = true;
            });

            try
            {
                engineUnderTest.Play("ms-appx:///Assets/TestSilence.wav");

                // Wait for the callback to be invoked until the timeout expires
                uint counter = 0;
                while (!callbackOccurred)
                {
                    Assert.IsFalse(counter == callbackTimeout,
                        "Timed out waiting for callback from mediaengine");

                    await Task.Delay(100);

                    counter++;
                }
            }
            catch (Exception e)
            {
                Assert.Fail("An exception was thrown during execution of the test: " + e.Message);
            }

            // Assert
            Assert.IsTrue(callbackOccurred);
        }
        public void TestPlayWithoutInitializeFails()
        {
            // Arrange
            var engineUnderTest = new MediaEngine();
            bool exceptionThrown = false;

            // Act
            try
            {
                engineUnderTest.Play("");
            }
            catch(Exception e)
            {
                exceptionThrown = true;
            }


            // Assert
            Assert.IsTrue(exceptionThrown);
                
        }
        public async Task TestPlayStreamWithInvalidStreamFails()
        {
            // Arrange
            var engineUnderTest = new MediaEngine();
            bool exceptionThrown = false;

            // Act
            Assert.IsTrue(MediaEngineInitializationResult.Success == await engineUnderTest.InitializeAsync()
                , "Failed to initialize MediaEngine");

            try
            {
                engineUnderTest.PlayStream(null);
            }
            catch (Exception e)
            {
                exceptionThrown = true;
            }

            // Assert

            // An exception should be thrown
            Assert.IsTrue(exceptionThrown);
        }
Exemplo n.º 6
0
        // loads all the available media engines into the combo box
        void loadEngineList()
        {
            string dir = AppDomain.CurrentDomain.BaseDirectory;
            if (dir.Length == 0) return;
            dir = System.IO.Path.Combine (dir, "plugins");

            foreach (string file in System.IO.Directory.GetFiles (dir, "*.dll"))
            {
                MediaEngine engine = new MediaEngine (file);
                if (engine.Load ())
                    store.AppendValues (engine, engine.Instance.Name);
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Loads the previously selected media engine.
        /// </summary>
        public void LoadEngine()
        {
            string engine_path = fuse.Config.MediaControls.Get ("Engine Path", "None");
            MediaEngine engine = new MediaEngine (engine_path);

            if (File.Exists (engine_path) && engine.Load ())
            {
                fuse.Controls.Engine = engine;
                fuse.ChosenEngine = engine_path;
            }
            else
            {
                fuse.Controls.Engine = null;
                engine_item_activated (null, null);
            }
        }
Exemplo n.º 8
0
 /// <summary>
 /// Called when media options have been changed.
 /// </summary>
 /// <param name="sender">The sender.</param>
 /// <param name="mediaInfo">The media information.</param>
 public void OnMediaChanged(MediaEngine sender, MediaInfo mediaInfo) =>
 Parent?.PostMediaChangedEvent(mediaInfo);
        /// <summary>
        /// Performs the actions represented by this deferred task.
        /// </summary>
        protected override void PerformActions()
        {
            var m = MediaCore;

            // Notify Media will start opening
            m.Log(MediaLogMessageType.Debug, $"Command {CommandType}: Entered");

            try
            {
                // TODO: Sometimes when the stream can't be read, the sample player stays as if it were trying to open
                // until the interrupt timeout occurs but and the Real-Time Clock continues. Strange behavior. Investigate more.

                // Signal the initial state
                m.State.ResetMediaProperties();
                m.State.UpdateFixedContainerProperties();
                m.State.Source = Source;

                // Register FFmpeg libraries if not already done
                if (MediaEngine.LoadFFmpeg())
                {
                    // Log an init message
                    m.Log(MediaLogMessageType.Info,
                          $"{nameof(FFInterop)}.{nameof(FFInterop.Initialize)}: FFmpeg v{MediaEngine.FFmpegVersionInfo}");
                }

                // Create a default stream container configuration object
                var containerConfig = new ContainerConfiguration();

                // Convert the URI object to something the Media Container understands (Uri to String)
                var mediaUrl = Source.ToString();

                // When opening via URL (and not via custom input stream), fixup the protocols and stuff
                if (InputStream == null)
                {
                    try
                    {
                        // the async protocol prefix allows for increased performance for local files.
                        // or anything that is file-system related
                        if (Source.IsFile || Source.IsUnc)
                        {
                            // Set the default protocol Prefix
                            mediaUrl = Source.LocalPath;
                            containerConfig.ProtocolPrefix = "async";
                        }
                    }
                    catch { }

                    // Support device URLs
                    // GDIGRAB: Example URI: device://gdigrab?desktop
                    if (string.IsNullOrWhiteSpace(Source.Scheme) == false &&
                        (Source.Scheme.Equals("format") || Source.Scheme.Equals("device")) &&
                        string.IsNullOrWhiteSpace(Source.Host) == false &&
                        string.IsNullOrWhiteSpace(containerConfig.ForcedInputFormat) &&
                        string.IsNullOrWhiteSpace(Source.Query) == false)
                    {
                        // Update the Input format and container input URL
                        // It is also possible to set some input options as follows:
                        // streamOptions.PrivateOptions["framerate"] = "20";
                        containerConfig.ForcedInputFormat = Source.Host;
                        mediaUrl = Uri.UnescapeDataString(Source.Query).TrimStart('?');
                        m.Log(MediaLogMessageType.Info, $"Media URI will be updated. Input Format: {Source.Host}, Input Argument: {mediaUrl}");
                    }
                }

                // Allow the stream input options to be changed
                m.SendOnMediaInitializing(containerConfig, mediaUrl);

                // Opening the media means we are buffering packets
                m.State.SignalBufferingStarted();

                // Instantiate the internal container using either a URL (default) or a custom input stream.
                if (InputStream == null)
                {
                    m.Container = new MediaContainer(mediaUrl, containerConfig, m);
                }
                else
                {
                    m.Container = new MediaContainer(InputStream, containerConfig, m);
                }

                // Notify the user media is opening and allow for media options to be modified
                // Stuff like audio and video filters and stream selection can be performed here.
                m.State.UpdateFixedContainerProperties();
                m.SendOnMediaOpening();

                // Side-load subtitles if requested
                m.PreloadSubtitles();

                // Set the callback to update buffering progress
                m.Container.Components.OnPacketQueued = (packetPtr, mediaType, bufferLength, lifetimeBytes) =>
                                                        m.State.UpdateBufferingProgress(bufferLength);

                // Get the main container open
                m.Container.Open();

                // Reset buffering properties
                m.State.UpdateFixedContainerProperties();
                m.State.InitializeBufferingProperties();

                // Check if we have at least audio or video here
                if (m.State.HasAudio == false && m.State.HasVideo == false)
                {
                    throw new MediaContainerException($"Unable to initialize at least one audio or video component fron the input stream.");
                }

                // Charge! We are good to go, fire up the worker threads!
                m.StartWorkers();
            }
            catch (Exception ex)
            {
                // On closing we immediately signal a buffering ended operation
                m.State.SignalBufferingEnded();

                try { m.StopWorkers(); } catch { }
                try { m.Container?.Dispose(); } catch { }
                m.DisposePreloadedSubtitles();
                m.Container     = null;
                ExceptionResult = ex;
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="DirectOpenCommand" /> class.
 /// </summary>
 /// <param name="mediaCore">The manager.</param>
 /// <param name="source">The source.</param>
 public DirectOpenCommand(MediaEngine mediaCore, Uri source)
     : base(mediaCore)
 {
     Source      = source;
     CommandType = CommandType.Open;
 }
Exemplo n.º 11
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MediaEngineState" /> class.
 /// </summary>
 /// <param name="parent">The parent.</param>
 internal MediaEngineState(MediaEngine parent)
 {
     Parent = parent;
 }
Exemplo n.º 12
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CommandManager" /> class.
 /// </summary>
 /// <param name="mediaCore">The media core.</param>
 public CommandManager(MediaEngine mediaCore)
 {
     MediaCore = mediaCore;
 }
Exemplo n.º 13
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SubtitleRenderer"/> class.
 /// </summary>
 /// <param name="mediaEngine">The core media element.</param>
 public SubtitleRenderer(MediaEngine mediaEngine)
 {
     MediaCore = mediaEngine;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="MediaCommandManager"/> class.
 /// </summary>
 /// <param name="mediaEngine">The media element.</param>
 public MediaCommandManager(MediaEngine mediaEngine)
 {
     m_MediaCore = mediaEngine;
 }
Exemplo n.º 15
0
 /// <summary>
 /// Initializes a new instance of the <see cref="VideoRendererBase"/> class.
 /// </summary>
 /// <param name="mediaCore">The media core.</param>
 protected VideoRendererBase(MediaEngine mediaCore)
 {
     MediaCore = mediaCore;
 }
Exemplo n.º 16
0
 public static async Task LoadAsync(this MediaEngine engine, string url, CancellationToken token)
 {
     await engine.DoAsync(token, () => engine.Source = url, e => e == MediaEngineEvent.LoadedMetadata);
 }
        public async Task TestVolumeGetandChangeSucceeds()
        {
            // Arrange
            var engineUnderTest = new MediaEngine();
            double volume = 0;

            // Act
            Assert.IsTrue(MediaEngineInitializationResult.Success == await engineUnderTest.InitializeAsync()
                , "Failed to initialize MediaEngine");

            try
            {
                // get the current volume
                volume = engineUnderTest.Volume;

                // decrease the volume by 0.1
                engineUnderTest.Volume -= 0.1;
            }
            catch (Exception e)
            {
                Assert.Fail("An exception was thrown during execution of the test: " + e.Message);
            }

            // Assert

            // Check that the current engine volume has been changed
            Assert.IsTrue((volume -= 0.1) == engineUnderTest.Volume);
        }
Exemplo n.º 18
0
 /// <summary>
 /// Initializes a new instance of the <see cref="T:Unosquare.FFME.MacOS.Rendering.AudioRenderer"/> class.
 /// </summary>
 /// <param name="mediaEngine">Media element core.</param>
 public AudioRenderer(MediaEngine mediaEngine)
 {
     MediaCore = mediaEngine;
 }
        public async Task TestStopStreamWithInitializeSucceeds()
        {
            // Arrange
            var  engineUnderTest         = new MediaEngine();
            bool playingCallbackOccurred = false;
            bool stoppedCallbackOccurred = false;
            uint callbackCount           = 0;
            uint callbackTimeout         = 10;

            // Act
            Assert.IsTrue(MediaEngineInitializationResult.Success == await engineUnderTest.InitializeAsync()
                          , "Failed to initialize MediaEngine");

            engineUnderTest.MediaStateChanged += ((MediaState newState) =>
            {
                switch (callbackCount)
                {
                case 0:
                    if (MediaState.Playing == newState)
                    {
                        playingCallbackOccurred = true;
                        callbackCount++;
                    }
                    break;

                case 1:
                    if (MediaState.Stopped == newState)
                    {
                        stoppedCallbackOccurred = true;
                        callbackCount++;
                    }
                    break;
                }
            });

            try
            {
                // Open the file as a byte stream
                engineUnderTest.Play("ms-appx:///Assets/TestSilence.wav");

                // Wait for the callback to be invoked until the timeout expires
                uint counter = 0;
                while (0 == callbackCount)
                {
                    Assert.IsFalse(counter == callbackTimeout,
                                   "Timed out waiting for callback from mediaengine");

                    await Task.Delay(100);

                    counter++;
                }

                engineUnderTest.Stop();

                counter = 0;
                while (1 == callbackCount)
                {
                    Assert.IsFalse(counter == callbackTimeout,
                                   "Timed out waiting for callback from mediaengine");

                    await Task.Delay(100);

                    counter++;
                }
            }
            catch (Exception e)
            {
                Assert.Fail("An exception was thrown during execution of the test: " + e.Message);
            }

            // Assert
            Assert.IsTrue(playingCallbackOccurred, "Track did not start playing");
            Assert.IsTrue(stoppedCallbackOccurred, "Track did not stop");
        }
Exemplo n.º 20
0
        /// <summary>
        /// Gets the length of a <see cref="Video"/>
        /// </summary>
        /// <param name="video"></param>
        /// <returns></returns>
        public static TimeSpan GetDuration(this Video video)
        {
            MediaInfo info = MediaEngine.RetrieveMediaInfo(video.Path);

            return(info.Duration);
        }
Exemplo n.º 21
0
 /// <summary>
 /// Called when [media initializing].
 /// </summary>
 /// <param name="sender">The sender.</param>
 /// <param name="config">The container configuration options.</param>
 /// <param name="url">The URL.</param>
 public void OnMediaInitializing(MediaEngine sender, ContainerConfiguration config, string url) =>
 Parent?.RaiseMediaInitializingEvent(config, url);
Exemplo n.º 22
0
 static VideoExtensions()
 {
     MediaEngine.LoadFFmpeg();
 }
Exemplo n.º 23
0
        // when the user has selected a media engine from the combo box
        void combo_changed(object o, EventArgs args)
        {
            TreeIter iter;
            if (combo.GetActiveIter (out iter)) {
                MediaEngine engine = (MediaEngine) store.GetValue (iter, 0);
                this.engine = engine;

                title.Markup = "<small>" + engine.Instance.Name + "</small>";
                version.Markup = "<small>" + engine.Instance.Version + "</small>";
                description.Markup = "<small>" + engine.Instance.Description + "</small>";
                author.Markup = "<small>" + engine.Instance.Author + "</small>";
                website.Markup = "<small>" + engine.Instance.Website + "</small>";
            }
        }
Exemplo n.º 24
0
 /// <summary>
 /// Called when [media initializing].
 /// </summary>
 /// <param name="sender">The sender.</param>
 /// <param name="options">The options.</param>
 /// <param name="url">The URL.</param>
 public void OnMediaInitializing(MediaEngine sender, StreamOptions options, string url)
 {
     Parent?.RaiseMediaInitializingEvent(options, url);
 }
Exemplo n.º 25
0
        public MainPage()
        {
            this.InitializeComponent();

            this.mediaEngine = new MediaEngine();
        }
Exemplo n.º 26
0
 /// <summary>
 /// Called when [message logged].
 /// </summary>
 /// <param name="sender">The sender.</param>
 /// <param name="e">The <see cref="T:Unosquare.FFME.Shared.MediaLogMessage" /> instance containing the event data.</param>
 public void OnMessageLogged(MediaEngine sender, MediaLogMessage e)
 {
     Parent?.RaiseMessageLoggedEvent(e);
 }
Exemplo n.º 27
0
 public async Task InitSpeech()
 {
     mediaEngine = new MediaEngine();
     synth = new SpeechSynthesizer();
     await mediaEngine.InitializeAsync();
 }
Exemplo n.º 28
0
 /// <summary>
 /// Called when [seeking started].
 /// </summary>
 /// <param name="sender">The sender.</param>
 public void OnSeekingStarted(MediaEngine sender)
 {
     Parent?.RaiseSeekingStartedEvent();
 }
        public async Task TestPlayStreamWithInitializeSucceeds()
        {
            // Arrange
            var engineUnderTest = new MediaEngine();
            bool callbackOccurred = false;
            uint callbackTimeout = 10;
            StorageFile testFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/TestSilence.wav"));

            // Act
            Assert.IsTrue(MediaEngineInitializationResult.Success == await engineUnderTest.InitializeAsync()
                , "Failed to initialize MediaEngine");

            engineUnderTest.MediaStateChanged += ((MediaState newState) =>
            {
                if (MediaState.Playing == newState)
                    callbackOccurred = true;
            });

            try
            {         
                // Open the file as a byte stream
                engineUnderTest.PlayStream(await testFile.OpenReadAsync());

                // Wait for the callback to be invoked until the timeout expires
                uint counter = 0;
                while (!callbackOccurred)
                {
                    Assert.IsFalse(counter == callbackTimeout,
                        "Timed out waiting for callback from mediaengine");

                    await Task.Delay(100);

                    counter++;
                }
            }
            catch (Exception e)
            {
                Assert.Fail("An exception was thrown during execution of the test: " + e.Message);
            }

            // Assert

            // The callback should be call within the timeout period
            Assert.IsTrue(callbackOccurred);
        }
Exemplo n.º 30
0
 /// <summary>
 /// Called when [buffering started].
 /// </summary>
 /// <param name="sender">The sender.</param>
 public void OnBufferingStarted(MediaEngine sender)
 {
     Parent?.RaiseBufferingStartedEvent();
 }
        public async Task TestPauseAndUnPauseSucceeds()
        {
            // Arrange
            var engineUnderTest = new MediaEngine();
            bool firstPlayingCallbackOccurred = false;
            bool pausedCallbackOccurred = false;
            bool secondPlayingCallbackOccurred = false;
            uint callbackCount = 0;
            uint callbackTimeout = 10;

            // Act
            var result = await engineUnderTest.InitializeAsync();

            engineUnderTest.MediaStateChanged += ((MediaState newState) =>
            {
                switch(callbackCount)
                {
                    case 0:
                            if (MediaState.Playing == newState)
                            {
                                firstPlayingCallbackOccurred = true;
                                callbackCount++;
                            }
                            break;
                    case 1:
                            if (MediaState.Paused == newState)
                            {
                                pausedCallbackOccurred = true;
                                callbackCount++;
                            }
                            break;
                    case 2:
                            if (MediaState.Playing == newState)
                            {
                                secondPlayingCallbackOccurred = true;
                                callbackCount++;
                            }
                            break;
                }
            });

            Assert.IsTrue(MediaEngineInitializationResult.Success == result);

            try
            {
                engineUnderTest.Play("ms-appx:///Assets/TestSilence.wav");

                uint counter = 0;
                while (0 == callbackCount)
                {
                    Assert.IsFalse(counter == callbackTimeout,
                        "Timed out waiting for callback from mediaengine");

                    await Task.Delay(100);

                    counter++;
                }

                engineUnderTest.Pause();

                counter = 0;
                while (1 == callbackCount)
                {
                    Assert.IsFalse(counter == callbackTimeout,
                        "Timed out waiting for callback from mediaengine");

                    await Task.Delay(100);

                    counter++;
                }

                engineUnderTest.Pause();

                counter = 0;
                while (2 == callbackCount)
                {
                    Assert.IsFalse(counter == callbackTimeout,
                        "Timed out waiting for callback from mediaengine");

                    await Task.Delay(100);

                    counter++;
                }

            }
            catch (Exception e)
            {
                Assert.Fail("An exception was thrown during execution of the test: " + e.Message);
            }

            Assert.IsTrue(firstPlayingCallbackOccurred, "Track did not start playing");
            Assert.IsTrue(pausedCallbackOccurred, "Track did not pause");
            Assert.IsTrue(secondPlayingCallbackOccurred, "Track did not resume");
        }
Exemplo n.º 32
0
 /// <summary>
 /// Called when [media closed].
 /// </summary>
 /// <param name="sender">The sender.</param>
 public void OnMediaClosed(MediaEngine sender)
 {
     Parent?.RaiseMediaClosedEvent();
 }
        public async Task TestStopStreamWithInitializeSucceeds()
        {
            // Arrange
            var engineUnderTest = new MediaEngine();
            bool playingCallbackOccurred = false;
            bool stoppedCallbackOccurred = false;
            uint callbackCount = 0;
            uint callbackTimeout = 10;

            // Act
            Assert.IsTrue(MediaEngineInitializationResult.Success == await engineUnderTest.InitializeAsync()
                , "Failed to initialize MediaEngine");

            engineUnderTest.MediaStateChanged += ((MediaState newState) =>
            {
                switch (callbackCount)
                {
                    case 0:
                        if (MediaState.Playing == newState)
                        {
                            playingCallbackOccurred = true;
                            callbackCount++;
                        }
                        break;
                    case 1:
                        if (MediaState.Stopped == newState)
                        {
                            stoppedCallbackOccurred = true;
                            callbackCount++;
                        }
                        break;
                }
            });

            try
            {
                // Open the file as a byte stream
                engineUnderTest.Play("ms-appx:///Assets/TestSilence.wav");

                // Wait for the callback to be invoked until the timeout expires
                uint counter = 0;
                while (0 == callbackCount)
                {
                    Assert.IsFalse(counter == callbackTimeout,
                        "Timed out waiting for callback from mediaengine");

                    await Task.Delay(100);

                    counter++;
                }

                engineUnderTest.Stop();

                counter = 0;
                while (1 == callbackCount)
                {
                    Assert.IsFalse(counter == callbackTimeout,
                        "Timed out waiting for callback from mediaengine");

                    await Task.Delay(100);

                    counter++;
                }
            }
            catch (Exception e)
            {
                Assert.Fail("An exception was thrown during execution of the test: " + e.Message);
            }

            // Assert
            Assert.IsTrue(playingCallbackOccurred, "Track did not start playing");
            Assert.IsTrue(stoppedCallbackOccurred, "Track did not stop");
        }
Exemplo n.º 34
0
 /// <summary>
 /// Called when [media failed].
 /// </summary>
 /// <param name="sender">The sender.</param>
 /// <param name="e">The e.</param>
 public void OnMediaFailed(MediaEngine sender, Exception e)
 {
     Parent?.RaiseMediaFailedEvent(e);
 }
        public void TestVolumeSetWithoutInitializeFails()
        {
            // Arrange
            var engineUnderTest = new MediaEngine();
            bool exceptionThrown = false;

            // Act
            try
            {
                engineUnderTest.Volume = 1;
            }
            catch (Exception e)
            {
                exceptionThrown = true;
            }

            // Assert

            // An exception should be thrown
            Assert.IsTrue(exceptionThrown);

        }
Exemplo n.º 36
0
 /// <summary>
 /// Called when media options are changing.
 /// </summary>
 /// <param name="sender">The sender.</param>
 /// <param name="options">The options.</param>
 /// <param name="mediaInfo">The media information.</param>
 public void OnMediaChanging(MediaEngine sender, MediaOptions options, MediaInfo mediaInfo) =>
 Parent?.RaiseMediaChangingEvent(options, mediaInfo);
        public async Task TestPlayWithInvalidUrlFails()
        {
            // Arrange
            var engineUnderTest = new MediaEngine();
            bool callbackOccurred = false;
            uint callbackTimeout = 10;

            // Act
            Assert.IsTrue(MediaEngineInitializationResult.Success == await engineUnderTest.InitializeAsync()
                , "Failed to initialize MediaEngine");

            engineUnderTest.MediaStateChanged += ((MediaState newState) =>
            {
                // We're looking for the error state as this should be returns for
                // an invalid URL
                if (MediaState.Error == newState)
                    callbackOccurred = true;
            });

            try
            {
                engineUnderTest.Play("");

                // Wait for the callback to be invoked until the timeout expires
                uint counter = 0;
                while (!callbackOccurred)
                {
                    Assert.IsFalse(counter == callbackTimeout, 
                        "Timed out waiting for callback from mediaengine");

                    await Task.Delay(100);

                    counter++;
                }
            }
            catch (Exception e)
            {
                Assert.Fail("An exception was thrown during execution of the test: " + e.Message);
            }

            // Assert

            // The callback should be call within the timeout period
            Assert.IsTrue(callbackOccurred);
        }
        public async Task TestPauseAndUnPauseSucceeds()
        {
            // Arrange
            var  engineUnderTest = new MediaEngine();
            bool firstPlayingCallbackOccurred  = false;
            bool pausedCallbackOccurred        = false;
            bool secondPlayingCallbackOccurred = false;
            uint callbackCount   = 0;
            uint callbackTimeout = 10;

            // Act
            var result = await engineUnderTest.InitializeAsync();

            engineUnderTest.MediaStateChanged += ((MediaState newState) =>
            {
                switch (callbackCount)
                {
                case 0:
                    if (MediaState.Playing == newState)
                    {
                        firstPlayingCallbackOccurred = true;
                        callbackCount++;
                    }
                    break;

                case 1:
                    if (MediaState.Paused == newState)
                    {
                        pausedCallbackOccurred = true;
                        callbackCount++;
                    }
                    break;

                case 2:
                    if (MediaState.Playing == newState)
                    {
                        secondPlayingCallbackOccurred = true;
                        callbackCount++;
                    }
                    break;
                }
            });

            Assert.IsTrue(MediaEngineInitializationResult.Success == result);

            try
            {
                engineUnderTest.Play("ms-appx:///Assets/TestSilence.wav");

                uint counter = 0;
                while (0 == callbackCount)
                {
                    Assert.IsFalse(counter == callbackTimeout,
                                   "Timed out waiting for callback from mediaengine");

                    await Task.Delay(100);

                    counter++;
                }

                engineUnderTest.Pause();

                counter = 0;
                while (1 == callbackCount)
                {
                    Assert.IsFalse(counter == callbackTimeout,
                                   "Timed out waiting for callback from mediaengine");

                    await Task.Delay(100);

                    counter++;
                }

                engineUnderTest.Pause();

                counter = 0;
                while (2 == callbackCount)
                {
                    Assert.IsFalse(counter == callbackTimeout,
                                   "Timed out waiting for callback from mediaengine");

                    await Task.Delay(100);

                    counter++;
                }
            }
            catch (Exception e)
            {
                Assert.Fail("An exception was thrown during execution of the test: " + e.Message);
            }

            Assert.IsTrue(firstPlayingCallbackOccurred, "Track did not start playing");
            Assert.IsTrue(pausedCallbackOccurred, "Track did not pause");
            Assert.IsTrue(secondPlayingCallbackOccurred, "Track did not resume");
        }