You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by pu...@apache.org on 2013/07/09 01:28:40 UTC

[1/2] [CB-4127] remove dupe code

Updated Branches:
  refs/heads/master f8b2f95e5 -> 155284bba


http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/blob/155284bb/src/wp7/Media.cs
----------------------------------------------------------------------
diff --git a/src/wp7/Media.cs b/src/wp7/Media.cs
deleted file mode 100644
index 90c54f1..0000000
--- a/src/wp7/Media.cs
+++ /dev/null
@@ -1,532 +0,0 @@
-/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-using System.Windows;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    /// <summary>
-    /// Provides the ability to record and play back audio files on a device. 
-    /// </summary>
-    public class Media : BaseCommand
-    {
-        /// <summary>
-        /// Audio player objects
-        /// </summary>
-        private static Dictionary<string, AudioPlayer> players = new Dictionary<string, AudioPlayer>();
-
-        /// <summary>
-        /// Represents Media action options.
-        /// </summary>
-        [DataContract]
-        public class MediaOptions
-        {
-            /// <summary>
-            /// Audio id
-            /// </summary>
-            [DataMember(Name = "id", IsRequired = true)]
-            public string Id { get; set; }
-
-            /// <summary>
-            /// Path to audio file
-            /// </summary>
-            [DataMember(Name = "src")]
-            public string Src { get; set; }
-
-            /// <summary>
-            /// New track position
-            /// </summary>
-            [DataMember(Name = "milliseconds")]
-            public int Milliseconds { get; set; }
-        }
-
-        /// <summary>
-        /// Releases the audio player instance to save memory.
-        /// </summary>  
-        public void release(string options)
-        {
-            try
-            {
-                MediaOptions mediaOptions;
-
-                try
-                {
-                    string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
-                    mediaOptions = new MediaOptions();
-                    mediaOptions.Id = optionsString[0];
-                }
-                catch (Exception)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                    return;
-                }
-
-                if (!Media.players.ContainsKey(mediaOptions.Id))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, false));
-                    return;
-                }
-
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    try
-                    {
-                        AudioPlayer audio = Media.players[mediaOptions.Id];
-                        Media.players.Remove(mediaOptions.Id);
-                        audio.Dispose();
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, true));
-                    }
-                    catch (Exception e)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                    }
-                });
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-            }
-        }
-
-        /// <summary>
-        /// Starts recording and save the specified file 
-        /// </summary>
-        public void startRecordingAudio(string options)
-        {
-            try
-            {
-                MediaOptions mediaOptions;
-
-                try
-                {
-                    string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
-                    mediaOptions = new MediaOptions();
-                    mediaOptions.Id = optionsString[0];
-                    mediaOptions.Src = optionsString[1];
-                }
-                catch (Exception)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                    return;
-                }
-
-                if (mediaOptions != null)
-                {
-
-                    Deployment.Current.Dispatcher.BeginInvoke(() =>
-                    {
-                        try
-                        {
-                            if (!Media.players.ContainsKey(mediaOptions.Id))
-                            {
-                                AudioPlayer audio = new AudioPlayer(this, mediaOptions.Id);
-                                Media.players.Add(mediaOptions.Id, audio);
-                                audio.startRecording(mediaOptions.Src);
-                            }
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-                        }
-                        catch (Exception e)
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                        }
-
-                    });
-                }
-                else
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                }
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-            }
-        }
-
-        /// <summary>
-        /// Stops recording and save to the file specified when recording started 
-        /// </summary>
-        public void stopRecordingAudio(string options)
-        {
-            try
-            {
-                string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    try
-                    {
-                        if (Media.players.ContainsKey(mediaId))
-                        {
-                            AudioPlayer audio = Media.players[mediaId];
-                            audio.stopRecording();
-                            Media.players.Remove(mediaId);
-                        }
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-                    }
-                    catch (Exception e)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                    }
-                });
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-            }
-        }
-
-        public void setVolume(string options) // id,volume
-        {
-            try
-            {
-                string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
-                string id = optionsString[0];
-                double volume = double.Parse(optionsString[1]);
-
-                if (Media.players.ContainsKey(id))
-                {
-                    Deployment.Current.Dispatcher.BeginInvoke(() =>
-                    {
-                        try
-                        {
-                            AudioPlayer player = Media.players[id];
-                            player.setVolume(volume);
-                        }
-                        catch (Exception e)
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                        }
-                    });
-                }
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Error parsing options into setVolume method"));
-                return;
-            }
-        }
-
-        // Some Audio Notes:
-        // In the Windows Phone Emulator, playback of video or audio content using the MediaElement control is not supported.
-        // While playing, a MediaElement stops all other media playback on the phone.
-        // Multiple MediaElement controls are NOT supported
-
-        // Called when you create a new Media('blah') object in JS.
-        public void create(string options)
-        {
-            // Debug.WriteLine("Creating Audio :: " + options);
-            try
-            {
-                MediaOptions mediaOptions;
-                try
-                {
-                    string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
-                    mediaOptions = new MediaOptions();
-                    mediaOptions.Id = optionsString[0];
-                    mediaOptions.Src = optionsString[1];
-                }
-                catch (Exception)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Error parsing options into create method"));
-                    return;
-                }
-
-                AudioPlayer audio = new AudioPlayer(this, mediaOptions.Id);
-                Media.players.Add(mediaOptions.Id, audio);
-                DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-            }
-        }
-
-        /// <summary>
-        /// Starts or resume playing audio file 
-        /// </summary>
-        public void startPlayingAudio(string options)
-        {
-            try
-            {
-                MediaOptions mediaOptions;
-                try
-                {
-                    string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
-                    mediaOptions = new MediaOptions();
-                    mediaOptions.Id = optionsString[0];
-                    mediaOptions.Src = optionsString[1];
-                    if (optionsString.Length > 2 && optionsString[2] != null)
-                    {
-                        mediaOptions.Milliseconds = int.Parse(optionsString[2]);
-                    }
-
-                }
-                catch (Exception)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                    return;
-                }
-
-                AudioPlayer audio;
-
-                if (!Media.players.ContainsKey(mediaOptions.Id))
-                {
-                    audio = new AudioPlayer(this, mediaOptions.Id);
-                    Media.players[mediaOptions.Id] = audio;
-                }
-                else
-                {
-                    Debug.WriteLine("INFO: startPlayingAudio FOUND mediaPlayer for " + mediaOptions.Id);
-                    audio = Media.players[mediaOptions.Id];
-                }
-
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    try
-                    {
-                        audio.startPlaying(mediaOptions.Src);
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-                    }
-                    catch (Exception e)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                    }
-                });
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-            }
-        }
-
-
-        /// <summary>
-        /// Seeks to a location
-        /// </summary>
-        public void seekToAudio(string options)
-        {
-            try
-            {
-                MediaOptions mediaOptions;
-
-                try
-                {
-                    string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
-                    mediaOptions = new MediaOptions();
-                    mediaOptions.Id = optionsString[0];
-                    if (optionsString.Length > 1 && optionsString[1] != null)
-                    {
-                        mediaOptions.Milliseconds = int.Parse(optionsString[1]);
-                    }
-                }
-                catch (Exception)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                    return;
-                }
-
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    try
-                    {
-                        if (Media.players.ContainsKey(mediaOptions.Id))
-                        {
-                            AudioPlayer audio = Media.players[mediaOptions.Id];
-                            audio.seekToPlaying(mediaOptions.Milliseconds);
-                        }
-                        else
-                        {
-                            Debug.WriteLine("ERROR: seekToAudio could not find mediaPlayer for " + mediaOptions.Id);
-                        }
-
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-                    }
-                    catch (Exception e)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                    }
-                });
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-            }
-        }
-
-        /// <summary>
-        /// Pauses playing 
-        /// </summary>
-        public void pausePlayingAudio(string options)
-        {
-
-            try
-            {
-                string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
-
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    try
-                    {
-                        if (Media.players.ContainsKey(mediaId))
-                        {
-                            AudioPlayer audio = Media.players[mediaId];
-                            audio.pausePlaying();
-                        }
-                        else
-                        {
-                            Debug.WriteLine("ERROR: pausePlayingAudio could not find mediaPlayer for " + mediaId);
-                        }
-
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-                    }
-                    catch (Exception e)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                    }
-                });
-
-
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-            }
-
-
-        }
-
-
-        /// <summary>
-        /// Stops playing the audio file
-        /// </summary>
-        public void stopPlayingAudio(String options)
-        {
-            try
-            {
-                string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    try
-                    {
-                        if (Media.players.ContainsKey(mediaId))
-                        {
-                            AudioPlayer audio = Media.players[mediaId];
-                            audio.stopPlaying();
-                        }
-                        else
-                        {
-                            Debug.WriteLine("stopPlaying could not find mediaPlayer for " + mediaId);
-                        }
-
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-                    }
-                    catch (Exception e)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                    }
-                });
-
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-            }
-        }
-
-        /// <summary>
-        /// Gets current position of playback
-        /// </summary>
-        public void getCurrentPositionAudio(string options)
-        {
-            try
-            {
-                string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    try
-                    {
-                        if (Media.players.ContainsKey(mediaId))
-                        {
-                            AudioPlayer audio = Media.players[mediaId];
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getCurrentPosition()));
-                        }
-                        else
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, -1));
-                        }
-                    }
-                    catch (Exception e)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                    }
-                });
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-        }
-
-
-        /// <summary>
-        /// Gets the duration of the audio file
-        /// </summary>
-        
-        [Obsolete("This method will be removed shortly")]
-        public void getDurationAudio(string options)
-        {
-            try
-            {
-                MediaOptions mediaOptions;
-
-                try
-                {
-                    mediaOptions = JSON.JsonHelper.Deserialize<MediaOptions>(options);
-                }
-                catch (Exception)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                    return;
-                }
-
-                AudioPlayer audio;
-                if (Media.players.ContainsKey(mediaOptions.Id))
-                {
-                    audio = Media.players[mediaOptions.Id];
-                }
-                else
-                {
-                    Debug.WriteLine("ERROR: getDurationAudio could not find mediaPlayer for " + mediaOptions.Id);
-                    audio = new AudioPlayer(this, mediaOptions.Id);
-                    Media.players.Add(mediaOptions.Id, audio);
-                }
-
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getDuration(mediaOptions.Src)));
-                });
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/blob/155284bb/src/wp8/AudioPlayer.cs
----------------------------------------------------------------------
diff --git a/src/wp8/AudioPlayer.cs b/src/wp8/AudioPlayer.cs
deleted file mode 100644
index 882eb96..0000000
--- a/src/wp8/AudioPlayer.cs
+++ /dev/null
@@ -1,647 +0,0 @@
-/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Threading;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Audio;
-using Microsoft.Xna.Framework.Media;
-using Microsoft.Phone.Controls;
-using System.Diagnostics;
-using System.Windows.Resources;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-
-    /// <summary>
-    /// Implements audio record and play back functionality.
-    /// </summary>
-    internal class AudioPlayer : IDisposable
-    {
-        #region Constants
-
-        // AudioPlayer states
-        private const int PlayerState_None = 0;
-        private const int PlayerState_Starting = 1;
-        private const int PlayerState_Running = 2;
-        private const int PlayerState_Paused = 3;
-        private const int PlayerState_Stopped = 4;
-
-        // AudioPlayer messages
-        private const int MediaState = 1;
-        private const int MediaDuration = 2;
-        private const int MediaPosition = 3;
-        private const int MediaError = 9;
-
-        // AudioPlayer errors
-        private const int MediaErrorPlayModeSet = 1;
-        private const int MediaErrorAlreadyRecording = 2;
-        private const int MediaErrorStartingRecording = 3;
-        private const int MediaErrorRecordModeSet = 4;
-        private const int MediaErrorStartingPlayback = 5;
-        private const int MediaErrorResumeState = 6;
-        private const int MediaErrorPauseState = 7;
-        private const int MediaErrorStopState = 8;
-
-        //TODO: get rid of this callback, it should be universal
-        //private const string CallbackFunction = "CordovaMediaonStatus";
-
-        #endregion
-
-
-        /// <summary>
-        /// The AudioHandler object
-        /// </summary>
-        private Media handler;
-
-        /// <summary>
-        /// Temporary buffer to store audio chunk
-        /// </summary>
-        private byte[] buffer;
-
-        /// <summary>
-        /// Xna game loop dispatcher
-        /// </summary>
-        DispatcherTimer dtXna;
-
-
-        /// <summary>
-        /// Output buffer
-        /// </summary>
-        private MemoryStream memoryStream;
-
-        /// <summary>
-        /// The id of this player (used to identify Media object in JavaScript)
-        /// </summary>
-        private String id;
-
-        /// <summary>
-        /// State of recording or playback
-        /// </summary>
-        private int state = PlayerState_None;
-
-        /// <summary>
-        /// File name to play or record to
-        /// </summary>
-        private String audioFile = null;
-
-        /// <summary>
-        /// Duration of audio
-        /// </summary>
-        private double duration = -1;
-
-        /// <summary>
-        /// Audio player object
-        /// </summary>
-        private MediaElement player = null;
-
-        /// <summary>
-        /// Audio source
-        /// </summary>
-        private Microphone recorder;
-
-        /// <summary>
-        /// Internal flag specified that we should only open audio w/o playing it
-        /// </summary>
-        private bool prepareOnly = false;
-
-        /// <summary>
-        /// Creates AudioPlayer instance
-        /// </summary>
-        /// <param name="handler">Media object</param>
-        /// <param name="id">player id</param>
-        public AudioPlayer(Media handler, String id)
-        {
-            this.handler = handler;
-            this.id = id;
-        }
-
-
-        /// <summary>
-        /// Destroys player and stop audio playing or recording
-        /// </summary>
-        public void Dispose()
-        {
-            if (this.player != null)
-            {
-                this.stopPlaying();
-                this.player = null;
-            }
-            if (this.recorder != null)
-            {
-                this.stopRecording();
-                this.recorder = null;
-            }
-
-            this.FinalizeXnaGameLoop();
-        }
-
-        private void InvokeCallback(int message, string value, bool removeHandler)
-        {
-            string args = string.Format("('{0}',{1},{2});", this.id, message, value);
-            string callback = @"(function(id,msg,value){
-                try {
-                    if (msg == Media.MEDIA_ERROR) {
-                        value = {'code':value};
-                    }
-                    Media.onStatus(id,msg,value);
-                }
-                catch(e) {
-                    console.log('Error calling Media.onStatus :: ' + e);
-                }
-            })" + args;
-            this.handler.InvokeCustomScript(new ScriptCallback("eval", new string[] { callback }), false);
-        }
-
-        private void InvokeCallback(int message, int value, bool removeHandler)
-        {
-            InvokeCallback(message, value.ToString(), removeHandler);
-        }
-
-        private void InvokeCallback(int message, double value, bool removeHandler)
-        {
-            InvokeCallback(message, value.ToString(), removeHandler);
-        }
-
-        /// <summary>
-        /// Starts recording, data is stored in memory
-        /// </summary>
-        /// <param name="filePath"></param>
-        public void startRecording(string filePath)
-        {
-            if (this.player != null)
-            {
-                InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
-            }
-            else if (this.recorder == null)
-            {
-                try
-                {
-                    this.audioFile = filePath;
-                    this.InitializeXnaGameLoop();
-                    this.recorder = Microphone.Default;
-                    this.recorder.BufferDuration = TimeSpan.FromMilliseconds(500);
-                    this.buffer = new byte[recorder.GetSampleSizeInBytes(this.recorder.BufferDuration)];
-                    this.recorder.BufferReady += new EventHandler<EventArgs>(recorderBufferReady);
-                    MemoryStream stream  = new MemoryStream();
-                    this.memoryStream = stream;
-                    int numBits = 16;
-                    int numBytes = numBits / 8;
-
-                    // inline version from AudioFormatsHelper
-                    stream.Write(System.Text.Encoding.UTF8.GetBytes("RIFF"), 0, 4);
-                    stream.Write(BitConverter.GetBytes(0), 0, 4);
-                    stream.Write(System.Text.Encoding.UTF8.GetBytes("WAVE"), 0, 4);
-                    stream.Write(System.Text.Encoding.UTF8.GetBytes("fmt "), 0, 4);
-                    stream.Write(BitConverter.GetBytes(16), 0, 4);
-                    stream.Write(BitConverter.GetBytes((short)1), 0, 2);
-                    stream.Write(BitConverter.GetBytes((short)1), 0, 2);
-                    stream.Write(BitConverter.GetBytes(this.recorder.SampleRate), 0, 4);
-                    stream.Write(BitConverter.GetBytes(this.recorder.SampleRate * numBytes), 0, 4);
-                    stream.Write(BitConverter.GetBytes((short)(numBytes)), 0, 2);
-                    stream.Write(BitConverter.GetBytes((short)(numBits)), 0, 2);
-                    stream.Write(System.Text.Encoding.UTF8.GetBytes("data"), 0, 4);
-                    stream.Write(BitConverter.GetBytes(0), 0, 4);
-
-                    this.recorder.Start();
-                    FrameworkDispatcher.Update();
-                    this.SetState(PlayerState_Running);
-                }
-                catch (Exception)
-                {
-                    InvokeCallback(MediaError, MediaErrorStartingRecording, false);
-                    //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingRecording),false);
-                }
-            }
-            else
-            {
-                InvokeCallback(MediaError, MediaErrorAlreadyRecording, false);
-                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorAlreadyRecording),false);
-            }
-        }
-
-        /// <summary>
-        /// Stops recording
-        /// </summary>
-        public void stopRecording()
-        {
-            if (this.recorder != null)
-            {
-                if (this.state == PlayerState_Running)
-                {
-                    try
-                    {
-                        this.recorder.Stop();
-                        this.recorder.BufferReady -= recorderBufferReady;
-                        this.recorder = null;
-                        SaveAudioClipToLocalStorage();
-                        this.FinalizeXnaGameLoop();
-                        this.SetState(PlayerState_Stopped);
-                    }
-                    catch (Exception)
-                    {
-                        //TODO 
-                    }
-                }
-            }
-        }
-
-        /// <summary>
-        /// Starts or resume playing audio file
-        /// </summary>
-        /// <param name="filePath">The name of the audio file</param>
-        /// <summary>
-        /// Starts or resume playing audio file
-        /// </summary>
-        /// <param name="filePath">The name of the audio file</param>
-        public void startPlaying(string filePath)
-        {
-            if (this.recorder != null)
-            {
-                InvokeCallback(MediaError, MediaErrorRecordModeSet, false);
-                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorRecordModeSet),false);
-                return;
-            }
-
-
-            if (this.player == null || this.player.Source.AbsolutePath.LastIndexOf(filePath) < 0)
-            {
-                try
-                {
-                    // this.player is a MediaElement, it must be added to the visual tree in order to play
-                    PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
-                    if (frame != null)
-                    {
-                        PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
-                        if (page != null)
-                        {
-                            Grid grid = page.FindName("LayoutRoot") as Grid;
-                            if (grid != null)
-                            {
-
-                                this.player = grid.FindName("playerMediaElement") as MediaElement;
-                                if (this.player == null) // still null ?
-                                {
-                                    this.player = new MediaElement();
-                                    this.player.Name = "playerMediaElement";
-                                    grid.Children.Add(this.player);
-                                    this.player.Visibility = Visibility.Visible;
-                                }
-                                if (this.player.CurrentState == System.Windows.Media.MediaElementState.Playing)
-                                {
-                                    this.player.Stop(); // stop it!
-                                }
-
-                                this.player.Source = null; // Garbage collect it.
-                                this.player.MediaOpened += MediaOpened;
-                                this.player.MediaEnded += MediaEnded;
-                                this.player.MediaFailed += MediaFailed;
-                            }
-                        }
-                    }
-
-                    this.audioFile = filePath;
-
-                    Uri uri = new Uri(filePath, UriKind.RelativeOrAbsolute);
-                    if (uri.IsAbsoluteUri)
-                    {
-                        this.player.Source = uri;
-                    }
-                    else
-                    {
-                        using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                        {
-                            if (!isoFile.FileExists(filePath))
-                            {
-                                // try to unpack it from the dll into isolated storage
-                                StreamResourceInfo fileResourceStreamInfo = Application.GetResourceStream(new Uri(filePath, UriKind.Relative));
-                                if (fileResourceStreamInfo != null)
-                                {
-                                    using (BinaryReader br = new BinaryReader(fileResourceStreamInfo.Stream))
-                                    {
-                                        byte[] data = br.ReadBytes((int)fileResourceStreamInfo.Stream.Length);
-
-                                        string[] dirParts = filePath.Split('/');
-                                        string dirName = "";
-                                        for (int n = 0; n < dirParts.Length - 1; n++)
-                                        {
-                                            dirName += dirParts[n] + "/";
-                                        }
-                                        if (!isoFile.DirectoryExists(dirName))
-                                        {
-                                            isoFile.CreateDirectory(dirName);
-                                        }
-
-                                        using (IsolatedStorageFileStream outFile = isoFile.OpenFile(filePath, FileMode.Create))
-                                        {
-                                            using (BinaryWriter writer = new BinaryWriter(outFile))
-                                            {
-                                                writer.Write(data);
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                            if (isoFile.FileExists(filePath))
-                            {
-                                using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, isoFile))
-                                {
-                                    this.player.SetSource(stream);
-                                }
-                            }
-                            else
-                            {
-                                InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
-                                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, 1), false);
-                                return;
-                            }
-                        }
-                    }
-                    this.SetState(PlayerState_Starting);
-                }
-                catch (Exception e)
-                {
-                    Debug.WriteLine("Error in AudioPlayer::startPlaying : " + e.Message);
-                    InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
-                    //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingPlayback),false);
-                }
-            }
-            else
-            {
-                if (this.state != PlayerState_Running)
-                {
-                    this.player.Play();
-                    this.SetState(PlayerState_Running);
-                }
-                else
-                {
-                    InvokeCallback(MediaError, MediaErrorResumeState, false);
-                    //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorResumeState),false);
-                }
-            }
-        }
-
-        /// <summary>
-        /// Callback to be invoked when the media source is ready for playback
-        /// </summary>
-        private void MediaOpened(object sender, RoutedEventArgs arg)
-        {
-            if (this.player != null)
-            {
-                this.duration = this.player.NaturalDuration.TimeSpan.TotalSeconds;
-                InvokeCallback(MediaDuration, this.duration, false);
-                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaDuration, this.duration),false);
-                if (!this.prepareOnly)
-                {
-                    this.player.Play();
-                    this.SetState(PlayerState_Running);
-                }
-                this.prepareOnly = false;
-            }
-            else
-            {
-                // TODO: occasionally MediaOpened is signalled, but player is null
-            }
-        }
-
-        /// <summary>
-        /// Callback to be invoked when playback of a media source has completed
-        /// </summary>
-        private void MediaEnded(object sender, RoutedEventArgs arg)
-        {
-            this.SetState(PlayerState_Stopped);
-        }
-
-        /// <summary>
-        /// Callback to be invoked when playback of a media source has failed
-        /// </summary>
-        private void MediaFailed(object sender, RoutedEventArgs arg)
-        {
-            player.Stop();
-            InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
-            //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError.ToString(), "Media failed"),false);
-        }
-
-        /// <summary>
-        /// Seek or jump to a new time in the track
-        /// </summary>
-        /// <param name="milliseconds">The new track position</param>
-        public void seekToPlaying(int milliseconds)
-        {
-            if (this.player != null)
-            {
-                TimeSpan tsPos = new TimeSpan(0, 0, 0, 0, milliseconds);
-                this.player.Position = tsPos;
-                InvokeCallback(MediaPosition, milliseconds / 1000.0f, false);
-                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, milliseconds / 1000.0f),false);
-            }
-        }
-
-        /// <summary>
-        /// Set the volume of the player
-        /// </summary>
-        /// <param name="vol">volume 0.0-1.0, default value is 0.5</param>
-        public void setVolume(double vol)
-        {
-            if (this.player != null)
-            {
-                this.player.Volume = vol;
-            }
-        }
-
-        /// <summary>
-        /// Pauses playing
-        /// </summary>
-        public void pausePlaying()
-        {
-            if (this.state == PlayerState_Running)
-            {
-                this.player.Pause();
-                this.SetState(PlayerState_Paused);
-            }
-            else
-            {
-                InvokeCallback(MediaError, MediaErrorPauseState, false);
-                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorPauseState),false);
-            }
-        }
-
-
-        /// <summary>
-        /// Stops playing the audio file
-        /// </summary>
-        public void stopPlaying()
-        {
-            if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
-            {
-                this.player.Stop();
-
-                this.player.Position = new TimeSpan(0L);
-                this.SetState(PlayerState_Stopped);
-            }
-            //else // Why is it an error to call stop on a stopped media?
-            //{
-            //    this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStopState), false);
-            //}
-        }
-
-        /// <summary>
-        /// Gets current position of playback
-        /// </summary>
-        /// <returns>current position</returns>
-        public double getCurrentPosition()
-        {
-            if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
-            {
-                double currentPosition = this.player.Position.TotalSeconds;
-                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, currentPosition),false);
-                return currentPosition;
-            }
-            else
-            {
-                return 0;
-            }
-        }
-
-        /// <summary>
-        /// Gets the duration of the audio file
-        /// </summary>
-        /// <param name="filePath">The name of the audio file</param>
-        /// <returns>track duration</returns>
-        public double getDuration(string filePath)
-        {
-            if (this.recorder != null)
-            {
-                return (-2);
-            }
-
-            if (this.player != null)
-            {
-                return this.duration;
-
-            }
-            else
-            {
-                this.prepareOnly = true;
-                this.startPlaying(filePath);
-                return this.duration;
-            }
-        }
-
-        /// <summary>
-        /// Sets the state and send it to JavaScript
-        /// </summary>
-        /// <param name="state">state</param>
-        private void SetState(int state)
-        {
-            if (this.state != state)
-            {
-                InvokeCallback(MediaState, state, false);
-                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaState, state),false);
-            }
-
-            this.state = state;
-        }
-
-        #region record methods
-
-        /// <summary>
-        /// Copies data from recorder to memory storages and updates recording state
-        /// </summary>
-        /// <param name="sender"></param>
-        /// <param name="e"></param>
-        private void recorderBufferReady(object sender, EventArgs e)
-        {
-            this.recorder.GetData(this.buffer);
-            this.memoryStream.Write(this.buffer, 0, this.buffer.Length);
-        }
-
-        /// <summary>
-        /// Writes audio data from memory to isolated storage
-        /// </summary>
-        /// <returns></returns>
-        private void SaveAudioClipToLocalStorage()
-        {
-            if (memoryStream == null || memoryStream.Length <= 0)
-            {
-                return;
-            }
-
-            long position = memoryStream.Position;
-            memoryStream.Seek(4, SeekOrigin.Begin);
-            memoryStream.Write(BitConverter.GetBytes((int)memoryStream.Length - 8), 0, 4);
-            memoryStream.Seek(40, SeekOrigin.Begin);
-            memoryStream.Write(BitConverter.GetBytes((int)memoryStream.Length - 44), 0, 4);
-            memoryStream.Seek(position, SeekOrigin.Begin);
-
-            try
-            {
-                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                {
-                    string directory = Path.GetDirectoryName(audioFile);
-
-                    if (!isoFile.DirectoryExists(directory))
-                    {
-                        isoFile.CreateDirectory(directory);
-                    }
-
-                    this.memoryStream.Seek(0, SeekOrigin.Begin);
-
-                    using (IsolatedStorageFileStream fileStream = isoFile.CreateFile(audioFile))
-                    {
-                        this.memoryStream.CopyTo(fileStream);
-                    }
-                }
-            }
-            catch (Exception)
-            {
-                //TODO: log or do something else
-                throw;
-            }
-        }
-
-        #region Xna loop
-        /// <summary>
-        /// Special initialization required for the microphone: XNA game loop
-        /// </summary>
-        private void InitializeXnaGameLoop()
-        {
-            // Timer to simulate the XNA game loop (Microphone is from XNA)
-            this.dtXna = new DispatcherTimer();
-            this.dtXna.Interval = TimeSpan.FromMilliseconds(33);
-            this.dtXna.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
-            this.dtXna.Start();
-        }
-        /// <summary>
-        /// Finalizes XNA game loop for microphone
-        /// </summary>
-        private void FinalizeXnaGameLoop()
-        {
-            // Timer to simulate the XNA game loop (Microphone is from XNA)
-            if (this.dtXna != null)
-            {
-                this.dtXna.Stop();
-                this.dtXna = null;
-            }
-        }
-
-        #endregion
-
-        #endregion
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/blob/155284bb/src/wp8/Media.cs
----------------------------------------------------------------------
diff --git a/src/wp8/Media.cs b/src/wp8/Media.cs
deleted file mode 100644
index 5de4884..0000000
--- a/src/wp8/Media.cs
+++ /dev/null
@@ -1,547 +0,0 @@
-/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-using System.Windows;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    /// <summary>
-    /// Provides the ability to record and play back audio files on a device. 
-    /// </summary>
-    public class Media : BaseCommand
-    {
-        /// <summary>
-        /// Audio player objects
-        /// </summary>
-        private static Dictionary<string, AudioPlayer> players = new Dictionary<string, AudioPlayer>();
-
-        /// <summary>
-        /// Represents Media action options.
-        /// </summary>
-        [DataContract]
-        public class MediaOptions
-        {
-            /// <summary>
-            /// Audio id
-            /// </summary>
-            [DataMember(Name = "id", IsRequired = true)]
-            public string Id { get; set; }
-
-            /// <summary>
-            /// Path to audio file
-            /// </summary>
-            [DataMember(Name = "src")]
-            public string Src { get; set; }
-
-            /// <summary>
-            /// New track position
-            /// </summary>
-            [DataMember(Name = "milliseconds")]
-            public int Milliseconds { get; set; }
-        }
-
-        /// <summary>
-        /// Releases the audio player instance to save memory.
-        /// </summary>  
-        public void release(string options)
-        {
-            try
-            {
-                MediaOptions mediaOptions;
-
-                try
-                {
-                    string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
-                    mediaOptions = new MediaOptions();
-                    mediaOptions.Id = optionsString[0];
-                }
-                catch (Exception)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                    return;
-                }
-
-                if (!Media.players.ContainsKey(mediaOptions.Id))
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, false));
-                    return;
-                }
-
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    try
-                    {
-                        AudioPlayer audio = Media.players[mediaOptions.Id];
-                        Media.players.Remove(mediaOptions.Id);
-                        audio.Dispose();
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, true));
-                    }
-                    catch (Exception e)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                    }
-                });
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-            }
-        }
-
-        /// <summary>
-        /// Starts recording and save the specified file 
-        /// </summary>
-        public void startRecordingAudio(string options)
-        {
-            try
-            {
-                MediaOptions mediaOptions;
-
-                try
-                {
-                    string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
-                    mediaOptions = new MediaOptions();
-                    mediaOptions.Id = optionsString[0];
-                    mediaOptions.Src = optionsString[1];
-                }
-                catch (Exception)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                    return;
-                }
-
-                if (mediaOptions != null)
-                {
-
-                    Deployment.Current.Dispatcher.BeginInvoke(() =>
-                    {
-                        try
-                        {
-                            AudioPlayer audio;
-                            if (!Media.players.ContainsKey(mediaOptions.Id))
-                            {
-                                audio = new AudioPlayer(this, mediaOptions.Id);
-                                Media.players.Add(mediaOptions.Id, audio);
-                            }
-                            else
-                            {
-                                audio = Media.players[mediaOptions.Id];
-                            }
-
-                            if (audio != null)
-                            {
-                                audio.startRecording(mediaOptions.Src);
-                                DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-                            }
-                            else
-                            {
-                                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error accessing AudioPlayer for key " + mediaOptions.Id));
-                            }
-                            
-                            
-                        }
-                        catch (Exception e)
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                        }
-
-                    });
-                }
-                else
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                }
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-            }
-        }
-
-        /// <summary>
-        /// Stops recording and save to the file specified when recording started 
-        /// </summary>
-        public void stopRecordingAudio(string options)
-        {
-            try
-            {
-                string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    try
-                    {
-                        if (Media.players.ContainsKey(mediaId))
-                        {
-                            AudioPlayer audio = Media.players[mediaId];
-                            audio.stopRecording();
-                            Media.players.Remove(mediaId);
-                        }
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-                    }
-                    catch (Exception e)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                    }
-                });
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-            }
-        }
-
-        public void setVolume(string options) // id,volume
-        {
-            try
-            {
-                string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
-                string id = optionsString[0];
-                double volume = double.Parse(optionsString[1]);
-
-                if (Media.players.ContainsKey(id))
-                {
-                    Deployment.Current.Dispatcher.BeginInvoke(() =>
-                    {
-                        try
-                        {
-                            AudioPlayer player = Media.players[id];
-                            player.setVolume(volume);
-                        }
-                        catch (Exception e)
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                        }
-                    });
-                }
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Error parsing options into setVolume method"));
-                return;
-            }
-        }
-
-        // Some Audio Notes:
-        // In the Windows Phone Emulator, playback of video or audio content using the MediaElement control is not supported.
-        // While playing, a MediaElement stops all other media playback on the phone.
-        // Multiple MediaElement controls are NOT supported
-
-        // Called when you create a new Media('blah') object in JS.
-        public void create(string options)
-        {
-            // Debug.WriteLine("Creating Audio :: " + options);
-            try
-            {
-                MediaOptions mediaOptions;
-                try
-                {
-                    string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
-                    mediaOptions = new MediaOptions();
-                    mediaOptions.Id = optionsString[0];
-                    mediaOptions.Src = optionsString[1];
-                }
-                catch (Exception)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Error parsing options into create method"));
-                    return;
-                }
-
-                AudioPlayer audio = new AudioPlayer(this, mediaOptions.Id);
-                Media.players.Add(mediaOptions.Id, audio);
-                DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-            }
-        }
-
-        /// <summary>
-        /// Starts or resume playing audio file 
-        /// </summary>
-        public void startPlayingAudio(string options)
-        {
-            try
-            {
-                MediaOptions mediaOptions;
-                try
-                {
-                    string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
-                    mediaOptions = new MediaOptions();
-                    mediaOptions.Id = optionsString[0];
-                    mediaOptions.Src = optionsString[1];
-                    if (optionsString.Length > 2 && optionsString[2] != null)
-                    {
-                        mediaOptions.Milliseconds = int.Parse(optionsString[2]);
-                    }
-
-                }
-                catch (Exception)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                    return;
-                }
-
-                AudioPlayer audio;
-
-                if (!Media.players.ContainsKey(mediaOptions.Id))
-                {
-                    audio = new AudioPlayer(this, mediaOptions.Id);
-                    Media.players.Add(mediaOptions.Id, audio);
-                }
-                else
-                {
-                    //Debug.WriteLine("INFO: startPlayingAudio FOUND mediaPlayer for " + mediaOptions.Id);
-                    audio = Media.players[mediaOptions.Id];
-                }
-
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    try
-                    {
-                        audio.startPlaying(mediaOptions.Src);
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-                    }
-                    catch (Exception e)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                    }
-                });
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-            }
-        }
-
-
-        /// <summary>
-        /// Seeks to a location
-        /// </summary>
-        public void seekToAudio(string options)
-        {
-            try
-            {
-                MediaOptions mediaOptions;
-
-                try
-                {
-                    string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
-                    mediaOptions = new MediaOptions();
-                    mediaOptions.Id = optionsString[0];
-                    if (optionsString.Length > 1 && optionsString[1] != null)
-                    {
-                        mediaOptions.Milliseconds = int.Parse(optionsString[1]);
-                    }
-                }
-                catch (Exception)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                    return;
-                }
-
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    try
-                    {
-                        if (Media.players.ContainsKey(mediaOptions.Id))
-                        {
-                            AudioPlayer audio = Media.players[mediaOptions.Id];
-                            audio.seekToPlaying(mediaOptions.Milliseconds);
-                        }
-                        else
-                        {
-                            Debug.WriteLine("ERROR: seekToAudio could not find mediaPlayer for " + mediaOptions.Id);
-                        }
-
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-                    }
-                    catch (Exception e)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                    }
-                });
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-            }
-        }
-
-        /// <summary>
-        /// Pauses playing 
-        /// </summary>
-        public void pausePlayingAudio(string options)
-        {
-
-            try
-            {
-                string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
-
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    try
-                    {
-                        if (Media.players.ContainsKey(mediaId))
-                        {
-                            AudioPlayer audio = Media.players[mediaId];
-                            audio.pausePlaying();
-                        }
-                        else
-                        {
-                            Debug.WriteLine("ERROR: pausePlayingAudio could not find mediaPlayer for " + mediaId);
-                        }
-
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-                    }
-                    catch (Exception e)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                    }
-                });
-
-
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-            }
-
-
-        }
-
-
-        /// <summary>
-        /// Stops playing the audio file
-        /// </summary>
-        public void stopPlayingAudio(String options)
-        {
-            try
-            {
-                string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    try
-                    {
-                        if (Media.players.ContainsKey(mediaId))
-                        {
-                            AudioPlayer audio = Media.players[mediaId];
-                            audio.stopPlaying();
-                        }
-                        else
-                        {
-                            Debug.WriteLine("stopPlaying could not find mediaPlayer for " + mediaId);
-                        }
-
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
-                    }
-                    catch (Exception e)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                    }
-                });
-
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-            }
-        }
-
-        /// <summary>
-        /// Gets current position of playback
-        /// </summary>
-        public void getCurrentPositionAudio(string options)
-        {
-            try
-            {
-                string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    try
-                    {
-                        if (Media.players.ContainsKey(mediaId))
-                        {
-                            AudioPlayer audio = Media.players[mediaId];
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getCurrentPosition()));
-                        }
-                        else
-                        {
-                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, -1));
-                        }
-                    }
-                    catch (Exception e)
-                    {
-                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-                    }
-                });
-            }
-            catch (Exception)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                return;
-            }
-        }
-
-
-        /// <summary>
-        /// Gets the duration of the audio file
-        /// </summary>
-        
-        [Obsolete("This method will be removed shortly")]
-        public void getDurationAudio(string options)
-        {
-            try
-            {
-                MediaOptions mediaOptions;
-
-                try
-                {
-                    mediaOptions = JSON.JsonHelper.Deserialize<MediaOptions>(options);
-                }
-                catch (Exception)
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
-                    return;
-                }
-
-                AudioPlayer audio;
-                if (Media.players.ContainsKey(mediaOptions.Id))
-                {
-                    audio = Media.players[mediaOptions.Id];
-                }
-                else
-                {
-                    Debug.WriteLine("ERROR: getDurationAudio could not find mediaPlayer for " + mediaOptions.Id);
-                    audio = new AudioPlayer(this, mediaOptions.Id);
-                    Media.players.Add(mediaOptions.Id, audio);
-                }
-
-                Deployment.Current.Dispatcher.BeginInvoke(() =>
-                {
-                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getDuration(mediaOptions.Src)));
-                });
-            }
-            catch (Exception e)
-            {
-                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
-            }
-        }
-    }
-}


