OSDN Git Service

Version 0.6.133, fix for closure compiler - ADVANCED_OPTIMIZATIONS
[pettanr/clientJs.git] / 0.6.x / js / 07_audio / 03_XSilverlightAudio.js
index 484a900..ce8ffa7 100644 (file)
  * SilverlLight5 ie6&7(ietester,winxp), ie8(winxp) で動作確認。firefox32 では動作しない。(4以下の方がよい?)\r
  */\r
 \r
-var X_Audio_SLAudio, X_Audio_SLAudioWrapper,\r
-       X_Audio_SLAudio_uid = 0,\r
-       X_Audio_SLAudio_LIVE_LIST = [],\r
-       X_Audio_SLAudio_POOL_LIST = [];\r
+var X_Audio_SLAudioWrapper,\r
+       X_Audio_SLAudio_uid = 0;\r
 \r
 if( X.Pulgin.SilverlightEnabled ){\r
        \r
-       function getSLAudioWrapper( proxy ){\r
-               var i = X_Audio_SLAudio_LIVE_LIST.length;\r
-               for( ; i; ){\r
-                       if( X_Audio_SLAudio_LIVE_LIST[ --i ].proxy === proxy ) return X_Audio_SLAudio_LIVE_LIST[ i ];\r
-               };\r
-       };\r
-       \r
-       X_Audio_SLAudio = X_Class_override(\r
-               new X.EventDispatcher(),\r
-               {\r
-                       backendName : 'Silverlight Audio',\r
-\r
-                       detect : function( source, ext ){\r
-                               var ok = ext === 'mp3' || ext === 'wma';\r
-                               \r
-                               this.asyncDispatch( ok ? 'support' : 'nosupport' );\r
-                               \r
-                               return this;\r
-                       },\r
-                       \r
-                       register : function( proxy, source, option ){\r
-                               X_Audio_SLAudio_LIVE_LIST.push( new X_Audio_SLAudioWrapper( proxy, source, option ) );\r
-                       },\r
-                       \r
-                       close : function(){\r
-                               return getSLAudioWrapper( this ).close();\r
-                       },\r
-                       \r
-                       play : function( position ){\r
-                               return getSLAudioWrapper( this ).play( position );\r
-                       },\r
-                       \r
-                       pause : function(){\r
-                               return getSLAudioWrapper( this ).pause();\r
-                       },\r
-                       \r
-                       stop : function(){\r
-                               return getSLAudioWrapper( this ).stop();\r
-                       },\r
-                       \r
-                       loop : function( v ){\r
-                               return getSLAudioWrapper( this ).loop( v );\r
-                       },\r
-       \r
-                       state : function(){\r
-                               return getSLAudioWrapper( this ).state();\r
-                       },\r
-       \r
-                       volume : function( v ){\r
-                               return getSLAudioWrapper( this ).volume( v );\r
-                       },\r
-       \r
-                       startTime : function( time ){\r
-                               return getSLAudioWrapper( this ).startTime( time );\r
-                       },\r
-       \r
-                       currentTime : function( time ){\r
-                               return getSLAudioWrapper( this ).currentTime( time );\r
-                       },\r
-       \r
-                       isPlaying : function(){\r
-                               return getSLAudioWrapper( this ).isPlaying();\r
-                       }\r
-               }\r
-       );\r
-       \r
-       X_Audio_BACKENDS.push( X_Audio_SLAudio );\r
-       \r
-       function slerror(){\r
-               alert( 'slerror' );\r
-       };\r
-       \r
+       // X.Node.inherits はできない。_rawObject は <object> でなく silverlight\r
        X_Audio_SLAudioWrapper = X.EventDispatcher.inherits(\r
                'X.AV.SilverlightAudioWrapper',\r
                X.Class.POOL_OBJECT,\r
                {\r
-                       _isSilverlight  : true, // for X.EventDispatcher.listen\r
+                       '_rawType'      : X_EventDispatcher_EVENT_TARGET_TYPE.SILVER_LIGHT,\r
                proxy           : null,\r
+               \r
+                       startTime       : 0,\r
+                       endTime         : -1,\r
+                       loopStartTime   : -1,\r
+                       loopEndTime     : -1,\r
+                       seekTime        : -1,\r
+                       duration        : 0,\r
+                       \r
+                       playing         : false,\r
+                       error           : 0,                    \r
+                       loop            : false,\r
+                       looped          : false,\r
+                       autoplay        : false,\r
+                       volume          : 0.5,\r
+               \r
                _onload         : '',\r
                _callback       : null,                 \r
                xnodeObject     : null,\r
-               \r
-                       _loop           : false,\r
                        _source         : '',\r
-                       _error          : 0,\r
                        _ended          : true,\r
                        _paused         : false,\r
-                       _volume         : 0.5,\r
-                       _startTime      : 0,\r
                        _lastUserAction : '',\r
                        _lastState      : '',\r
-                       _duration       : 0,\r
                        _interval       : 0, // setInterval timer id\r
                        \r
                        Constructor : function( proxy, source, option ){\r
                                \r
                                if( !X_Audio_SLAudio_uid ){\r
                                        // source\r
-                                       //X.X_Node_systemNode.create( 'script', { type : 'text/xaml', id : 'silverlightaudio' } )\r
+                                       // X_Node_systemNode.create( 'script', { type : 'text/xaml', id : 'silverlightaudio' } )\r
                                        //      .text( '<Canvas xmlns="http://schemas.microsoft.com/client/2007" ' +\r
                                        // 'xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"></Canvas>');\r
                                        \r
@@ -132,8 +68,10 @@ if( X.Pulgin.SilverlightEnabled ){
                                \r
                                // TODO embed\r
                                this.proxy       = proxy;\r
+                               this._source     = source;\r
+                               // X.Audio._slOnload_ は不可\r
                        this._onload     = 'XAudioSilverlightOnLoad' + ( ++X_Audio_SLAudio_uid );\r
-                               this._callback   = window[ this._onload ] = X_Callback_create( this, this.onSLReady, [ option.autoplay ] );\r
+                               this._callback   = window[ this._onload ] = X_Callback_create( this, this.onSLReady );\r
                        this.xnodeObject = X_Node_body\r
                                .create( 'object', {\r
                                                type   : 'application/x-silverlight-2',\r
@@ -145,21 +83,17 @@ if( X.Pulgin.SilverlightEnabled ){
                                            '<param name="background" value="#00000000">' +      // transparent\r
                                            '<param name="windowless" value="true">' +\r
                                            '<param name="source" value="#silverlightaudio">' +  // XAML ID\r
-                                           '<param name="onload" value="' + this._onload + '">'// + // bond to global\r
+                                           '<param name="onload" value="' + this._onload + '">' // + // bond to global\r
                                            //'<param value="2.0.31005.0" name="minRuntimeVersion">' +\r
                                            //'<param value="true" name="autoUpgrade">' +\r
                                            //'<param name="onerror" value="slerror">' // bond to global\r
                                        );\r
-                               \r
-                           this._loop       = option.loop;\r
-                           this._source     = source;\r
-                               if( option.volume       ) this._volume  = option.volume;\r
-                               if( option.startTime ) this._startTime = option.startTime;\r
+                               X_AudioWrapper_updateStates( this, option );\r
        \r
-                               this.listenOnce( X.Event.KILL_INSTANCE );\r
+                               this.listenOnce( X_Event.KILL_INSTANCE );\r
                        },\r
                        \r
-                       onSLReady : function( sender, autoplay ){\r
+                       onSLReady : function( sender ){\r
                                if( !this._onload ) return;\r
                                \r
                                window[ this._onload ] = null;\r
@@ -167,50 +101,53 @@ if( X.Pulgin.SilverlightEnabled ){
                                X_Callback_correct( this._callback );\r
                                delete this._callback;\r
 \r
-                               //if( sender.findName('media') ) alert( 'exist' );\r
-\r
                                sender.children.add(\r
                                        sender.GetHost().\r
                                        content.\r
                                        CreateFromXaml(\r
                                        '<Canvas xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">' +\r
-                                               '<MediaElement x:Name="media" Source="' + this._source + '" Volume="' + this._volume + '" AutoPlay="false" />' +\r
+                                               '<MediaElement x:Name="media" Source="' + this._source + '" Volume="' + this.volume + '" AutoPlay="false" />' +\r
                                        '</Canvas>'));\r
                \r
                                this._rawObject = sender.findName('media'); // x:Name='media'\r
-                               \r
+\r
                                this.listen( [ 'MediaFailed', 'MediaOpened', 'MediaEnded', 'CurrentStateChanged' ] );\r
-                               \r
-                               autoplay && X.Timer.once( 100, this, this.play );\r
                        },\r
                        \r
                        handleEvent : function( e ){\r
                                var lastState, currentState;\r
                                \r
+                               console.log( e.type );\r
                                switch( e.type ){\r
                                        \r
                                        case 'MediaFailed' :\r
-                                               this._error = 4;\r
-                                               this._ended = true;\r
+                                               this.error   = 4;\r
+                                               this.playing = false;\r
+                                               this._ended  = true;\r
                                                this._paused = false;\r
-                               \r
-                                               this.proxy.dispatch( 'error' ); // open failed\r
+                                               this.proxy.dispatch( X_Event.ERROR ); // open failed\r
                                                break;\r
+\r
                                        case 'MediaOpened' :\r
                                                // http://msdn.microsoft.com/ja-jp/library/bb979710(VS.95).aspx\r
-                                               this._duration = this._rawObject.NaturalDuration.Seconds;\r
-                               // TODO 'canplaythrough'\r
-                                               this.proxy.dispatch( 'canplay' );\r
+                                               this.duration = this._rawObject.NaturalDuration.Seconds * 1000;\r
+                                               // TODO 'canplaythrough'\r
+                                               //this.proxy.asyncDispatch( 'loadstart' );\r
+                               //this.proxy.asyncDispatch( 'loadedmetadata' );\r
+                               //this.proxy.asyncDispatch( 'loadeddata' );\r
+                               //this.proxy.asyncDispatch( 'canplay' );\r
+                               //this.proxy.asyncDispatch( 'canplaythrough' );\r
+                               this.proxy.asyncDispatch( X_Event.READY );\r
+                               \r
+                               this.autoplay && X.Timer.once( 16, this, this.play );\r
                                                break;\r
-                                       case 'MediaEnded' :\r
-                                               this.currentTime(this._startTime);\r
-                               \r
-                                               if (this._loop) {\r
-                                                       this._rawObject.play();\r
-                                               }\r
+\r
+                                       case 'MediaEnded' :                             \r
+                                               this.loop && this.playing && this.play();\r
                                                break;\r
+\r
                                        case 'CurrentStateChanged' :\r
-                                               lastState       = this._lastState,\r
+                                               lastState        = this._lastState,\r
                                                currentState = this._rawObject.CurrentState;\r
                                \r
                                                // ignore consecutive events or 'Closed' == 'Error'\r
@@ -220,63 +157,84 @@ if( X.Pulgin.SilverlightEnabled ){
                                                };\r
                                                this._lastState = currentState; // update last state\r
                                \r
-                                               switch (currentState) {\r
-                                                       case 'Buffering':\r
-                                                       case 'Opening':\r
-                                                                       break;\r
-                                       \r
+                                               switch( currentState ){\r
+                                                       case 'Buffering' :\r
+                                                       case 'Opening' :\r
+                                                               switch( this._lastUserAction ){\r
+                                                                       case 'play' :\r
+                                                                               this.proxy.dispatch( X_Event.MEDIA_WAITING );\r
+                                                                               break;\r
+                                                                       case 'seek' :\r
+                                                                               this.proxy.dispatch( X_Event.MEDIA_SEEKING );\r
+                                                                               break;\r
+                                                                       case 'pause' :\r
+                                                                               break;\r
+                                                               };\r
+                                                               break;\r
+\r
                                                        // media.play(none supported file) -> 'Error'\r
                                                        // media.play(file not found)     -> 'Closed'\r
                                                        // media.load -> 'Error'\r
                                                        case 'Error':\r
+                                                               this.error   = 4;\r
                                                        case 'Closed':\r
-                                                                       this._error = 4;\r
-                                                                       this._ended = true;\r
-                                                                       this._paused = false;\r
-                                                                       this.proxy.dispatch( 'error' );\r
-                                                                       break;\r
-                                       \r
+                                                               this.error   = this.error || 2;\r
+                                                               this.playing = false;\r
+                                                               this._ended  = true;\r
+                                                               this._paused = false;\r
+                                                               this.proxy.dispatch( X_Event.ERROR );\r
+                                                               break;\r
+\r
                                                        // userAction.pause()              -> MediaState('Paused') -> x\r
                                                        // userAction.stop()                    -> MediaState('Paused') -> x\r
                                                        // userAction.play() + file end -> MediaState('Paused') -> uueventfire('ended')\r
                                                        case 'Paused':\r
-                                                                       switch (this._lastUserAction) {\r
-                                                                               case 'play': // play() -> file end -> event('ended')\r
-                                                                                       this._ended = true;\r
-                                                                                       this._paused = false;\r
-                                                                                       this.proxy.dispatch( 'ended' );\r
-                                                                                       this.currentTime(this._startTime);\r
-                                                                                       break;\r
-                                                                               case 'pause':\r
-                                                                                       this._ended = false;\r
-                                                                                       this._paused = true;\r
-                                                                                       break;\r
-                                                                               case 'stop':\r
-                                                                                       this._ended = true;\r
-                                                                                       this._paused = false;\r
-                                                                       }\r
-                                                                       break;\r
-                                       \r
+                                                               this.playing = false;\r
+                                                               \r
+                                                               switch( this._lastUserAction ){\r
+                                                                       case 'play': // play() -> file end -> event('ended')\r
+                                                                       case 'seek':\r
+                                                                               this.seekTime = 0;\r
+                                                                               this._ended   = true;\r
+                                                                               this._paused  = false;\r
+                                                                               this.proxy.dispatch( X_Event.MEDIA_ENDED );\r
+                                                                               this._currentTime( this.startTime );\r
+                                                                               break;\r
+                                                                       case 'pause':\r
+                                                                               this._ended  = false;\r
+                                                                               this._paused = true;\r
+                                                                               break;\r
+                                                                       case 'stop':\r
+                                                                               this._ended  = true;\r
+                                                                               this._paused = false;\r
+                                                               };\r
+                                                               break;\r
+\r
                                                        // media.play -> 'Playing'\r
                                                        case 'Playing':\r
-                                                                       this._error = 0;\r
-                                                                       this._ended = false;\r
-                                                                       this._paused = false;\r
-                                                                       this.proxy.dispatch( 'playing' );\r
-                                                                       break;\r
-                                       \r
+                                                               this.error   = 0;\r
+                                                               this.playing = true;\r
+                                                               this._ended  = false;\r
+                                                               this._paused = false;\r
+                                                               this.proxy.dispatch( X_Event.MEDIA_PLAYING );\r
+                                                               break;\r
+\r
                                                        // stop()\r
                                                        case 'Stopped':\r
-                                                                       this._ended = true;\r
-                                                                       this._paused = false;\r
-                                                                       this.currentTime(this._startTime);\r
-                                               }\r
+                                                               this.playing = false;\r
+                                                               this._ended  = true;\r
+                                                               this._paused = false;\r
+                                                               this._currentTime( this.startTime );\r
+                                                               break;\r
+                                               };\r
                                                break;\r
-                                       \r
-                                       case X.Event.KILL_INSTANCE :\r
+\r
+                                       case X_Event.KILL_INSTANCE :\r
                                                if( this._onload ){\r
+                                                       // window への delete に ie5 は対応しないが、そもそも ie5 は Silverlight に非対応\r
                                                        window[ this._onload ] = null;\r
-                                                       this._callback.kill();\r
+                                                       delete this._onload;\r
+                                                       X_Callback_correct( this._callback );\r
                                                };\r
                                                this.xnodeObject.destroy();\r
                                                break;\r
@@ -284,121 +242,182 @@ if( X.Pulgin.SilverlightEnabled ){
                        },\r
                        \r
                        close : function(){\r
-                               if (this._interval) {\r
-                                       X.Timer.remove( this._interval );\r
-                                       delete this._interval;\r
-                               };\r
-                               this.proxy.dispatch( 'ended' );\r
+                               this.playing && this.pause();\r
+                               this.proxy.dispatch( X_Event.MEDIA_ENDED );\r
                                this.kill();\r
                        },\r
                        \r
                        // SilverlightAudio.play\r
                        play : function(){\r
-                               if (!this._error) {\r
-                                       this._lastUserAction = 'play';\r
-                                       if (this._ended) {\r
-                                               this.currentTime(this._startTime);\r
-                                       }\r
-                       \r
-                                       this._rawObject.play();\r
-                                       this.proxy.dispatch( 'play' );\r
-                       \r
-                                       if (!this._interval) {\r
-                                               this._interval = X.Timer.add( 1000, 0, this, this._onInterval );\r
-                                       }\r
-                               }\r
-                       },\r
-                       \r
-                       _onInterval : function(){\r
-                               this.isPlaying() && this.proxy.dispatch( 'timeupdate' );\r
+                               var begin, end;\r
+                               \r
+                               // もし kill 後に autoplayTimer で呼ばれても、_closed==true なので平気\r
+                               if( this.error ) return;\r
+                               if( !this.duration ){\r
+                                       this.autoplay = true;\r
+                                       return;\r
+                               };\r
+                               \r
+                               this._lastUserAction = 0 <= this.seekTime ? 'seek' : 'play';\r
+                               \r
+                               end   = X_AudioWrapper_getEndTime( this );\r
+                               begin = X_AudioWrapper_getStartTime( this, end, true ) | 0;\r
+                               \r
+                               console.log( '[SLAudio] play ' + begin + ' -> ' + end );\r
+                               \r
+                           this._rawObject.Volume = this.volume;\r
+                           this._beginTime = begin;\r
+                           this._currentTime( begin );\r
+                           \r
+                           if( !this.playing ){\r
+                                   this._rawObject.play();\r
+                           //this.proxy.dispatch( 'play' );\r
+                           \r
+                           this.playing = true;\r
+                           };\r
+                   \r
+                   this._timerID && X.Timer.remove( this._timerID );\r
+                   \r
+                if( end < this.duration ){\r
+                                       this._timerID = X.Timer.once( end - begin, this, this._onEnded );\r
+                } else {\r
+                       delete this._timerID;\r
+                };\r
+                \r
+                               if( !this._interval ){\r
+                                       this._interval = X.Timer.add( 1000, 0, this, this._onInterval );\r
+                               };\r
                        },\r
+                               \r
+                               _onInterval : function(){\r
+                                       if( !this.playing ){\r
+                                               delete this._interval;\r
+                                               return X_Callback_UN_LISTEN;\r
+                                       };\r
+                                       this.proxy.dispatch( X_Event.MEDIA_PLAYING );\r
+                               },\r
+                               \r
+                               _onEnded : function(){\r
+                                       var time, end;\r
+                                       delete this._timerID;\r
+                                       \r
+                           if( this.playing ){\r
+                               console.log( '> end ' + X_AudioWrapper_getEndTime( this ) + ' current:' + ( this._rawObject.Position.Seconds * 1000 | 0 ) );\r
+                               time = this._rawObject.Position.Seconds * 1000 | 0;\r
+                               \r
+                               if( time <= this._beginTime ){\r
+                                       console.log( '== waiting' );\r
+                                       this.proxy.dispatch( X_Event.MEDIA_WAITING );\r
+                                       this._timerID = X.Timer.once( X_AudioWrapper_getEndTime( this ) - this._beginTime, this, this._onEnded );\r
+                                       return;\r
+                               };\r
+                               \r
+                               time -= X_AudioWrapper_getEndTime( this );\r
+                               if( time < 0 ){\r
+                                       console.log( '> onEnd ' + time );\r
+                                       this._timerID = X.Timer.once( -time, this, this._onEnded );\r
+                                       return;\r
+                               };\r
+                               \r
+                               if( this.loop ){\r
+                                       if( !( this.proxy.dispatch( X_Event.MEDIA_BEFORE_LOOP ) & X.Callback.PREVENT_DEFAULT ) ){\r
+                                               this.looped = true;\r
+                                               this.proxy.dispatch( X_Event.MEDIA_LOOPED );\r
+                                               this.play();\r
+                                       };\r
+                               } else {\r
+                                       this.pause();\r
+                                       this.proxy.dispatch( X_Event.MEDIA_ENDED );\r
+                               };\r
+                           };\r
+                               },\r
                        \r
                        // SilverlightAudio.pause\r
                        pause : function(){\r
-                               if (!this._error) {\r
-                                       this._lastUserAction = 'pause';\r
-                                       this._paused = true;\r
-                                       this._ended = false;\r
-                                       this._rawObject.pause();\r
-                                       this.proxy.dispatch( 'pause' );\r
-                               }\r
-                       },\r
-                       \r
-                       // SilverlightAudio.stop\r
-                       stop : function(){\r
-                               if (!this._error) {\r
-                                       this._lastUserAction = 'stop';\r
-                                       this._rawObject.stop();\r
-                                       this._ended = true;\r
-                               }\r
-                       },\r
-                       \r
-                       // SilverlightAudio.loop\r
-                       loop : function(value){ // @param Boolean: true is loop\r
-                                                                  // @return Boolean/void: true is loop\r
-                               if (value === undefined) {\r
-                                       return this._loop;\r
-                               }\r
-                               this._loop = value;\r
+                               if( this.error || !this.playing ) return;\r
+                               \r
+                               this._lastUserAction = 'pause';\r
+                               this.seekTime = this.state().currentTime;\r
+                               this.playing  = false;\r
+                               this._paused  = true;\r
+                               this._ended   = false;\r
+                                                       \r
+                               this._rawObject.pause();\r
+                               //this.proxy.dispatch( 'pause' );\r
                        },\r
                        \r
                        // SilverlightAudio.state\r
-                       state : function(){ // @return Hash: { loop, error, paused, ended, source, duration }\r
-                               return {\r
-                                       loop     : this._loop,\r
-                                       error    : this._error,\r
-                                       paused   : this._paused,\r
-                                       ended    : this._ended,\r
-                                       source   : this._source,\r
-                                       duration : this._duration\r
-                               };\r
-                       },\r
-                       \r
-                       // SilverlightAudio.volume\r
-                       volume : function(value){ // @param Number: 0.0 ~ 1.0\r
-                                                                        // @return Number/void:\r
-                               if (value === undefined) {\r
-                                       return this._volume;\r
-                               }\r
-                               this._volume = value;\r
-                               this._rawObject.Volume = value;\r
-                       },\r
-                       \r
-                       // SilverlightAudio.startTime\r
-                       startTime : function(time){ // @param Number: time\r
-                                                                          // @return Number/void:\r
-                               if (time === undefined) {\r
-                                       return this._startTime;\r
-                               }\r
-                               this._startTime = time;\r
-                       },\r
-                       \r
-                       // SilverlightAudio.currentTime\r
-                       currentTime : function(time){ // @param Number: time\r
-                                                                                // @return Number/void:\r
-                               var position = this._rawObject.Position; // [!] create instance\r
+                       state : function( obj ){ // @return Hash: { loop, error, paused, ended, source, duration }\r
+                               var result, end;\r
                                \r
-                               if (time === undefined) {\r
-                                       return position.Seconds;\r
-                               };\r
+                               if( obj === undefined ){\r
+                                   return {\r
+                                       startTime     : this.startTime,\r
+                                       endTime       : this.endTime < 0 ? this.duration : this.endTime,\r
+                                       loopStartTime : this.loopStartTime < 0 ? this.startTime : this.loopStartTime,\r
+                                       loopEndTime   : this.loopEndTime < 0 ? ( this.endTime || this.duration ) : this.loopEndTime,\r
+                                       \r
+                                       // 整数化 しておかないと seek 時に不具合がある。\r
+                                       currentTime   : this.playing ? this._rawObject.Position.Seconds * 1000 | 0 : this.seekTime,\r
 \r
-                               position.Seconds = time; // set current time\r
+                                       loop          : this.loop,\r
+                                       looped        : this.looped,\r
+                                       volume        : this.volume,\r
+                                       error         : this.error,\r
+                                       playing       : this.playing,\r
+                                       duration      : this.duration // this._rawObject.NaturalDuration.Seconds;\r
+                                   };\r
+                               };\r
                        \r
-                               this._rawObject.Position = position; // [!] reattach instance\r
+                               result = X_AudioWrapper_updateStates( this, obj );\r
+                           \r
+                               if( result & 2 ){ // seek\r
+                       this.play();\r
+                               } else {\r
+                                       if( result & 1 ){\r
+                                               end     = X_AudioWrapper_getEndTime( this );\r
+                                               halfway = end < this.duration;\r
+                                               this._timerID && X.Timer.remove( this._timerID );\r
+                                               \r
+                                               if( halfway ){\r
+                                                       this._timerID = X.Timer.once( end - this._rawObject.Position.Seconds * 1000 | 0, this, this._onEnded );\r
+                                               } else {\r
+                                                       delete this._timerID;\r
+                                               };\r
+\r
+                                       };\r
+                                       if( result & 4 ){\r
+                              this._rawObject.Volume = this.volume;\r
+                                       };\r
+                               };\r
                        },\r
                        \r
-                       // SilverlightAudio.isPlaying\r
-                       isPlaying : function(){ // @return Boolean:\r
-                               if (!this._error && !this._paused && !this._ended) {\r
-                                       return true;\r
+                               // SilverlightAudio.currentTime\r
+                               _currentTime : function( time ){ // @param Number: time\r
+                                       var position = this._rawObject.Position; // [!] create instance\r
+       \r
+                                       position.Seconds = time / 1000 | 0; // set current time\r
+                               \r
+                                       this._rawObject.Position = position; // [!] reattach instance\r
                                }\r
-                               return false;\r
-                       }\r
 \r
                }\r
        );\r
-       \r
-};\r
 \r
+       function slerror(){\r
+               alert( 'slerror' );\r
+       };\r
 \r
+       X_Audio_BACKENDS.push( {\r
+               backendName : 'Silverlight Audio',\r
+\r
+               detect : function( proxy, source, ext ){\r
+                       var ok = ext === 'mp3' || ext === 'wma' || ext === 'wav';\r
+                       proxy.asyncDispatch( { type : X_Event.COMPLETE, canPlay : ok } );                               \r
+               },\r
+               \r
+               klass : X_Audio_SLAudioWrapper\r
+               \r
+       } );\r
 \r
+};
\ No newline at end of file