OSDN Git Service

Version 0.6.111, rename files.
[pettanr/clientJs.git] / 0.6.x / js / 07_audio / 03_XSilverlightAudio.js
1 \r
2 /*\r
3  * original : uupaa-js SilverlightAudio.js\r
4  * https://code.google.com/p/uupaa-js/source/browse/trunk/0.8/src/Audio/SilverlightAudio.js?r=568\r
5  *\r
6  * Silverlight 4 → 5における不具合の状況\r
7  * http://www.slideshare.net/wakabayashiy/silverlight-4-5 \r
8  * \r
9  * IE10以降でSilverlightでF5押したらフリーズする不具合と対処\r
10  * http://katsuyuzu.hatenablog.jp/entry/2014/01/11/003550\r
11  * \r
12  * SilverlLight5 ie6&7(ietester,winxp), ie8(winxp) で動作確認。firefox32 では動作しない。(4以下の方がよい?)\r
13  */\r
14 \r
15 var X_Audio_SLAudio, X_Audio_SLAudioWrapper,\r
16         X_Audio_SLAudio_uid = 0,\r
17         X_Audio_SLAudio_LIVE_LIST = [],\r
18         X_Audio_SLAudio_POOL_LIST = [];\r
19 \r
20 if( X.Pulgin.SilverlightEnabled ){\r
21         \r
22         function getSLAudioWrapper( proxy ){\r
23                 var i = X_Audio_SLAudio_LIVE_LIST.length;\r
24                 for( ; i; ){\r
25                         if( X_Audio_SLAudio_LIVE_LIST[ --i ].proxy === proxy ) return X_Audio_SLAudio_LIVE_LIST[ i ];\r
26                 };\r
27         };\r
28         \r
29         X_Audio_SLAudio = X_Class_override(\r
30                 new X.EventDispatcher(),\r
31                 {\r
32                         backendName : 'Silverlight Audio',\r
33 \r
34                         detect : function( source, ext ){\r
35                                 var ok = ext === 'mp3' || ext === 'wma';\r
36                                 \r
37                                 this.asyncDispatch( ok ? 'support' : 'nosupport' );\r
38                                 \r
39                                 return this;\r
40                         },\r
41                         \r
42                         register : function( proxy, source, option ){\r
43                                 X_Audio_SLAudio_LIVE_LIST.push( new X_Audio_SLAudioWrapper( proxy, source, option ) );\r
44                         },\r
45                         \r
46                         close : function(){\r
47                                 return getSLAudioWrapper( this ).close();\r
48                         },\r
49                         \r
50                         play : function( position ){\r
51                                 return getSLAudioWrapper( this ).play( position );\r
52                         },\r
53                         \r
54                         pause : function(){\r
55                                 return getSLAudioWrapper( this ).pause();\r
56                         },\r
57                         \r
58                         stop : function(){\r
59                                 return getSLAudioWrapper( this ).stop();\r
60                         },\r
61                         \r
62                         loop : function( v ){\r
63                                 return getSLAudioWrapper( this ).loop( v );\r
64                         },\r
65         \r
66                         state : function(){\r
67                                 return getSLAudioWrapper( this ).state();\r
68                         },\r
69         \r
70                         volume : function( v ){\r
71                                 return getSLAudioWrapper( this ).volume( v );\r
72                         },\r
73         \r
74                         startTime : function( time ){\r
75                                 return getSLAudioWrapper( this ).startTime( time );\r
76                         },\r
77         \r
78                         currentTime : function( time ){\r
79                                 return getSLAudioWrapper( this ).currentTime( time );\r
80                         },\r
81         \r
82                         isPlaying : function(){\r
83                                 return getSLAudioWrapper( this ).isPlaying();\r
84                         }\r
85                 }\r
86         );\r
87         \r
88         X_Audio_BACKENDS.push( X_Audio_SLAudio );\r
89         \r
90         function slerror(){\r
91                 alert( 'slerror' );\r
92         };\r
93         \r
94         X_Audio_SLAudioWrapper = X.EventDispatcher.inherits(\r
95                 'X.AV.SilverlightAudioWrapper',\r
96                 X.Class.POOL_OBJECT,\r
97                 {\r
98                         _isSilverlight  : true, // for X.EventDispatcher.listen\r
99                 proxy           : null,\r
100                 _onload         : '',\r
101                 _callback       : null,                 \r
102                 xnodeObject     : null,\r
103                 \r
104                         _loop           : false,\r
105                         _source         : '',\r
106                         _error          : 0,\r
107                         _ended          : true,\r
108                         _paused         : false,\r
109                         _volume         : 0.5,\r
110                         _startTime      : 0,\r
111                         _lastUserAction : '',\r
112                         _lastState      : '',\r
113                         _duration       : 0,\r
114                         _interval       : 0, // setInterval timer id\r
115                         \r
116                         Constructor : function( proxy, source, option ){\r
117                                 \r
118                                 if( !X_Audio_SLAudio_uid ){\r
119                                         // source\r
120                                         //X.X_Node_systemNode.create( 'script', { type : 'text/xaml', id : 'silverlightaudio' } )\r
121                                         //      .text( '<Canvas xmlns="http://schemas.microsoft.com/client/2007" ' +\r
122                                         // 'xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"></Canvas>');\r
123                                         \r
124                                         // html に以下を書いた                     \r
125                                         // <script id="silverlightaudio" type="text/xaml"><Canvas xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"></Canvas></script>\r
126                                 };\r
127                                 /*\r
128                                  * [Silverlight 2]JavaScriptコードからSilverlightのオブジェクトを利用するには?[C#、VB]\r
129                                  * http://www.atmarkit.co.jp/fdotnet/dotnettips/902slobjcallfromjs/slobjcallfromjs.html\r
130                                  * このページのサンプルは sl5+firefox32 環境で動いている。xaml を js から利用する形ではなく、.xap を sl4 以下で作るのがよさそう.\r
131                                  */\r
132                                 \r
133                                 // TODO embed\r
134                                 this.proxy       = proxy;\r
135                         this._onload     = 'XAudioSilverlightOnLoad' + ( ++X_Audio_SLAudio_uid );\r
136                                 this._callback   = window[ this._onload ] = X_Callback_create( this, this.onSLReady, [ option.autoplay ] );\r
137                         this.xnodeObject = X_Node_body\r
138                                 .create( 'object', {\r
139                                                 type   : 'application/x-silverlight-2',\r
140                                                 data   : 'data:application/x-silverlight-2,',\r
141                                                 width  : 1,\r
142                                                 height : 1\r
143                                         })\r
144                                         .html(\r
145                                             '<param name="background" value="#00000000">' +      // transparent\r
146                                             '<param name="windowless" value="true">' +\r
147                                             '<param name="source" value="#silverlightaudio">' +  // XAML ID\r
148                                             '<param name="onload" value="' + this._onload + '">'// + // bond to global\r
149                                             //'<param value="2.0.31005.0" name="minRuntimeVersion">' +\r
150                                             //'<param value="true" name="autoUpgrade">' +\r
151                                             //'<param name="onerror" value="slerror">' // bond to global\r
152                                         );\r
153                                 \r
154                             this._loop       = option.loop;\r
155                             this._source     = source;\r
156                                 if( option.volume       ) this._volume  = option.volume;\r
157                                 if( option.startTime ) this._startTime = option.startTime;\r
158         \r
159                                 this.listenOnce( X.Event.KILL_INSTANCE );\r
160                         },\r
161                         \r
162                         onSLReady : function( sender, autoplay ){\r
163                                 if( !this._onload ) return;\r
164                                 \r
165                                 window[ this._onload ] = null;\r
166                                 delete this._onload;\r
167                                 X_Callback_correct( this._callback );\r
168                                 delete this._callback;\r
169 \r
170                                 //if( sender.findName('media') ) alert( 'exist' );\r
171 \r
172                                 sender.children.add(\r
173                                         sender.GetHost().\r
174                                         content.\r
175                                         CreateFromXaml(\r
176                                         '<Canvas xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">' +\r
177                                                 '<MediaElement x:Name="media" Source="' + this._source + '" Volume="' + this._volume + '" AutoPlay="false" />' +\r
178                                         '</Canvas>'));\r
179                 \r
180                                 this._rawObject = sender.findName('media'); // x:Name='media'\r
181                                 \r
182                                 this.listen( [ 'MediaFailed', 'MediaOpened', 'MediaEnded', 'CurrentStateChanged' ] );\r
183                                 \r
184                                 autoplay && X.Timer.once( 100, this, this.play );\r
185                         },\r
186                         \r
187                         handleEvent : function( e ){\r
188                                 var lastState, currentState;\r
189                                 \r
190                                 switch( e.type ){\r
191                                         \r
192                                         case 'MediaFailed' :\r
193                                                 this._error = 4;\r
194                                                 this._ended = true;\r
195                                                 this._paused = false;\r
196                                 \r
197                                                 this.proxy.dispatch( 'error' ); // open failed\r
198                                                 break;\r
199                                         case 'MediaOpened' :\r
200                                                 // http://msdn.microsoft.com/ja-jp/library/bb979710(VS.95).aspx\r
201                                                 this._duration = this._rawObject.NaturalDuration.Seconds;\r
202                                 // TODO 'canplaythrough'\r
203                                                 this.proxy.dispatch( 'canplay' );\r
204                                                 break;\r
205                                         case 'MediaEnded' :\r
206                                                 this.currentTime(this._startTime);\r
207                                 \r
208                                                 if (this._loop) {\r
209                                                         this._rawObject.play();\r
210                                                 }\r
211                                                 break;\r
212                                         case 'CurrentStateChanged' :\r
213                                                 lastState       = this._lastState,\r
214                                                 currentState = this._rawObject.CurrentState;\r
215                                 \r
216                                                 // ignore consecutive events or 'Closed' == 'Error'\r
217                                                 if( lastState === currentState\r
218                                                         || ( (lastState === 'Closed' || lastState === 'Error') && ( currentState === 'Closed' || currentState === 'Error') ) ){\r
219                                                         return;\r
220                                                 };\r
221                                                 this._lastState = currentState; // update last state\r
222                                 \r
223                                                 switch (currentState) {\r
224                                                         case 'Buffering':\r
225                                                         case 'Opening':\r
226                                                                         break;\r
227                                         \r
228                                                         // media.play(none supported file) -> 'Error'\r
229                                                         // media.play(file not found)     -> 'Closed'\r
230                                                         // media.load -> 'Error'\r
231                                                         case 'Error':\r
232                                                         case 'Closed':\r
233                                                                         this._error = 4;\r
234                                                                         this._ended = true;\r
235                                                                         this._paused = false;\r
236                                                                         this.proxy.dispatch( 'error' );\r
237                                                                         break;\r
238                                         \r
239                                                         // userAction.pause()              -> MediaState('Paused') -> x\r
240                                                         // userAction.stop()                    -> MediaState('Paused') -> x\r
241                                                         // userAction.play() + file end -> MediaState('Paused') -> uueventfire('ended')\r
242                                                         case 'Paused':\r
243                                                                         switch (this._lastUserAction) {\r
244                                                                                 case 'play': // play() -> file end -> event('ended')\r
245                                                                                         this._ended = true;\r
246                                                                                         this._paused = false;\r
247                                                                                         this.proxy.dispatch( 'ended' );\r
248                                                                                         this.currentTime(this._startTime);\r
249                                                                                         break;\r
250                                                                                 case 'pause':\r
251                                                                                         this._ended = false;\r
252                                                                                         this._paused = true;\r
253                                                                                         break;\r
254                                                                                 case 'stop':\r
255                                                                                         this._ended = true;\r
256                                                                                         this._paused = false;\r
257                                                                         }\r
258                                                                         break;\r
259                                         \r
260                                                         // media.play -> 'Playing'\r
261                                                         case 'Playing':\r
262                                                                         this._error = 0;\r
263                                                                         this._ended = false;\r
264                                                                         this._paused = false;\r
265                                                                         this.proxy.dispatch( 'playing' );\r
266                                                                         break;\r
267                                         \r
268                                                         // stop()\r
269                                                         case 'Stopped':\r
270                                                                         this._ended = true;\r
271                                                                         this._paused = false;\r
272                                                                         this.currentTime(this._startTime);\r
273                                                 }\r
274                                                 break;\r
275                                         \r
276                                         case X.Event.KILL_INSTANCE :\r
277                                                 if( this._onload ){\r
278                                                         window[ this._onload ] = null;\r
279                                                         this._callback.kill();\r
280                                                 };\r
281                                                 this.xnodeObject.destroy();\r
282                                                 break;\r
283                                 };\r
284                         },\r
285                         \r
286                         close : function(){\r
287                                 if (this._interval) {\r
288                                         X.Timer.remove( this._interval );\r
289                                         delete this._interval;\r
290                                 };\r
291                                 this.proxy.dispatch( 'ended' );\r
292                                 this.kill();\r
293                         },\r
294                         \r
295                         // SilverlightAudio.play\r
296                         play : function(){\r
297                                 if (!this._error) {\r
298                                         this._lastUserAction = 'play';\r
299                                         if (this._ended) {\r
300                                                 this.currentTime(this._startTime);\r
301                                         }\r
302                         \r
303                                         this._rawObject.play();\r
304                                         this.proxy.dispatch( 'play' );\r
305                         \r
306                                         if (!this._interval) {\r
307                                                 this._interval = X.Timer.add( 1000, 0, this, this._onInterval );\r
308                                         }\r
309                                 }\r
310                         },\r
311                         \r
312                         _onInterval : function(){\r
313                                 this.isPlaying() && this.proxy.dispatch( 'timeupdate' );\r
314                         },\r
315                         \r
316                         // SilverlightAudio.pause\r
317                         pause : function(){\r
318                                 if (!this._error) {\r
319                                         this._lastUserAction = 'pause';\r
320                                         this._paused = true;\r
321                                         this._ended = false;\r
322                                         this._rawObject.pause();\r
323                                         this.proxy.dispatch( 'pause' );\r
324                                 }\r
325                         },\r
326                         \r
327                         // SilverlightAudio.stop\r
328                         stop : function(){\r
329                                 if (!this._error) {\r
330                                         this._lastUserAction = 'stop';\r
331                                         this._rawObject.stop();\r
332                                         this._ended = true;\r
333                                 }\r
334                         },\r
335                         \r
336                         // SilverlightAudio.loop\r
337                         loop : function(value){ // @param Boolean: true is loop\r
338                                                                    // @return Boolean/void: true is loop\r
339                                 if (value === undefined) {\r
340                                         return this._loop;\r
341                                 }\r
342                                 this._loop = value;\r
343                         },\r
344                         \r
345                         // SilverlightAudio.state\r
346                         state : function(){ // @return Hash: { loop, error, paused, ended, source, duration }\r
347                                 return {\r
348                                         loop     : this._loop,\r
349                                         error    : this._error,\r
350                                         paused   : this._paused,\r
351                                         ended    : this._ended,\r
352                                         source   : this._source,\r
353                                         duration : this._duration\r
354                                 };\r
355                         },\r
356                         \r
357                         // SilverlightAudio.volume\r
358                         volume : function(value){ // @param Number: 0.0 ~ 1.0\r
359                                                                          // @return Number/void:\r
360                                 if (value === undefined) {\r
361                                         return this._volume;\r
362                                 }\r
363                                 this._volume = value;\r
364                                 this._rawObject.Volume = value;\r
365                         },\r
366                         \r
367                         // SilverlightAudio.startTime\r
368                         startTime : function(time){ // @param Number: time\r
369                                                                            // @return Number/void:\r
370                                 if (time === undefined) {\r
371                                         return this._startTime;\r
372                                 }\r
373                                 this._startTime = time;\r
374                         },\r
375                         \r
376                         // SilverlightAudio.currentTime\r
377                         currentTime : function(time){ // @param Number: time\r
378                                                                                  // @return Number/void:\r
379                                 var position = this._rawObject.Position; // [!] create instance\r
380                                 \r
381                                 if (time === undefined) {\r
382                                         return position.Seconds;\r
383                                 };\r
384 \r
385                                 position.Seconds = time; // set current time\r
386                         \r
387                                 this._rawObject.Position = position; // [!] reattach instance\r
388                         },\r
389                         \r
390                         // SilverlightAudio.isPlaying\r
391                         isPlaying : function(){ // @return Boolean:\r
392                                 if (!this._error && !this._paused && !this._ended) {\r
393                                         return true;\r
394                                 }\r
395                                 return false;\r
396                         }\r
397 \r
398                 }\r
399         );\r
400         \r
401 };\r
402 \r
403 \r
404 \r