[2/2] git commit: [CB-4127] remove dupe code

Posted by pu...@apache.org.
[CB-4127] remove dupe code


Project: http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/commit/155284bb
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/tree/155284bb
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/diff/155284bb

Branch: refs/heads/master
Commit: 155284bbadb8654689ac352e69e030fb026d5bf2
Parents: f8b2f95
Author: Jesse MacFadyen <pu...@gmail.com>
Authored: Mon Jul 8 16:28:19 2013 -0700
Committer: Jesse MacFadyen <pu...@gmail.com>
Committed: Mon Jul 8 16:28:19 2013 -0700

----------------------------------------------------------------------
 plugin.xml             |   8 +-
 src/wp/AudioPlayer.cs  | 647 ++++++++++++++++++++++++++++++++++++++++++++
 src/wp/Media.cs        | 547 +++++++++++++++++++++++++++++++++++++
 src/wp7/AudioPlayer.cs | 647 --------------------------------------------
 src/wp7/Media.cs       | 532 ------------------------------------
 src/wp8/AudioPlayer.cs | 647 --------------------------------------------
 src/wp8/Media.cs       | 547 -------------------------------------
 7 files changed, 1198 insertions(+), 2377 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/blob/155284bb/plugin.xml
----------------------------------------------------------------------
diff --git a/plugin.xml b/plugin.xml
index adbe998..d81be4d 100644
--- a/plugin.xml
+++ b/plugin.xml
@@ -64,8 +64,8 @@ id="org.apache.cordova.core.AudioHandler"
             <Capability Name="ID_CAP_MICROPHONE"/>
         </config-file>
 
-        <source-file src="src/wp7/Media.cs" />
-        <source-file src="src/wp7/AudioPlayer.cs" />
+        <source-file src="src/wp/Media.cs" />
+        <source-file src="src/wp/AudioPlayer.cs" />
     </platform>
 
     <!-- wp8 -->
@@ -82,8 +82,8 @@ id="org.apache.cordova.core.AudioHandler"
             <Capability Name="ID_CAP_MICROPHONE"/>
         </config-file>
 
-        <source-file src="src/wp8/Media.cs" />
-        <source-file src="src/wp8/AudioPlayer.cs" />
+        <source-file src="src/wp/Media.cs" />
+        <source-file src="src/wp/AudioPlayer.cs" />
     </platform>
     
             

http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/blob/155284bb/src/wp/AudioPlayer.cs
----------------------------------------------------------------------
diff --git a/src/wp/AudioPlayer.cs b/src/wp/AudioPlayer.cs
new file mode 100644
index 0000000..882eb96
--- /dev/null
+++ b/src/wp/AudioPlayer.cs
@@ -0,0 +1,647 @@
+/*  
+	Licensed under the Apache License, Version 2.0 (the "License");
+	you may not use this file except in compliance with the License.
+	You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+	
+	Unless required by applicable law or agreed to in writing, software
+	distributed under the License is distributed on an "AS IS" BASIS,
+	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+	See the License for the specific language governing permissions and
+	limitations under the License.
+*/
+
+using System;
+using System.IO;
+using System.IO.IsolatedStorage;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Threading;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Audio;
+using Microsoft.Xna.Framework.Media;
+using Microsoft.Phone.Controls;
+using System.Diagnostics;
+using System.Windows.Resources;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+
+    /// <summary>
+    /// Implements audio record and play back functionality.
+    /// </summary>
+    internal class AudioPlayer : IDisposable
+    {
+        #region Constants
+
+        // AudioPlayer states
+        private const int PlayerState_None = 0;
+        private const int PlayerState_Starting = 1;
+        private const int PlayerState_Running = 2;
+        private const int PlayerState_Paused = 3;
+        private const int PlayerState_Stopped = 4;
+
+        // AudioPlayer messages
+        private const int MediaState = 1;
+        private const int MediaDuration = 2;
+        private const int MediaPosition = 3;
+        private const int MediaError = 9;
+
+        // AudioPlayer errors
+        private const int MediaErrorPlayModeSet = 1;
+        private const int MediaErrorAlreadyRecording = 2;
+        private const int MediaErrorStartingRecording = 3;
+        private const int MediaErrorRecordModeSet = 4;
+        private const int MediaErrorStartingPlayback = 5;
+        private const int MediaErrorResumeState = 6;
+        private const int MediaErrorPauseState = 7;
+        private const int MediaErrorStopState = 8;
+
+        //TODO: get rid of this callback, it should be universal
+        //private const string CallbackFunction = "CordovaMediaonStatus";
+
+        #endregion
+
+
+        /// <summary>
+        /// The AudioHandler object
+        /// </summary>
+        private Media handler;
+
+        /// <summary>
+        /// Temporary buffer to store audio chunk
+        /// </summary>
+        private byte[] buffer;
+
+        /// <summary>
+        /// Xna game loop dispatcher
+        /// </summary>
+        DispatcherTimer dtXna;
+
+
+        /// <summary>
+        /// Output buffer
+        /// </summary>
+        private MemoryStream memoryStream;
+
+        /// <summary>
+        /// The id of this player (used to identify Media object in JavaScript)
+        /// </summary>
+        private String id;
+
+        /// <summary>
+        /// State of recording or playback
+        /// </summary>
+        private int state = PlayerState_None;
+
+        /// <summary>
+        /// File name to play or record to
+        /// </summary>
+        private String audioFile = null;
+
+        /// <summary>
+        /// Duration of audio
+        /// </summary>
+        private double duration = -1;
+
+        /// <summary>
+        /// Audio player object
+        /// </summary>
+        private MediaElement player = null;
+
+        /// <summary>
+        /// Audio source
+        /// </summary>
+        private Microphone recorder;
+
+        /// <summary>
+        /// Internal flag specified that we should only open audio w/o playing it
+        /// </summary>
+        private bool prepareOnly = false;
+
+        /// <summary>
+        /// Creates AudioPlayer instance
+        /// </summary>
+        /// <param name="handler">Media object</param>
+        /// <param name="id">player id</param>
+        public AudioPlayer(Media handler, String id)
+        {
+            this.handler = handler;
+            this.id = id;
+        }
+
+
+        /// <summary>
+        /// Destroys player and stop audio playing or recording
+        /// </summary>
+        public void Dispose()
+        {
+            if (this.player != null)
+            {
+                this.stopPlaying();
+                this.player = null;
+            }
+            if (this.recorder != null)
+            {
+                this.stopRecording();
+                this.recorder = null;
+            }
+
+            this.FinalizeXnaGameLoop();
+        }
+
+        private void InvokeCallback(int message, string value, bool removeHandler)
+        {
+            string args = string.Format("('{0}',{1},{2});", this.id, message, value);
+            string callback = @"(function(id,msg,value){
+                try {
+                    if (msg == Media.MEDIA_ERROR) {
+                        value = {'code':value};
+                    }
+                    Media.onStatus(id,msg,value);
+                }
+                catch(e) {
+                    console.log('Error calling Media.onStatus :: ' + e);
+                }
+            })" + args;
+            this.handler.InvokeCustomScript(new ScriptCallback("eval", new string[] { callback }), false);
+        }
+
+        private void InvokeCallback(int message, int value, bool removeHandler)
+        {
+            InvokeCallback(message, value.ToString(), removeHandler);
+        }
+
+        private void InvokeCallback(int message, double value, bool removeHandler)
+        {
+            InvokeCallback(message, value.ToString(), removeHandler);
+        }
+
+        /// <summary>
+        /// Starts recording, data is stored in memory
+        /// </summary>
+        /// <param name="filePath"></param>
+        public void startRecording(string filePath)
+        {
+            if (this.player != null)
+            {
+                InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
+            }
+            else if (this.recorder == null)
+            {
+                try
+                {
+                    this.audioFile = filePath;
+                    this.InitializeXnaGameLoop();
+                    this.recorder = Microphone.Default;
+                    this.recorder.BufferDuration = TimeSpan.FromMilliseconds(500);
+                    this.buffer = new byte[recorder.GetSampleSizeInBytes(this.recorder.BufferDuration)];
+                    this.recorder.BufferReady += new EventHandler<EventArgs>(recorderBufferReady);
+                    MemoryStream stream  = new MemoryStream();
+                    this.memoryStream = stream;
+                    int numBits = 16;
+                    int numBytes = numBits / 8;
+
+                    // inline version from AudioFormatsHelper
+                    stream.Write(System.Text.Encoding.UTF8.GetBytes("RIFF"), 0, 4);
+                    stream.Write(BitConverter.GetBytes(0), 0, 4);
+                    stream.Write(System.Text.Encoding.UTF8.GetBytes("WAVE"), 0, 4);
+                    stream.Write(System.Text.Encoding.UTF8.GetBytes("fmt "), 0, 4);
+                    stream.Write(BitConverter.GetBytes(16), 0, 4);
+                    stream.Write(BitConverter.GetBytes((short)1), 0, 2);
+                    stream.Write(BitConverter.GetBytes((short)1), 0, 2);
+                    stream.Write(BitConverter.GetBytes(this.recorder.SampleRate), 0, 4);
+                    stream.Write(BitConverter.GetBytes(this.recorder.SampleRate * numBytes), 0, 4);
+                    stream.Write(BitConverter.GetBytes((short)(numBytes)), 0, 2);
+                    stream.Write(BitConverter.GetBytes((short)(numBits)), 0, 2);
+                    stream.Write(System.Text.Encoding.UTF8.GetBytes("data"), 0, 4);
+                    stream.Write(BitConverter.GetBytes(0), 0, 4);
+
+                    this.recorder.Start();
+                    FrameworkDispatcher.Update();
+                    this.SetState(PlayerState_Running);
+                }
+                catch (Exception)
+                {
+                    InvokeCallback(MediaError, MediaErrorStartingRecording, false);
+                    //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingRecording),false);
+                }
+            }
+            else
+            {
+                InvokeCallback(MediaError, MediaErrorAlreadyRecording, false);
+                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorAlreadyRecording),false);
+            }
+        }
+
+        /// <summary>
+        /// Stops recording
+        /// </summary>
+        public void stopRecording()
+        {
+            if (this.recorder != null)
+            {
+                if (this.state == PlayerState_Running)
+                {
+                    try
+                    {
+                        this.recorder.Stop();
+                        this.recorder.BufferReady -= recorderBufferReady;
+                        this.recorder = null;
+                        SaveAudioClipToLocalStorage();
+                        this.FinalizeXnaGameLoop();
+                        this.SetState(PlayerState_Stopped);
+                    }
+                    catch (Exception)
+                    {
+                        //TODO 
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// Starts or resume playing audio file
+        /// </summary>
+        /// <param name="filePath">The name of the audio file</param>
+        /// <summary>
+        /// Starts or resume playing audio file
+        /// </summary>
+        /// <param name="filePath">The name of the audio file</param>
+        public void startPlaying(string filePath)
+        {
+            if (this.recorder != null)
+            {
+                InvokeCallback(MediaError, MediaErrorRecordModeSet, false);
+                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorRecordModeSet),false);
+                return;
+            }
+
+
+            if (this.player == null || this.player.Source.AbsolutePath.LastIndexOf(filePath) < 0)
+            {
+                try
+                {
+                    // this.player is a MediaElement, it must be added to the visual tree in order to play
+                    PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
+                    if (frame != null)
+                    {
+                        PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
+                        if (page != null)
+                        {
+                            Grid grid = page.FindName("LayoutRoot") as Grid;
+                            if (grid != null)
+                            {
+
+                                this.player = grid.FindName("playerMediaElement") as MediaElement;
+                                if (this.player == null) // still null ?
+                                {
+                                    this.player = new MediaElement();
+                                    this.player.Name = "playerMediaElement";
+                                    grid.Children.Add(this.player);
+                                    this.player.Visibility = Visibility.Visible;
+                                }
+                                if (this.player.CurrentState == System.Windows.Media.MediaElementState.Playing)
+                                {
+                                    this.player.Stop(); // stop it!
+                                }
+
+                                this.player.Source = null; // Garbage collect it.
+                                this.player.MediaOpened += MediaOpened;
+                                this.player.MediaEnded += MediaEnded;
+                                this.player.MediaFailed += MediaFailed;
+                            }
+                        }
+                    }
+
+                    this.audioFile = filePath;
+
+                    Uri uri = new Uri(filePath, UriKind.RelativeOrAbsolute);
+                    if (uri.IsAbsoluteUri)
+                    {
+                        this.player.Source = uri;
+                    }
+                    else
+                    {
+                        using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+                        {
+                            if (!isoFile.FileExists(filePath))
+                            {
+                                // try to unpack it from the dll into isolated storage
+                                StreamResourceInfo fileResourceStreamInfo = Application.GetResourceStream(new Uri(filePath, UriKind.Relative));
+                                if (fileResourceStreamInfo != null)
+                                {
+                                    using (BinaryReader br = new BinaryReader(fileResourceStreamInfo.Stream))
+                                    {
+                                        byte[] data = br.ReadBytes((int)fileResourceStreamInfo.Stream.Length);
+
+                                        string[] dirParts = filePath.Split('/');
+                                        string dirName = "";
+                                        for (int n = 0; n < dirParts.Length - 1; n++)
+                                        {
+                                            dirName += dirParts[n] + "/";
+                                        }
+                                        if (!isoFile.DirectoryExists(dirName))
+                                        {
+                                            isoFile.CreateDirectory(dirName);
+                                        }
+
+                                        using (IsolatedStorageFileStream outFile = isoFile.OpenFile(filePath, FileMode.Create))
+                                        {
+                                            using (BinaryWriter writer = new BinaryWriter(outFile))
+                                            {
+                                                writer.Write(data);
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                            if (isoFile.FileExists(filePath))
+                            {
+                                using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, isoFile))
+                                {
+                                    this.player.SetSource(stream);
+                                }
+                            }
+                            else
+                            {
+                                InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
+                                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, 1), false);
+                                return;
+                            }
+                        }
+                    }
+                    this.SetState(PlayerState_Starting);
+                }
+                catch (Exception e)
+                {
+                    Debug.WriteLine("Error in AudioPlayer::startPlaying : " + e.Message);
+                    InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
+                    //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingPlayback),false);
+                }
+            }
+            else
+            {
+                if (this.state != PlayerState_Running)
+                {
+                    this.player.Play();
+                    this.SetState(PlayerState_Running);
+                }
+                else
+                {
+                    InvokeCallback(MediaError, MediaErrorResumeState, false);
+                    //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorResumeState),false);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Callback to be invoked when the media source is ready for playback
+        /// </summary>
+        private void MediaOpened(object sender, RoutedEventArgs arg)
+        {
+            if (this.player != null)
+            {
+                this.duration = this.player.NaturalDuration.TimeSpan.TotalSeconds;
+                InvokeCallback(MediaDuration, this.duration, false);
+                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaDuration, this.duration),false);
+                if (!this.prepareOnly)
+                {
+                    this.player.Play();
+                    this.SetState(PlayerState_Running);
+                }
+                this.prepareOnly = false;
+            }
+            else
+            {
+                // TODO: occasionally MediaOpened is signalled, but player is null
+            }
+        }
+
+        /// <summary>
+        /// Callback to be invoked when playback of a media source has completed
+        /// </summary>
+        private void MediaEnded(object sender, RoutedEventArgs arg)
+        {
+            this.SetState(PlayerState_Stopped);
+        }
+
+        /// <summary>
+        /// Callback to be invoked when playback of a media source has failed
+        /// </summary>
+        private void MediaFailed(object sender, RoutedEventArgs arg)
+        {
+            player.Stop();
+            InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
+            //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError.ToString(), "Media failed"),false);
+        }
+
+        /// <summary>
+        /// Seek or jump to a new time in the track
+        /// </summary>
+        /// <param name="milliseconds">The new track position</param>
+        public void seekToPlaying(int milliseconds)
+        {
+            if (this.player != null)
+            {
+                TimeSpan tsPos = new TimeSpan(0, 0, 0, 0, milliseconds);
+                this.player.Position = tsPos;
+                InvokeCallback(MediaPosition, milliseconds / 1000.0f, false);
+                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, milliseconds / 1000.0f),false);
+            }
+        }
+
+        /// <summary>
+        /// Set the volume of the player
+        /// </summary>
+        /// <param name="vol">volume 0.0-1.0, default value is 0.5</param>
+        public void setVolume(double vol)
+        {
+            if (this.player != null)
+            {
+                this.player.Volume = vol;
+            }
+        }
+
+        /// <summary>
+        /// Pauses playing
+        /// </summary>
+        public void pausePlaying()
+        {
+            if (this.state == PlayerState_Running)
+            {
+                this.player.Pause();
+                this.SetState(PlayerState_Paused);
+            }
+            else
+            {
+                InvokeCallback(MediaError, MediaErrorPauseState, false);
+                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorPauseState),false);
+            }
+        }
+
+
+        /// <summary>
+        /// Stops playing the audio file
+        /// </summary>
+        public void stopPlaying()
+        {
+            if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
+            {
+                this.player.Stop();
+
+                this.player.Position = new TimeSpan(0L);
+                this.SetState(PlayerState_Stopped);
+            }
+            //else // Why is it an error to call stop on a stopped media?
+            //{
+            //    this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStopState), false);
+            //}
+        }
+
+        /// <summary>
+        /// Gets current position of playback
+        /// </summary>
+        /// <returns>current position</returns>
+        public double getCurrentPosition()
+        {
+            if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
+            {
+                double currentPosition = this.player.Position.TotalSeconds;
+                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, currentPosition),false);
+                return currentPosition;
+            }
+            else
+            {
+                return 0;
+            }
+        }
+
+        /// <summary>
+        /// Gets the duration of the audio file
+        /// </summary>
+        /// <param name="filePath">The name of the audio file</param>
+        /// <returns>track duration</returns>
+        public double getDuration(string filePath)
+        {
+            if (this.recorder != null)
+            {
+                return (-2);
+            }
+
+            if (this.player != null)
+            {
+                return this.duration;
+
+            }
+            else
+            {
+                this.prepareOnly = true;
+                this.startPlaying(filePath);
+                return this.duration;
+            }
+        }
+
+        /// <summary>
+        /// Sets the state and send it to JavaScript
+        /// </summary>
+        /// <param name="state">state</param>
+        private void SetState(int state)
+        {
+            if (this.state != state)
+            {
+                InvokeCallback(MediaState, state, false);
+                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaState, state),false);
+            }
+
+            this.state = state;
+        }
+
+        #region record methods
+
+        /// <summary>
+        /// Copies data from recorder to memory storages and updates recording state
+        /// </summary>
+        /// <param name="sender"></param>
+        /// <param name="e"></param>
+        private void recorderBufferReady(object sender, EventArgs e)
+        {
+            this.recorder.GetData(this.buffer);
+            this.memoryStream.Write(this.buffer, 0, this.buffer.Length);
+        }
+
+        /// <summary>
+        /// Writes audio data from memory to isolated storage
+        /// </summary>
+        /// <returns></returns>
+        private void SaveAudioClipToLocalStorage()
+        {
+            if (memoryStream == null || memoryStream.Length <= 0)
+            {
+                return;
+            }
+
+            long position = memoryStream.Position;
+            memoryStream.Seek(4, SeekOrigin.Begin);
+            memoryStream.Write(BitConverter.GetBytes((int)memoryStream.Length - 8), 0, 4);
+            memoryStream.Seek(40, SeekOrigin.Begin);
+            memoryStream.Write(BitConverter.GetBytes((int)memoryStream.Length - 44), 0, 4);
+            memoryStream.Seek(position, SeekOrigin.Begin);
+
+            try
+            {
+                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
+                {
+                    string directory = Path.GetDirectoryName(audioFile);
+
+                    if (!isoFile.DirectoryExists(directory))
+                    {
+                        isoFile.CreateDirectory(directory);
+                    }
+
+                    this.memoryStream.Seek(0, SeekOrigin.Begin);
+
+                    using (IsolatedStorageFileStream fileStream = isoFile.CreateFile(audioFile))
+                    {
+                        this.memoryStream.CopyTo(fileStream);
+                    }
+                }
+            }
+            catch (Exception)
+            {
+                //TODO: log or do something else
+                throw;
+            }
+        }
+
+        #region Xna loop
+        /// <summary>
+        /// Special initialization required for the microphone: XNA game loop
+        /// </summary>
+        private void InitializeXnaGameLoop()
+        {
+            // Timer to simulate the XNA game loop (Microphone is from XNA)
+            this.dtXna = new DispatcherTimer();
+            this.dtXna.Interval = TimeSpan.FromMilliseconds(33);
+            this.dtXna.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
+            this.dtXna.Start();
+        }
+        /// <summary>
+        /// Finalizes XNA game loop for microphone
+        /// </summary>
+        private void FinalizeXnaGameLoop()
+        {
+            // Timer to simulate the XNA game loop (Microphone is from XNA)
+            if (this.dtXna != null)
+            {
+                this.dtXna.Stop();
+                this.dtXna = null;
+            }
+        }
+
+        #endregion
+
+        #endregion
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/blob/155284bb/src/wp/Media.cs
----------------------------------------------------------------------
diff --git a/src/wp/Media.cs b/src/wp/Media.cs
new file mode 100644
index 0000000..5de4884
--- /dev/null
+++ b/src/wp/Media.cs
@@ -0,0 +1,547 @@
+/*  
+	Licensed under the Apache License, Version 2.0 (the "License");
+	you may not use this file except in compliance with the License.
+	You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+	
+	Unless required by applicable law or agreed to in writing, software
+	distributed under the License is distributed on an "AS IS" BASIS,
+	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+	See the License for the specific language governing permissions and
+	limitations under the License.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Windows;
+using System.Diagnostics;
+
+namespace WPCordovaClassLib.Cordova.Commands
+{
+    /// <summary>
+    /// Provides the ability to record and play back audio files on a device. 
+    /// </summary>
+    public class Media : BaseCommand
+    {
+        /// <summary>
+        /// Audio player objects
+        /// </summary>
+        private static Dictionary<string, AudioPlayer> players = new Dictionary<string, AudioPlayer>();
+
+        /// <summary>
+        /// Represents Media action options.
+        /// </summary>
+        [DataContract]
+        public class MediaOptions
+        {
+            /// <summary>
+            /// Audio id
+            /// </summary>
+            [DataMember(Name = "id", IsRequired = true)]
+            public string Id { get; set; }
+
+            /// <summary>
+            /// Path to audio file
+            /// </summary>
+            [DataMember(Name = "src")]
+            public string Src { get; set; }
+
+            /// <summary>
+            /// New track position
+            /// </summary>
+            [DataMember(Name = "milliseconds")]
+            public int Milliseconds { get; set; }
+        }
+
+        /// <summary>
+        /// Releases the audio player instance to save memory.
+        /// </summary>  
+        public void release(string options)
+        {
+            try
+            {
+                MediaOptions mediaOptions;
+
+                try
+                {
+                    string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
+                    mediaOptions = new MediaOptions();
+                    mediaOptions.Id = optionsString[0];
+                }
+                catch (Exception)
+                {
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+                    return;
+                }
+
+                if (!Media.players.ContainsKey(mediaOptions.Id))
+                {
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, false));
+                    return;
+                }
+
+                Deployment.Current.Dispatcher.BeginInvoke(() =>
+                {
+                    try
+                    {
+                        AudioPlayer audio = Media.players[mediaOptions.Id];
+                        Media.players.Remove(mediaOptions.Id);
+                        audio.Dispose();
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK, true));
+                    }
+                    catch (Exception e)
+                    {
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                    }
+                });
+            }
+            catch (Exception e)
+            {
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+            }
+        }
+
+        /// <summary>
+        /// Starts recording and save the specified file 
+        /// </summary>
+        public void startRecordingAudio(string options)
+        {
+            try
+            {
+                MediaOptions mediaOptions;
+
+                try
+                {
+                    string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
+                    mediaOptions = new MediaOptions();
+                    mediaOptions.Id = optionsString[0];
+                    mediaOptions.Src = optionsString[1];
+                }
+                catch (Exception)
+                {
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+                    return;
+                }
+
+                if (mediaOptions != null)
+                {
+
+                    Deployment.Current.Dispatcher.BeginInvoke(() =>
+                    {
+                        try
+                        {
+                            AudioPlayer audio;
+                            if (!Media.players.ContainsKey(mediaOptions.Id))
+                            {
+                                audio = new AudioPlayer(this, mediaOptions.Id);
+                                Media.players.Add(mediaOptions.Id, audio);
+                            }
+                            else
+                            {
+                                audio = Media.players[mediaOptions.Id];
+                            }
+
+                            if (audio != null)
+                            {
+                                audio.startRecording(mediaOptions.Src);
+                                DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+                            }
+                            else
+                            {
+                                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "Error accessing AudioPlayer for key " + mediaOptions.Id));
+                            }
+                            
+                            
+                        }
+                        catch (Exception e)
+                        {
+                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                        }
+
+                    });
+                }
+                else
+                {
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+                }
+            }
+            catch (Exception e)
+            {
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+            }
+        }
+
+        /// <summary>
+        /// Stops recording and save to the file specified when recording started 
+        /// </summary>
+        public void stopRecordingAudio(string options)
+        {
+            try
+            {
+                string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
+                Deployment.Current.Dispatcher.BeginInvoke(() =>
+                {
+                    try
+                    {
+                        if (Media.players.ContainsKey(mediaId))
+                        {
+                            AudioPlayer audio = Media.players[mediaId];
+                            audio.stopRecording();
+                            Media.players.Remove(mediaId);
+                        }
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+                    }
+                    catch (Exception e)
+                    {
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                    }
+                });
+            }
+            catch (Exception)
+            {
+                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+            }
+        }
+
+        public void setVolume(string options) // id,volume
+        {
+            try
+            {
+                string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
+                string id = optionsString[0];
+                double volume = double.Parse(optionsString[1]);
+
+                if (Media.players.ContainsKey(id))
+                {
+                    Deployment.Current.Dispatcher.BeginInvoke(() =>
+                    {
+                        try
+                        {
+                            AudioPlayer player = Media.players[id];
+                            player.setVolume(volume);
+                        }
+                        catch (Exception e)
+                        {
+                            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                        }
+                    });
+                }
+            }
+            catch (Exception)
+            {
+                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Error parsing options into setVolume method"));
+                return;
+            }
+        }
+
+        // Some Audio Notes:
+        // In the Windows Phone Emulator, playback of video or audio content using the MediaElement control is not supported.
+        // While playing, a MediaElement stops all other media playback on the phone.
+        // Multiple MediaElement controls are NOT supported
+
+        // Called when you create a new Media('blah') object in JS.
+        public void create(string options)
+        {
+            // Debug.WriteLine("Creating Audio :: " + options);
+            try
+            {
+                MediaOptions mediaOptions;
+                try
+                {
+                    string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
+                    mediaOptions = new MediaOptions();
+                    mediaOptions.Id = optionsString[0];
+                    mediaOptions.Src = optionsString[1];
+                }
+                catch (Exception)
+                {
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, "Error parsing options into create method"));
+                    return;
+                }
+
+                AudioPlayer audio = new AudioPlayer(this, mediaOptions.Id);
+                Media.players.Add(mediaOptions.Id, audio);
+                DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+
+            }
+            catch (Exception e)
+            {
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+            }
+        }
+
+        /// <summary>
+        /// Starts or resume playing audio file 
+        /// </summary>
+        public void startPlayingAudio(string options)
+        {
+            try
+            {
+                MediaOptions mediaOptions;
+                try
+                {
+                    string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
+                    mediaOptions = new MediaOptions();
+                    mediaOptions.Id = optionsString[0];
+                    mediaOptions.Src = optionsString[1];
+                    if (optionsString.Length > 2 && optionsString[2] != null)
+                    {
+                        mediaOptions.Milliseconds = int.Parse(optionsString[2]);
+                    }
+
+                }
+                catch (Exception)
+                {
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+                    return;
+                }
+
+                AudioPlayer audio;
+
+                if (!Media.players.ContainsKey(mediaOptions.Id))
+                {
+                    audio = new AudioPlayer(this, mediaOptions.Id);
+                    Media.players.Add(mediaOptions.Id, audio);
+                }
+                else
+                {
+                    //Debug.WriteLine("INFO: startPlayingAudio FOUND mediaPlayer for " + mediaOptions.Id);
+                    audio = Media.players[mediaOptions.Id];
+                }
+
+                Deployment.Current.Dispatcher.BeginInvoke(() =>
+                {
+                    try
+                    {
+                        audio.startPlaying(mediaOptions.Src);
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+                    }
+                    catch (Exception e)
+                    {
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                    }
+                });
+            }
+            catch (Exception e)
+            {
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+            }
+        }
+
+
+        /// <summary>
+        /// Seeks to a location
+        /// </summary>
+        public void seekToAudio(string options)
+        {
+            try
+            {
+                MediaOptions mediaOptions;
+
+                try
+                {
+                    string[] optionsString = JSON.JsonHelper.Deserialize<string[]>(options);
+                    mediaOptions = new MediaOptions();
+                    mediaOptions.Id = optionsString[0];
+                    if (optionsString.Length > 1 && optionsString[1] != null)
+                    {
+                        mediaOptions.Milliseconds = int.Parse(optionsString[1]);
+                    }
+                }
+                catch (Exception)
+                {
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+                    return;
+                }
+
+                Deployment.Current.Dispatcher.BeginInvoke(() =>
+                {
+                    try
+                    {
+                        if (Media.players.ContainsKey(mediaOptions.Id))
+                        {
+                            AudioPlayer audio = Media.players[mediaOptions.Id];
+                            audio.seekToPlaying(mediaOptions.Milliseconds);
+                        }
+                        else
+                        {
+                            Debug.WriteLine("ERROR: seekToAudio could not find mediaPlayer for " + mediaOptions.Id);
+                        }
+
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+                    }
+                    catch (Exception e)
+                    {
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                    }
+                });
+            }
+            catch (Exception e)
+            {
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+            }
+        }
+
+        /// <summary>
+        /// Pauses playing 
+        /// </summary>
+        public void pausePlayingAudio(string options)
+        {
+
+            try
+            {
+                string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
+
+                Deployment.Current.Dispatcher.BeginInvoke(() =>
+                {
+                    try
+                    {
+                        if (Media.players.ContainsKey(mediaId))
+                        {
+                            AudioPlayer audio = Media.players[mediaId];
+                            audio.pausePlaying();
+                        }
+                        else
+                        {
+                            Debug.WriteLine("ERROR: pausePlayingAudio could not find mediaPlayer for " + mediaId);
+                        }
+
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+                    }
+                    catch (Exception e)
+                    {
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                    }
+                });
+
+
+            }
+            catch (Exception)
+            {
+                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+            }
+
+
+        }
+
+
+        /// <summary>
+        /// Stops playing the audio file
+        /// </summary>
+        public void stopPlayingAudio(String options)
+        {
+            try
+            {
+                string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
+                Deployment.Current.Dispatcher.BeginInvoke(() =>
+                {
+                    try
+                    {
+                        if (Media.players.ContainsKey(mediaId))
+                        {
+                            AudioPlayer audio = Media.players[mediaId];
+                            audio.stopPlaying();
+                        }
+                        else
+                        {
+                            Debug.WriteLine("stopPlaying could not find mediaPlayer for " + mediaId);
+                        }
+
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
+                    }
+                    catch (Exception e)
+                    {
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                    }
+                });
+
+            }
+            catch (Exception)
+            {
+                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+            }
+        }
+
+        /// <summary>
+        /// Gets current position of playback
+        /// </summary>
+        public void getCurrentPositionAudio(string options)
+        {
+            try
+            {
+                string mediaId = JSON.JsonHelper.Deserialize<string[]>(options)[0];
+                Deployment.Current.Dispatcher.BeginInvoke(() =>
+                {
+                    try
+                    {
+                        if (Media.players.ContainsKey(mediaId))
+                        {
+                            AudioPlayer audio = Media.players[mediaId];
+                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getCurrentPosition()));
+                        }
+                        else
+                        {
+                            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, -1));
+                        }
+                    }
+                    catch (Exception e)
+                    {
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+                    }
+                });
+            }
+            catch (Exception)
+            {
+                DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+                return;
+            }
+        }
+
+
+        /// <summary>
+        /// Gets the duration of the audio file
+        /// </summary>
+        
+        [Obsolete("This method will be removed shortly")]
+        public void getDurationAudio(string options)
+        {
+            try
+            {
+                MediaOptions mediaOptions;
+
+                try
+                {
+                    mediaOptions = JSON.JsonHelper.Deserialize<MediaOptions>(options);
+                }
+                catch (Exception)
+                {
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+                    return;
+                }
+
+                AudioPlayer audio;
+                if (Media.players.ContainsKey(mediaOptions.Id))
+                {
+                    audio = Media.players[mediaOptions.Id];
+                }
+                else
+                {
+                    Debug.WriteLine("ERROR: getDurationAudio could not find mediaPlayer for " + mediaOptions.Id);
+                    audio = new AudioPlayer(this, mediaOptions.Id);
+                    Media.players.Add(mediaOptions.Id, audio);
+                }
+
+                Deployment.Current.Dispatcher.BeginInvoke(() =>
+                {
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, audio.getDuration(mediaOptions.Src)));
+                });
+            }
+            catch (Exception e)
+            {
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-plugin-media/blob/155284bb/src/wp7/AudioPlayer.cs
----------------------------------------------------------------------
diff --git a/src/wp7/AudioPlayer.cs b/src/wp7/AudioPlayer.cs
deleted file mode 100644
index 882eb96..0000000
--- a/src/wp7/AudioPlayer.cs
+++ /dev/null
@@ -1,647 +0,0 @@
-/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Threading;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Audio;
-using Microsoft.Xna.Framework.Media;
-using Microsoft.Phone.Controls;
-using System.Diagnostics;
-using System.Windows.Resources;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-
-    /// <summary>
-    /// Implements audio record and play back functionality.
-    /// </summary>
-    internal class AudioPlayer : IDisposable
-    {
-        #region Constants
-
-        // AudioPlayer states
-        private const int PlayerState_None = 0;
-        private const int PlayerState_Starting = 1;
-        private const int PlayerState_Running = 2;
-        private const int PlayerState_Paused = 3;
-        private const int PlayerState_Stopped = 4;
-
-        // AudioPlayer messages
-        private const int MediaState = 1;
-        private const int MediaDuration = 2;
-        private const int MediaPosition = 3;
-        private const int MediaError = 9;
-
-        // AudioPlayer errors
-        private const int MediaErrorPlayModeSet = 1;
-        private const int MediaErrorAlreadyRecording = 2;
-        private const int MediaErrorStartingRecording = 3;
-        private const int MediaErrorRecordModeSet = 4;
-        private const int MediaErrorStartingPlayback = 5;
-        private const int MediaErrorResumeState = 6;
-        private const int MediaErrorPauseState = 7;
-        private const int MediaErrorStopState = 8;
-
-        //TODO: get rid of this callback, it should be universal
-        //private const string CallbackFunction = "CordovaMediaonStatus";
-
-        #endregion
-
-
-        /// <summary>
-        /// The AudioHandler object
-        /// </summary>
-        private Media handler;
-
-        /// <summary>
-        /// Temporary buffer to store audio chunk
-        /// </summary>
-        private byte[] buffer;
-
-        /// <summary>
-        /// Xna game loop dispatcher
-        /// </summary>
-        DispatcherTimer dtXna;
-
-
-        /// <summary>
-        /// Output buffer
-        /// </summary>
-        private MemoryStream memoryStream;
-
-        /// <summary>
-        /// The id of this player (used to identify Media object in JavaScript)
-        /// </summary>
-        private String id;
-
-        /// <summary>
-        /// State of recording or playback
-        /// </summary>
-        private int state = PlayerState_None;
-
-        /// <summary>
-        /// File name to play or record to
-        /// </summary>
-        private String audioFile = null;
-
-        /// <summary>
-        /// Duration of audio
-        /// </summary>
-        private double duration = -1;
-
-        /// <summary>
-        /// Audio player object
-        /// </summary>
-        private MediaElement player = null;
-
-        /// <summary>
-        /// Audio source
-        /// </summary>
-        private Microphone recorder;
-
-        /// <summary>
-        /// Internal flag specified that we should only open audio w/o playing it
-        /// </summary>
-        private bool prepareOnly = false;
-
-        /// <summary>
-        /// Creates AudioPlayer instance
-        /// </summary>
-        /// <param name="handler">Media object</param>
-        /// <param name="id">player id</param>
-        public AudioPlayer(Media handler, String id)
-        {
-            this.handler = handler;
-            this.id = id;
-        }
-
-
-        /// <summary>
-        /// Destroys player and stop audio playing or recording
-        /// </summary>
-        public void Dispose()
-        {
-            if (this.player != null)
-            {
-                this.stopPlaying();
-                this.player = null;
-            }
-            if (this.recorder != null)
-            {
-                this.stopRecording();
-                this.recorder = null;
-            }
-
-            this.FinalizeXnaGameLoop();
-        }
-
-        private void InvokeCallback(int message, string value, bool removeHandler)
-        {
-            string args = string.Format("('{0}',{1},{2});", this.id, message, value);
-            string callback = @"(function(id,msg,value){
-                try {
-                    if (msg == Media.MEDIA_ERROR) {
-                        value = {'code':value};
-                    }
-                    Media.onStatus(id,msg,value);
-                }
-                catch(e) {
-                    console.log('Error calling Media.onStatus :: ' + e);
-                }
-            })" + args;
-            this.handler.InvokeCustomScript(new ScriptCallback("eval", new string[] { callback }), false);
-        }
-
-        private void InvokeCallback(int message, int value, bool removeHandler)
-        {
-            InvokeCallback(message, value.ToString(), removeHandler);
-        }
-
-        private void InvokeCallback(int message, double value, bool removeHandler)
-        {
-            InvokeCallback(message, value.ToString(), removeHandler);
-        }
-
-        /// <summary>
-        /// Starts recording, data is stored in memory
-        /// </summary>
-        /// <param name="filePath"></param>
-        public void startRecording(string filePath)
-        {
-            if (this.player != null)
-            {
-                InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
-            }
-            else if (this.recorder == null)
-            {
-                try
-                {
-                    this.audioFile = filePath;
-                    this.InitializeXnaGameLoop();
-                    this.recorder = Microphone.Default;
-                    this.recorder.BufferDuration = TimeSpan.FromMilliseconds(500);
-                    this.buffer = new byte[recorder.GetSampleSizeInBytes(this.recorder.BufferDuration)];
-                    this.recorder.BufferReady += new EventHandler<EventArgs>(recorderBufferReady);
-                    MemoryStream stream  = new MemoryStream();
-                    this.memoryStream = stream;
-                    int numBits = 16;
-                    int numBytes = numBits / 8;
-
-                    // inline version from AudioFormatsHelper
-                    stream.Write(System.Text.Encoding.UTF8.GetBytes("RIFF"), 0, 4);
-                    stream.Write(BitConverter.GetBytes(0), 0, 4);
-                    stream.Write(System.Text.Encoding.UTF8.GetBytes("WAVE"), 0, 4);
-                    stream.Write(System.Text.Encoding.UTF8.GetBytes("fmt "), 0, 4);
-                    stream.Write(BitConverter.GetBytes(16), 0, 4);
-                    stream.Write(BitConverter.GetBytes((short)1), 0, 2);
-                    stream.Write(BitConverter.GetBytes((short)1), 0, 2);
-                    stream.Write(BitConverter.GetBytes(this.recorder.SampleRate), 0, 4);
-                    stream.Write(BitConverter.GetBytes(this.recorder.SampleRate * numBytes), 0, 4);
-                    stream.Write(BitConverter.GetBytes((short)(numBytes)), 0, 2);
-                    stream.Write(BitConverter.GetBytes((short)(numBits)), 0, 2);
-                    stream.Write(System.Text.Encoding.UTF8.GetBytes("data"), 0, 4);
-                    stream.Write(BitConverter.GetBytes(0), 0, 4);
-
-                    this.recorder.Start();
-                    FrameworkDispatcher.Update();
-                    this.SetState(PlayerState_Running);
-                }
-                catch (Exception)
-                {
-                    InvokeCallback(MediaError, MediaErrorStartingRecording, false);
-                    //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingRecording),false);
-                }
-            }
-            else
-            {
-                InvokeCallback(MediaError, MediaErrorAlreadyRecording, false);
-                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorAlreadyRecording),false);
-            }
-        }
-
-        /// <summary>
-        /// Stops recording
-        /// </summary>
-        public void stopRecording()
-        {
-            if (this.recorder != null)
-            {
-                if (this.state == PlayerState_Running)
-                {
-                    try
-                    {
-                        this.recorder.Stop();
-                        this.recorder.BufferReady -= recorderBufferReady;
-                        this.recorder = null;
-                        SaveAudioClipToLocalStorage();
-                        this.FinalizeXnaGameLoop();
-                        this.SetState(PlayerState_Stopped);
-                    }
-                    catch (Exception)
-                    {
-                        //TODO 
-                    }
-                }
-            }
-        }
-
-        /// <summary>
-        /// Starts or resume playing audio file
-        /// </summary>
-        /// <param name="filePath">The name of the audio file</param>
-        /// <summary>
-        /// Starts or resume playing audio file
-        /// </summary>
-        /// <param name="filePath">The name of the audio file</param>
-        public void startPlaying(string filePath)
-        {
-            if (this.recorder != null)
-            {
-                InvokeCallback(MediaError, MediaErrorRecordModeSet, false);
-                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorRecordModeSet),false);
-                return;
-            }
-
-
-            if (this.player == null || this.player.Source.AbsolutePath.LastIndexOf(filePath) < 0)
-            {
-                try
-                {
-                    // this.player is a MediaElement, it must be added to the visual tree in order to play
-                    PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
-                    if (frame != null)
-                    {
-                        PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
-                        if (page != null)
-                        {
-                            Grid grid = page.FindName("LayoutRoot") as Grid;
-                            if (grid != null)
-                            {
-
-                                this.player = grid.FindName("playerMediaElement") as MediaElement;
-                                if (this.player == null) // still null ?
-                                {
-                                    this.player = new MediaElement();
-                                    this.player.Name = "playerMediaElement";
-                                    grid.Children.Add(this.player);
-                                    this.player.Visibility = Visibility.Visible;
-                                }
-                                if (this.player.CurrentState == System.Windows.Media.MediaElementState.Playing)
-                                {
-                                    this.player.Stop(); // stop it!
-                                }
-
-                                this.player.Source = null; // Garbage collect it.
-                                this.player.MediaOpened += MediaOpened;
-                                this.player.MediaEnded += MediaEnded;
-                                this.player.MediaFailed += MediaFailed;
-                            }
-                        }
-                    }
-
-                    this.audioFile = filePath;
-
-                    Uri uri = new Uri(filePath, UriKind.RelativeOrAbsolute);
-                    if (uri.IsAbsoluteUri)
-                    {
-                        this.player.Source = uri;
-                    }
-                    else
-                    {
-                        using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                        {
-                            if (!isoFile.FileExists(filePath))
-                            {
-                                // try to unpack it from the dll into isolated storage
-                                StreamResourceInfo fileResourceStreamInfo = Application.GetResourceStream(new Uri(filePath, UriKind.Relative));
-                                if (fileResourceStreamInfo != null)
-                                {
-                                    using (BinaryReader br = new BinaryReader(fileResourceStreamInfo.Stream))
-                                    {
-                                        byte[] data = br.ReadBytes((int)fileResourceStreamInfo.Stream.Length);
-
-                                        string[] dirParts = filePath.Split('/');
-                                        string dirName = "";
-                                        for (int n = 0; n < dirParts.Length - 1; n++)
-                                        {
-                                            dirName += dirParts[n] + "/";
-                                        }
-                                        if (!isoFile.DirectoryExists(dirName))
-                                        {
-                                            isoFile.CreateDirectory(dirName);
-                                        }
-
-                                        using (IsolatedStorageFileStream outFile = isoFile.OpenFile(filePath, FileMode.Create))
-                                        {
-                                            using (BinaryWriter writer = new BinaryWriter(outFile))
-                                            {
-                                                writer.Write(data);
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                            if (isoFile.FileExists(filePath))
-                            {
-                                using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, isoFile))
-                                {
-                                    this.player.SetSource(stream);
-                                }
-                            }
-                            else
-                            {
-                                InvokeCallback(MediaError, MediaErrorPlayModeSet, false);
-                                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, 1), false);
-                                return;
-                            }
-                        }
-                    }
-                    this.SetState(PlayerState_Starting);
-                }
-                catch (Exception e)
-                {
-                    Debug.WriteLine("Error in AudioPlayer::startPlaying : " + e.Message);
-                    InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
-                    //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStartingPlayback),false);
-                }
-            }
-            else
-            {
-                if (this.state != PlayerState_Running)
-                {
-                    this.player.Play();
-                    this.SetState(PlayerState_Running);
-                }
-                else
-                {
-                    InvokeCallback(MediaError, MediaErrorResumeState, false);
-                    //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorResumeState),false);
-                }
-            }
-        }
-
-        /// <summary>
-        /// Callback to be invoked when the media source is ready for playback
-        /// </summary>
-        private void MediaOpened(object sender, RoutedEventArgs arg)
-        {
-            if (this.player != null)
-            {
-                this.duration = this.player.NaturalDuration.TimeSpan.TotalSeconds;
-                InvokeCallback(MediaDuration, this.duration, false);
-                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaDuration, this.duration),false);
-                if (!this.prepareOnly)
-                {
-                    this.player.Play();
-                    this.SetState(PlayerState_Running);
-                }
-                this.prepareOnly = false;
-            }
-            else
-            {
-                // TODO: occasionally MediaOpened is signalled, but player is null
-            }
-        }
-
-        /// <summary>
-        /// Callback to be invoked when playback of a media source has completed
-        /// </summary>
-        private void MediaEnded(object sender, RoutedEventArgs arg)
-        {
-            this.SetState(PlayerState_Stopped);
-        }
-
-        /// <summary>
-        /// Callback to be invoked when playback of a media source has failed
-        /// </summary>
-        private void MediaFailed(object sender, RoutedEventArgs arg)
-        {
-            player.Stop();
-            InvokeCallback(MediaError, MediaErrorStartingPlayback, false);
-            //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError.ToString(), "Media failed"),false);
-        }
-
-        /// <summary>
-        /// Seek or jump to a new time in the track
-        /// </summary>
-        /// <param name="milliseconds">The new track position</param>
-        public void seekToPlaying(int milliseconds)
-        {
-            if (this.player != null)
-            {
-                TimeSpan tsPos = new TimeSpan(0, 0, 0, 0, milliseconds);
-                this.player.Position = tsPos;
-                InvokeCallback(MediaPosition, milliseconds / 1000.0f, false);
-                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, milliseconds / 1000.0f),false);
-            }
-        }
-
-        /// <summary>
-        /// Set the volume of the player
-        /// </summary>
-        /// <param name="vol">volume 0.0-1.0, default value is 0.5</param>
-        public void setVolume(double vol)
-        {
-            if (this.player != null)
-            {
-                this.player.Volume = vol;
-            }
-        }
-
-        /// <summary>
-        /// Pauses playing
-        /// </summary>
-        public void pausePlaying()
-        {
-            if (this.state == PlayerState_Running)
-            {
-                this.player.Pause();
-                this.SetState(PlayerState_Paused);
-            }
-            else
-            {
-                InvokeCallback(MediaError, MediaErrorPauseState, false);
-                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorPauseState),false);
-            }
-        }
-
-
-        /// <summary>
-        /// Stops playing the audio file
-        /// </summary>
-        public void stopPlaying()
-        {
-            if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
-            {
-                this.player.Stop();
-
-                this.player.Position = new TimeSpan(0L);
-                this.SetState(PlayerState_Stopped);
-            }
-            //else // Why is it an error to call stop on a stopped media?
-            //{
-            //    this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaError, MediaErrorStopState), false);
-            //}
-        }
-
-        /// <summary>
-        /// Gets current position of playback
-        /// </summary>
-        /// <returns>current position</returns>
-        public double getCurrentPosition()
-        {
-            if ((this.state == PlayerState_Running) || (this.state == PlayerState_Paused))
-            {
-                double currentPosition = this.player.Position.TotalSeconds;
-                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaPosition, currentPosition),false);
-                return currentPosition;
-            }
-            else
-            {
-                return 0;
-            }
-        }
-
-        /// <summary>
-        /// Gets the duration of the audio file
-        /// </summary>
-        /// <param name="filePath">The name of the audio file</param>
-        /// <returns>track duration</returns>
-        public double getDuration(string filePath)
-        {
-            if (this.recorder != null)
-            {
-                return (-2);
-            }
-
-            if (this.player != null)
-            {
-                return this.duration;
-
-            }
-            else
-            {
-                this.prepareOnly = true;
-                this.startPlaying(filePath);
-                return this.duration;
-            }
-        }
-
-        /// <summary>
-        /// Sets the state and send it to JavaScript
-        /// </summary>
-        /// <param name="state">state</param>
-        private void SetState(int state)
-        {
-            if (this.state != state)
-            {
-                InvokeCallback(MediaState, state, false);
-                //this.handler.InvokeCustomScript(new ScriptCallback(CallbackFunction, this.id, MediaState, state),false);
-            }
-
-            this.state = state;
-        }
-
-        #region record methods
-
-        /// <summary>
-        /// Copies data from recorder to memory storages and updates recording state
-        /// </summary>
-        /// <param name="sender"></param>
-        /// <param name="e"></param>
-        private void recorderBufferReady(object sender, EventArgs e)
-        {
-            this.recorder.GetData(this.buffer);
-            this.memoryStream.Write(this.buffer, 0, this.buffer.Length);
-        }
-
-        /// <summary>
-        /// Writes audio data from memory to isolated storage
-        /// </summary>
-        /// <returns></returns>
-        private void SaveAudioClipToLocalStorage()
-        {
-            if (memoryStream == null || memoryStream.Length <= 0)
-            {
-                return;
-            }
-
-            long position = memoryStream.Position;
-            memoryStream.Seek(4, SeekOrigin.Begin);
-            memoryStream.Write(BitConverter.GetBytes((int)memoryStream.Length - 8), 0, 4);
-            memoryStream.Seek(40, SeekOrigin.Begin);
-            memoryStream.Write(BitConverter.GetBytes((int)memoryStream.Length - 44), 0, 4);
-            memoryStream.Seek(position, SeekOrigin.Begin);
-
-            try
-            {
-                using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
-                {
-                    string directory = Path.GetDirectoryName(audioFile);
-
-                    if (!isoFile.DirectoryExists(directory))
-                    {
-                        isoFile.CreateDirectory(directory);
-                    }
-
-                    this.memoryStream.Seek(0, SeekOrigin.Begin);
-
-                    using (IsolatedStorageFileStream fileStream = isoFile.CreateFile(audioFile))
-                    {
-                        this.memoryStream.CopyTo(fileStream);
-                    }
-                }
-            }
-            catch (Exception)
-            {
-                //TODO: log or do something else
-                throw;
-            }
-        }
-
-        #region Xna loop
-        /// <summary>
-        /// Special initialization required for the microphone: XNA game loop
-        /// </summary>
-        private void InitializeXnaGameLoop()
-        {
-            // Timer to simulate the XNA game loop (Microphone is from XNA)
-            this.dtXna = new DispatcherTimer();
-            this.dtXna.Interval = TimeSpan.FromMilliseconds(33);
-            this.dtXna.Tick += delegate { try { FrameworkDispatcher.Update(); } catch { } };
-            this.dtXna.Start();
-        }
-        /// <summary>
-        /// Finalizes XNA game loop for microphone
-        /// </summary>
-        private void FinalizeXnaGameLoop()
-        {
-            // Timer to simulate the XNA game loop (Microphone is from XNA)
-            if (this.dtXna != null)
-            {
-                this.dtXna.Stop();
-                this.dtXna = null;
-            }
-        }
-
-        #endregion
-
-        #endregion
-    }
-}