From 3c07e12e13272820cedf983e0d9fe46e5f0a4bd9 Mon Sep 17 00:00:00 2001 From: itozyun Date: Mon, 26 Oct 2015 23:22:22 +0900 Subject: [PATCH] Version 0.6.184, fi x X.AudioSprite & X.Audio, add X.WMPAudio. --- 0.6.x/js/01_core/12_XClosure.js | 9 +- 0.6.x/js/01_core/21_XViewPort.js | 3 +- 0.6.x/js/02_dom/04_XBoxModel.js | 2 +- 0.6.x/js/02_dom/20_XNode.js | 14 +- 0.6.x/js/03_plugin/00_XPlugin.js | 21 ++- 0.6.x/js/05_util/04_XXML.js | 2 +- 0.6.x/js/07_audio/00_XAudio.js | 64 +++++--- 0.6.x/js/07_audio/01_XWebAudio.js | 21 ++- 0.6.x/js/07_audio/02_XHTMLAudio.js | 66 ++++----- 0.6.x/js/07_audio/03_XSilverlightAudio.js | 12 +- 0.6.x/js/07_audio/05_XWMPAudio.js | 233 ++++++++++++++++++++++++++++++ 0.6.x/js/07_audio/10_XAudioSprite.js | 196 ++++++++++++------------- 12 files changed, 438 insertions(+), 205 deletions(-) create mode 100644 0.6.x/js/07_audio/05_XWMPAudio.js diff --git a/0.6.x/js/01_core/12_XClosure.js b/0.6.x/js/01_core/12_XClosure.js index a25dee0..deca998 100644 --- a/0.6.x/js/01_core/12_XClosure.js +++ b/0.6.x/js/01_core/12_XClosure.js @@ -208,21 +208,14 @@ function X_Closure_proxyCallback( xfunc, _args ){ function X_Closure_correct( f ){ var i = X_CLOSURE_LIVE_LIST.indexOf( f ), obj; + if( i !== -1 ){ X_CLOSURE_LIVE_LIST.splice( i, 1 ); X_CLOSURE_POOL_LIST[ X_CLOSURE_POOL_LIST.length ] = f; obj = f( X_Closure_COMMAND_BACK ); - /* - delete obj.cbKind; - if( obj.funcName ) delete obj.funcName; - if( obj.func ) delete obj.func; - if( obj.context ) delete obj.context; - if( obj.supplement ) delete obj.supplement; - delete obj.proxy; */ X_Object_clear( obj ); return true; }; - return false; }; function X_Closure_monitor(){ diff --git a/0.6.x/js/01_core/21_XViewPort.js b/0.6.x/js/01_core/21_XViewPort.js index a89df05..5f1f098 100644 --- a/0.6.x/js/01_core/21_XViewPort.js +++ b/0.6.x/js/01_core/21_XViewPort.js @@ -41,7 +41,7 @@ X_ViewPort = X_Class_override( case 'beforeunload' : // ie では a href='javascript' な要素でも beforeunload が起こる href = e.target && e.target[ 'attr' ] && e.target[ 'attr' ]( 'href' ); - if( href && href.indexOf && href.indexOf( 'javascript:' ) === 0 ) return X_CALLBACK_PREVENT_DEFAULT | X_CALLBACK_STOP_PROPAGATION; + if( X_Type_isString( href ) && !href.toLowerCase().indexOf( 'javascript:' ) ) return X_CALLBACK_PREVENT_DEFAULT | X_CALLBACK_STOP_PROPAGATION; return X_ViewPort[ 'dispatch' ]( X_EVENT_BEFORE_UNLOAD ); @@ -136,6 +136,7 @@ function X_ViewPort_changeFocus(){ }; +// TODO EventDispatcherProxy /** * window に相当する ViewPort 情報を提供するオブジェクト。 * @namespace X.ViewPort diff --git a/0.6.x/js/02_dom/04_XBoxModel.js b/0.6.x/js/02_dom/04_XBoxModel.js index a609fc4..37391ce 100644 --- a/0.6.x/js/02_dom/04_XBoxModel.js +++ b/0.6.x/js/02_dom/04_XBoxModel.js @@ -275,7 +275,7 @@ var X_Node_getPosition = var ey = 0; // var el = target; - var bd = document.body; + var bd = X_elmBody; do { diff --git a/0.6.x/js/02_dom/20_XNode.js b/0.6.x/js/02_dom/20_XNode.js index b775d71..c303b3d 100644 --- a/0.6.x/js/02_dom/20_XNode.js +++ b/0.6.x/js/02_dom/20_XNode.js @@ -562,7 +562,7 @@ function X_Node_append( v ){ // 親の xnodes から v を消す v.parent && v[ 'remove' ](); // IE4 でテキストノードの追加、FIXED 済でない場合、親に要素の追加を通知 - if( X_UA[ 'IE4' ] && !v[ '_tag' ] && ( this[ '_flags' ] & X_NodeFlags_IE4_FIXED ) === 0 ) this[ '_flags' ] |= X_NodeFlags_IE4_DIRTY_CHILDREN; + if( X_UA[ 'IE4' ] && !v[ '_tag' ] && ( ( this[ '_flags' ] & X_NodeFlags_IE4_FIXED ) === 0 ) ) this[ '_flags' ] |= X_NodeFlags_IE4_DIRTY_CHILDREN; break; default : return this; @@ -638,7 +638,7 @@ function X_Node_appendAt( start, v ){ v[ 'remove' ](); }; // IE4 でテキストノードの追加、FIXED 済でない場合、親に要素の追加を通知 - if( X_UA[ 'IE4' ] && !v[ '_tag' ] && ( this[ '_flags' ] & X_NodeFlags_IE4_FIXED ) === 0 ) this[ '_flags' ] |= X_NodeFlags_IE4_DIRTY_CHILDREN; + if( X_UA[ 'IE4' ] && !v[ '_tag' ] && ( ( this[ '_flags' ] & X_NodeFlags_IE4_FIXED ) === 0 ) ) this[ '_flags' ] |= X_NodeFlags_IE4_DIRTY_CHILDREN; break; default : return this; @@ -791,7 +791,7 @@ function X_Node_remove(){ X_Node_reserveRemoval[ X_Node_reserveRemoval.length ] = this; X_Node_reserveUpdate(); } else - if( !this[ '_tag' ] && ( parent[ '_flags' ] & X_NodeFlags_IE4_FIXED ) === 0 ){ + if( !this[ '_tag' ] && ( ( parent[ '_flags' ] & X_NodeFlags_IE4_FIXED ) === 0 ) ){ parent[ '_flags' ] |= X_NodeFlags_IE4_DIRTY_CHILDREN; }; } else { @@ -854,7 +854,7 @@ function X_Node_onKill( that ){ X_Node_reserveRemoval[ X_Node_reserveRemoval.length ] = elm; X_Node_reserveUpdate(); } else - if( !that[ '_tag' ] && ( parent[ '_flags' ] & X_NodeFlags_IE4_FIXED ) === 0 ){ + if( !that[ '_tag' ] && ( ( parent[ '_flags' ] & X_NodeFlags_IE4_FIXED ) === 0 ) ){ parent[ '_flags' ] |= X_NodeFlags_IE4_DIRTY_CHILDREN; }; } else { @@ -1452,7 +1452,7 @@ var X_Node__commitUpdate = accumulatedFlags |= that[ '_flags' ]; if( that[ '_flags' ] & X_NodeFlags_IE5_DISPLAY_NONE_FIX ){ - if( accumulatedFlags & ( X_NodeFlags_DIRTY_POSITION | X_NodeFlags_DIRTY_ID | X_NodeFlags_DIRTY_CLASSNAME ) === 0 ){ + if( ( accumulatedFlags & ( X_NodeFlags_DIRTY_POSITION | X_NodeFlags_DIRTY_ID | X_NodeFlags_DIRTY_CLASSNAME ) ) === 0 ){ return nextElement; }; }; @@ -1481,6 +1481,8 @@ var X_Node__commitUpdate = } else if( that[ '_flags' ] & X_NodeFlags_IS_SVG ){ elm = document.createElementNS( 'http://www.w3.org/2000/svg', that[ '_tag' ].toLowerCase() ); + + // math http://www.w3.org/1998/Math/MathML } else { elm = document.createElement( that[ '_tag' ] ); }; @@ -1534,7 +1536,7 @@ var X_Node__commitUpdate = parentElement.appendChild( elm ); }; - if( that[ '_listeners' ] && ( that[ '_flags' ] & X_NodeFlags_ACTUAL_LISTENING ) === 0 ){ + if( that[ '_listeners' ] && ( ( that[ '_flags' ] & X_NodeFlags_ACTUAL_LISTENING ) === 0 ) ){ X_EventDispatcher_toggleAllEvents( that, true );// イベントの退避 that[ '_flags' ] |= X_NodeFlags_ACTUAL_LISTENING; }; diff --git a/0.6.x/js/03_plugin/00_XPlugin.js b/0.6.x/js/03_plugin/00_XPlugin.js index 07420dd..ffcdedc 100644 --- a/0.6.x/js/03_plugin/00_XPlugin.js +++ b/0.6.x/js/03_plugin/00_XPlugin.js @@ -60,8 +60,20 @@ var X_Pulgin_FLASH_VERSION = return X_Script_createActiveXObjectSafty( 'Gears.Factory' ); })() : X_Object_find( navigator, 'mimeTypes>application/x-googlegears>enabledPlugin' ) - ); - + ), + +// https://support.microsoft.com/ja-jp/kb/279022 +// Windows Media Player 7 がクライアントにインストールされている場合に、自動的に Web ページに埋め込む方法 +// TODO GeckoActiveXObject + X_Pulgin_WMP_VERSION = + !X_UA[ 'IE' ] || !X_UA[ 'ActiveX' ] ? parseFloat( X_Object_find( navigator, 'plugins>Windows Media Player Plug-in Dynamic Link Library>version' ) || 0 ) : + (function(){ + var obj = X_Script_createActiveXObjectSafty( 'WMPlayer.OCX.7' ); + + return obj ? parseFloat( obj[ 'versionInfo' ] ) : + X_Script_createActiveXObjectSafty( '{22D6F312-B0F6-11D0-94AB-0080C74C7E95}' ) ? 6.4 : 0; + })(); + // QuickTime Plug-in 7.7.6 /* X_Pulgin_QUICKTIME_VERSION = @@ -79,7 +91,6 @@ var X_Pulgin_FLASH_VERSION = })() : 0, */ - /** * @namespace X.Pulgin */ @@ -95,7 +106,9 @@ X[ 'Pulgin' ] = { //'QuickTime' : X_Pulgin_QUICKTIME_VERSION, - 'Gears' : !!X_Pulgin_GEARS_ENABLED + 'Gears' : !!X_Pulgin_GEARS_ENABLED, + + 'WMP' : X_Pulgin_WMP_VERSION }; diff --git a/0.6.x/js/05_util/04_XXML.js b/0.6.x/js/05_util/04_XXML.js index 44a020d..38fcaf3 100644 --- a/0.6.x/js/05_util/04_XXML.js +++ b/0.6.x/js/05_util/04_XXML.js @@ -540,7 +540,7 @@ var XMLWrapper_filter = { for( ; xnode = xmlList[i]; ++i ){ tmp = true; for( node = xnode.firstChild; node; node = node.nextSibling ){ - if( node.nodeType === 1 || ( node.nodeType === 3 && node._text ) ){ + if( node.nodeType === 1 || ( node.nodeType === 3 && node.nodeValue ) ){ tmp = false; break; }; diff --git a/0.6.x/js/07_audio/00_XAudio.js b/0.6.x/js/07_audio/00_XAudio.js index 4de81ae..49d1ee1 100644 --- a/0.6.x/js/07_audio/00_XAudio.js +++ b/0.6.x/js/07_audio/00_XAudio.js @@ -82,6 +82,7 @@ X[ 'Audio' ] = X_EventDispatcher[ 'inherits' ]( X_Type_isArray( sourceList ) ? X_Array_copy( sourceList ) : [ sourceList ], opt_option || {} ); this[ 'listenOnce' ]( [ X_EVENT_BACKEND_READY, X_EVENT_BACKEND_NONE, X_EVENT_KILL_INSTANCE ], X_Audio_handleEvent ); + X_ViewPort[ 'listenOnce' ]( X_EVENT_UNLOAD, this, X_AudioSprite_handleEvent ); }, /** @@ -176,7 +177,7 @@ X[ 'Audio' ] = X_EventDispatcher[ 'inherits' ]( ); function X_Audio_handleEvent( e ){ - var backend; + var backend, pair; switch( e.type ){ case X_EVENT_BACKEND_READY : @@ -185,17 +186,28 @@ function X_Audio_handleEvent( e ){ this[ 'unlisten' ]( X_EVENT_BACKEND_NONE, X_Audio_handleEvent ); this[ 'source' ] = e[ 'source' ]; this[ 'backendName' ] = backend.backendName; + X_Pair_create( this, backend.klass( this, e[ 'source' ], e[ 'option' ] ) ); + this[ 'listenOnce' ]( X_EVENT_READY, X_Audio_handleEvent ); + break; + + case X_EVENT_READY : + pair = X_Pair_get( this ); + ( pair.autoplay || pair._playReserved ) && pair.actualPlay(); + delete pair._playReserved; break; case X_EVENT_BACKEND_NONE : + case X_EVENT_UNLOAD : this[ 'kill' ](); break; case X_EVENT_KILL_INSTANCE : - backend = X_Pair_get( this ); - backend && backend[ 'kill' ](); - X_Pair_release( this, backend ); + X_ViewPort[ 'unlisten' ]( X_EVENT_UNLOAD, this, X_AudioSprite_handleEvent ); + if( backend = X_Pair_get( this ) ){ + backend[ 'kill' ](); + X_Pair_release( this, backend ); + }; break; }; }; @@ -255,8 +267,8 @@ var X_AudioBase = X_EventDispatcher[ 'inherits' ]( { disatcher : null, - startTime : 0, // - endTime : -1, // + startTime : 0, // state_startTime + endTime : -1, // state_startTime loopStartTime : -1, loopEndTime : -1, seekTime : -1, @@ -269,6 +281,8 @@ var X_AudioBase = X_EventDispatcher[ 'inherits' ]( autoplay : false,// gain : 0.5, + _playReserved : false, + play : function( startTime, endTime, loop, loopStartTime, loopEndTime ){ if( 0 <= startTime ){ this.setState( { @@ -292,6 +306,7 @@ var X_AudioBase = X_EventDispatcher[ 'inherits' ]( }, pause : function(){ + this.seekTime = this.getActualCurrentTime(); this.playing && this.actualPause(); // delete this.autoplay // delete this.playing @@ -344,7 +359,7 @@ var X_AudioBase = X_EventDispatcher[ 'inherits' ]( for( k in obj ){ v = obj[ k ]; switch( k ){ - case 'currentTime' : + case 'currentTime' : v = X_Audio_timeStringToNumber( v ); if( X_Type_isNumber( v ) ){ if( playing ){ @@ -440,7 +455,7 @@ var X_AudioBase = X_EventDispatcher[ 'inherits' ]( case 'useVideo' : break; default : - throw ( 'bad arg! ' + k ); + alert( 'bad arg! ' + k ); }; }; @@ -463,6 +478,7 @@ var X_AudioBase = X_EventDispatcher[ 'inherits' ]( function X_Audio_timeStringToNumber( time ){ var ary, ms, s = 0, m = 0, h = 0; + if( X_Type_isNumber( time ) ) return time; if( !X_Type_isString( time ) || !time.length ) return; @@ -497,34 +513,34 @@ function X_Audio_timeStringToNumber( time ){ return ms < 0 ? 0 : ms; }; -function X_Audio_getStartTime( audioWrapper, endTime, delSeekTime ){ - var seek = audioWrapper.seekTime; +function X_Audio_getStartTime( audioBase, endTime, delSeekTime ){ + var seek = audioBase.seekTime; - if( delSeekTime ) delete audioWrapper.seekTime; + if( delSeekTime ) delete audioBase.seekTime; if( 0 <= seek ){ - if( audioWrapper.duration <= seek || endTime < seek ) return 0; + if( audioBase.duration <= seek || endTime < seek ) return 0; return seek; }; - if( audioWrapper.looped && 0 <= audioWrapper.loopStartTime ){ - if( audioWrapper.duration <= audioWrapper.loopStartTime || endTime < audioWrapper.loopStartTime ) return 0; - return audioWrapper.loopStartTime; + if( audioBase.looped && 0 <= audioBase.loopStartTime ){ + if( audioBase.duration <= audioBase.loopStartTime || endTime < audioBase.loopStartTime ) return 0; + return audioBase.loopStartTime; }; - if( audioWrapper.startTime < 0 || audioWrapper.duration <= audioWrapper.startTime ) return 0; - return audioWrapper.startTime; + if( audioBase.startTime < 0 || audioBase.duration <= audioBase.startTime ) return 0; + return audioBase.startTime; }; -function X_Audio_getEndTime( audioWrapper ){ - var duration = audioWrapper.duration; +function X_Audio_getEndTime( audioBase ){ + var duration = audioBase.duration; - if( audioWrapper.looped && 0 <= audioWrapper.loopEndTime ){ - if( duration <= audioWrapper.loopEndTime ) return duration; - return audioWrapper.loopEndTime; + if( audioBase.looped && 0 <= audioBase.loopEndTime ){ + if( duration <= audioBase.loopEndTime ) return duration; + return audioBase.loopEndTime; }; - if( audioWrapper.endTime < 0 || duration <= audioWrapper.endTime ) return duration; - return audioWrapper.endTime; + if( audioBase.endTime < 0 || duration <= audioBase.endTime ) return duration; + return audioBase.endTime; }; diff --git a/0.6.x/js/07_audio/01_XWebAudio.js b/0.6.x/js/07_audio/01_XWebAudio.js index 47026ef..e33630b 100644 --- a/0.6.x/js/07_audio/01_XWebAudio.js +++ b/0.6.x/js/07_audio/01_XWebAudio.js @@ -88,6 +88,7 @@ var X_WebAudio_context = // 4s 以下ではない iPad 2G または iPad mi ( window[ 'AudioContext' ] || window[ 'webkitAudioContext' ] ), X_WebAudio_BUFFER_LIST = [], X_WebAudio_need1stTouch = X_UA[ 'iOS' ], + X_WebAudio_touchState = X_WebAudio_need1stTouch, X_WebAudio, X_WebAudio_BufferLoader, X_WebAudio_fpsFix; @@ -122,9 +123,13 @@ if( X_WebAudio_context ){ }, handleEvent : function( e ){ + var i, l; + switch( e.type ){ case X_EVENT_PROGRESS : - this[ 'dispatch' ]( { type : 'progress', 'percent' : e[ 'percent' ] } ); + for( i = 0, l = this.webAudioList.length; i < l; ++i ){ + this.webAudioList[ i ][ 'dispatch' ]( { type : X_EVENT_PROGRESS, 'percent' : e[ 'percent' ] } ); + }; return; case X_EVENT_SUCCESS : @@ -298,9 +303,6 @@ if( X_WebAudio_context ){ this.disatcher[ 'asyncDispatch' ]( X_EVENT_READY ); console.log( 'WebAudio buffer ready' ); - - this.autoplay && !X_WebAudio_need1stTouch && X_Timer_once( 16, this, this.actualPlay ); - }, actualPlay : function(){ @@ -309,17 +311,18 @@ if( X_WebAudio_context ){ console.log( '[WebAudio] play abuf:' + !!this.audioBuffer ); if( !this.audioBuffer ){ - this.autoplay = true; + this._playReserved = true; return; }; - if( X_WebAudio_need1stTouch ){ + if( X_WebAudio_touchState ){ e = X_EventDispatcher_CURRENT_EVENTS[ X_EventDispatcher_CURRENT_EVENTS.length - 1 ]; if( !e || !e[ 'pointerType' ] ){ - alert( 'タッチイベント以外での play! ' + ( e ? e.type : '' ) ); + // alert( 'タッチイベント以外での play! ' + ( e ? e.type : '' ) ); return; }; }; + X_WebAudio_touchState = false; end = X_Audio_getEndTime( this ); begin = X_Audio_getStartTime( this, end, true ); @@ -408,12 +411,8 @@ if( X_WebAudio_context ){ }, actualPause : function(){ - //if( !this.playing ) return this; - console.log( '[WebAudio] pause' ); - this.seekTime = this.getActualCurrentTime(); - this._timerID && X_Timer_remove( this._timerID ); delete this._timerID; delete this.playing; diff --git a/0.6.x/js/07_audio/02_XHTMLAudio.js b/0.6.x/js/07_audio/02_XHTMLAudio.js index 2c64eeb..786f343 100644 --- a/0.6.x/js/07_audio/02_XHTMLAudio.js +++ b/0.6.x/js/07_audio/02_XHTMLAudio.js @@ -60,7 +60,7 @@ var */ X_HTMLAudio_volumeEnabled = !( X_UA[ 'WinPhone' ] && X_UA[ 'IE9' ] ) && !X_UA[ 'Opera' ], // Gecko PC + Android でseek時に再生がしばしば止まる問題の修正 - X_HTMLAudio_needPlayForSeek = X_UA[ 'Gecko' ], + X_HTMLAudio_needPlayForSeek = X_UA[ 'iOS' ] || X_UA[ 'Gecko' ], // X_HTMLAudio_pauseFix = 12 <= X_UA[ 'Opera' ] && 0 < ' XP XPSP2 2003|XP64'.indexOf( X_UA[ 'Windows' ] ), // XP + Opera12 のみ? @@ -133,7 +133,6 @@ if( X_Audio_constructor ){ X_elmBody.appendChild( raw ); } else { raw = X_TEMP.rawAudio || new X_Audio_constructor( '' ); - // raw.loop = false; // loop を使えば ended で止まること回避できるかも 但し ended イベントが起きなくなる if( X_TEMP.rawAudio ) delete X_TEMP.rawAudio; }; @@ -160,14 +159,18 @@ if( X_Audio_constructor ){ 'playing', 'waiting', 'seeking', 'durationchange', 'timeupdate', 'ended' ], this.onDebug ); + if( X_HTMLAudio_endedFixAOSP2 || X_HTMLAudio_endedFixAOSP4 ){ + raw.loop = true; // loop を使えば ended で止まること回避できるかも 但し ended イベントが起きなくなる + }; + if( X_HTMLAudio_need1stTouch ){ raw.src = source; } else { // if( this.autoplay ){ raw.preload = 'auto'; raw.autoplay = true; // Android 4.0-4.1.x で必要 + //raw.autobuffer = true; //}; - //raw.autobuffer = true; raw.src = source; raw.load(); // Android4.1.1 HTL21 では必要! }; @@ -177,25 +180,21 @@ if( X_Audio_constructor ){ this.disatcher[ 'dispatch' ]( { type : X_EVENT_DEBUG, 'rawEvent' : e.type, - current : this[ '_rawObject' ].currentTime, + 'current' : this[ '_rawObject' ].currentTime, duration : this[ '_rawObject' ].duration } ); }, handleEvent : function( e ){ - if( !e || !e.type ) alert( 888 ); - var raw = this[ '_rawObject' ], actualEnded = e.type === 'ended', ended = actualEnded, + i, l, buf, time, ready, eventType, duration, end, now; if( this._closed ) return; - - // global に公開 - //window[ '__rawAudio' ] = this[ '_rawObject' ]; - - e.type !== 'timeupdate' && console.log( ' > ' + e.type ); + + //e.type !== 'timeupdate' && console.log( ' > ' + e.type ); switch( e.type ){ @@ -205,7 +204,7 @@ if( X_Audio_constructor ){ // 【javascript】モバイル向けブラウザでも音を鳴らしたい【WebAudio】 // http://ingaouhou.com/archives/3633 - // ・使い終わったインスタンスはload()しておくとやや安定 + // ・使い終わったインスタンスはload()しておくとやや安定 raw.src = ''; raw.load(); @@ -218,7 +217,14 @@ if( X_Audio_constructor ){ // console.log( e.loaded + ' ' + e.total * 100 + '%' ); // iem9 で常に0 raw.networkState; // opera Android 12 で buffered.end() へのアクセスはエラー try catch も無効、iem9 は常に end(0) = 0 - //console.log( 'buffered.end ' + raw.buffered && raw.buffered.end(0) ); + if( !( X_UA[ 'Opera' ] && X_UA[ 'Android' ] ) && !( X_UA[ 'WinPhones' ] && X_UA[ 'IE9' ] ) && this.duration ){ + buf = raw.buffered; + time = 0; + for( i = 0, l = buf.length; i < l; ++i ){ + time += buf[ 'end' ]( i ) - buf[ 'start' ]( i ); + }; + this.disatcher[ 'dispatch' ]( { type : X_EVENT_PROGRESS, 'percent' : time * 1000 / this.duration } ); + }; break; case 'loadeddata' : // コンテンツの表示を現在の再生位置で初めて行えるようになった場合に発生 @@ -254,7 +260,7 @@ if( X_Audio_constructor ){ duration = raw.duration; eventType = X_EVENT_MEDIA_WAITING; } else - if( !X_HTMLAudio_durationFix && X_HTMLAudio_need1stTouch && this._touchState === 3 ){ + if( this._touchState === 3 && !X_HTMLAudio_durationFix ){ this._touchState = 0; this._readyState |= 1; } else @@ -264,12 +270,12 @@ if( X_Audio_constructor ){ if( this.playing ){ end = X_Audio_getEndTime( this ) + this._shortPlayFixTime; //console.log( now + ' / ' + end ); - // || now < this._lastCurrentTime // loop した場合 - if( 0 + end <= 0 + now ){ // 0+ なぜか iem9 で必要,,, + if( ( 0 + end <= 0 + now ) || // 0+ なぜか iem9 で必要,,, + ( now < this._lastCurrentTime ) ){ // loop した場合 if( this.autoLoop ){ console.log( '☆★☆ 曲の最後に到達 @timeupdate now-end:' + ( now - end ) ); ended = true; - if( X_HTMLAudio_endedFixIOS ) actualEnded = true; + //if( X_HTMLAudio_endedFixIOS ) actualEnded = true; } else { this.actualPause(); eventType = X_EVENT_MEDIA_ENDED; @@ -325,15 +331,14 @@ if( X_Audio_constructor ){ console.log( '▼ DurationFix の終了 @' + e.type ); this._durationFixPhase = 8; - if( this.autoplay ){ + if( this.autoplay || this._playReserved ){ console.log( '☆ 再生 <- DurationFix の終了' ); + delete this._playReserved; this.actualPlay(); } else if( X_HTMLAudio_pauseFix ){ console.log( '☆ PAUSE <- DurationFix の終了' ); - //raw.src = ''; - //raw.load(); - this.actualPause(); + this.actualPause(); }; } else if( this._durationFixPhase & 3 ){ // === 1 | 2 @@ -353,10 +358,7 @@ if( X_Audio_constructor ){ if( !( this.disatcher[ 'dispatch' ]( X_EVENT_MEDIA_BEFORE_LOOP ) & X_CALLBACK_PREVENT_DEFAULT ) ){ this.looped = true; this.disatcher[ 'dispatch' ]( X_EVENT_MEDIA_LOOPED ); - ( X_HTMLAudio_endedFixAOSP3 || X_HTMLAudio_endedFixAOSP4 || X_HTMLAudio_endedFixCWV || X_HTMLAudio_endedFixIOS ) && actualEnded && console.log( '☆★☆ 音声の継続用の play() @ended' ); - this.actualPlay( - ( X_HTMLAudio_endedFixAOSP4 || X_HTMLAudio_endedFixCWV || X_HTMLAudio_endedFixIOS ) && actualEnded, - ( X_HTMLAudio_endedFixAOSP3 || X_HTMLAudio_endedFixAOSP2 ) && actualEnded ); + this.actualPlay( X_HTMLAudio_endedFixCWV && actualEnded, X_HTMLAudio_endedFixAOSP3 && actualEnded ); }; } else { this.seekTime = 0; @@ -367,7 +369,6 @@ if( X_Audio_constructor ){ if( this._readyState === 1 && this.duration ){ this._readyState = 3; this.disatcher[ 'asyncDispatch' ]( X_EVENT_READY ); - this.autoplay && X_Timer_once( 16, this, this.actualPlay ); console.log( '> Audio Loaded!! ' + e.type + ' d:' + ( this.duration | 0 ) ); } else if( eventType ){ @@ -396,7 +397,7 @@ if( X_Audio_constructor ){ this._touchState = 3; } else if( this._readyState !== 3 && this._durationFixPhase < 2 ){ - this.autoplay = true; + this._playReserved = true; return; }; @@ -431,7 +432,7 @@ if( X_Audio_constructor ){ } else if( X_HTMLAudio_needPlayForSeek || forcePlay ){ raw.play(); - console.log( '[HTMLAudio] currentTime より先.' ); + //console.log( '[HTMLAudio] currentTime より先.' ); }; //http://himaxoff.blog111.fc2.com/blog-entry-97.html @@ -444,15 +445,12 @@ if( X_Audio_constructor ){ console.log( '[HTMLAudio] play ' + begin + ' -> ' + end + ' crt:' + ( raw.currentTime | 0 ) + ' last:' + this._lastCurrentTime ); - if( forceReload || ( X_HTMLAudio_endedFixAOSP4 && raw.duration && raw.currentTime === raw.duration ) ){ - raw.src = ''; - raw.src = this._src; + if( forceReload ){ this.playing = false; this._endedFixON = true; + raw.src = this._src; console.log( '△ onEndedFix の開始' ); - raw.currentTime = this._lastCurrentTime; this.disatcher[ 'dispatch' ]( X_EVENT_MEDIA_WAITING ); - X_HTMLAudio_endedFixAOSP2 && raw.load(); }; }; @@ -466,8 +464,6 @@ if( X_Audio_constructor ){ var raw = this[ '_rawObject' ]; console.log( '[HTMLAudio] pause' ); - - this.seekTime = this.getActualCurrentTime(); delete this._currentFixStart; diff --git a/0.6.x/js/07_audio/03_XSilverlightAudio.js b/0.6.x/js/07_audio/03_XSilverlightAudio.js index 97582a7..ff2f7b5 100644 --- a/0.6.x/js/07_audio/03_XSilverlightAudio.js +++ b/0.6.x/js/07_audio/03_XSilverlightAudio.js @@ -15,7 +15,7 @@ var X_SLAudio, X_SLAudio_uid = 0; -if( X[ 'Pulgin' ][ 'Silverlight' ] ){ +if( X_Pulgin_SILVER_LIGHT_VERSION ){ X_TEMP.slaudioInit = function(){ // @@ -131,8 +131,6 @@ if( X[ 'Pulgin' ][ 'Silverlight' ] ){ // http://msdn.microsoft.com/ja-jp/library/bb979710(VS.95).aspx this.duration = this[ '_rawObject' ][ 'NaturalDuration' ][ 'Seconds' ] * 1000; this.disatcher[ 'asyncDispatch' ]( X_EVENT_READY ); - - this.autoplay && X_Timer_once( 16, this, this.actualPlay ); break; case 'MediaEnded' : @@ -253,7 +251,7 @@ if( X[ 'Pulgin' ][ 'Silverlight' ] ){ // もし kill 後に autoplayTimer で呼ばれても、_closed==true なので平気 if( this.error ) return; if( !this.duration ){ - this.autoplay = true; + this._playReserved = true; return; }; @@ -349,16 +347,14 @@ if( X[ 'Pulgin' ][ 'Silverlight' ] ){ // SilverlightAudio.pause actualPause : function(){ - if( this.error /* || !this.playing */ ) return; + if( this.error ) return; this._lastUserAction = 'pause'; - this.seekTime = this.getActualCurrentTime(); this.playing = false; this._paused = true; this._ended = false; this[ '_rawObject' ].pause(); - //this.disatcher[ 'dispatch' ]( 'pause' ); }, getActualCurrentTime : function(){ @@ -366,6 +362,8 @@ if( X[ 'Pulgin' ][ 'Silverlight' ] ){ }, afterUpdateState : function( result ){ + var end, halfway; + if( result & 3 ){ // seek this.actualPlay(); } else diff --git a/0.6.x/js/07_audio/05_XWMPAudio.js b/0.6.x/js/07_audio/05_XWMPAudio.js new file mode 100644 index 0000000..075f537 --- /dev/null +++ b/0.6.x/js/07_audio/05_XWMPAudio.js @@ -0,0 +1,233 @@ +// https://msdn.microsoft.com/ja-jp/library/cc410695.aspx +// Windows Media Player コントロール Version 6.4 + +// http://www.tohoho-web.com/wwwmmd2.htm + +// http://devedge.primedirective.net/viewsource/2003/windows-media-in-netscape/index.html + +var X_WMPAudio; + +if( X_Pulgin_WMP_VERSION ){ // IETester で 6.x は不可 + X_WMPAudio = X_AudioBase[ 'inherits' ]( + 'X.WMPAudio', + X_Class.POOL_OBJECT, + { + xnodeObject : null, + wmp : null, + _wmp : null, + // 0 : no + // 1 : loading + // 2 : loaded + _readyState : 0, + _seekDirection : 0, + _timerID : 0, + + 'Constructor' : function( disatcher, source, option ){ + this.disatcher = disatcher || this; + this._source = source; + + if( 7 <= X_Pulgin_WMP_VERSION ){ + this.xnodeObject = X_Node_systemNode[ 'create' ]( 'object', { + 'classID' : 'CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6', + width : 1, + height : 1 + })[ 'html' ]( + X_UA[ 'IE55' ] ? '' : '' + //+ '' + //+ '' + ); + } else { + this.xnodeObject = X_Node_systemNode[ 'create' ]( 'object', { + classID : 'CLSID:22D6F312-B0F6-11D0-94AB-0080C74C7E95', + width : 0, + height : 0 + })[ 'html' ]( + X_UA[ 'IE55' ] ? '' : '' + //+ '' + //+ '' + ); + }; + // TODO embed + + this.setState( option ); + + X_ViewPort[ 'listenOnce' ]( X_EVENT_AFTER_UPDATE, this ); + this[ 'listenOnce' ]( X_EVENT_KILL_INSTANCE ); + }, + + handleEvent : function( e ){ + switch( e.type ){ + case X_EVENT_AFTER_UPDATE : + this._readyState = 1; + if( 7 <= X_Pulgin_WMP_VERSION ){ + this._wmp = this.xnodeObject[ '_rawObject' ]; + this._wmp[ 'URL' ] = this._source; + this.wmp = this._wmp[ 'controls' ]; + } else { + this.wmp = this.xnodeObject[ '_rawObject' ]; + this.wmp[ 'FileName' ] = this._source; + }; + this._timerID = X_Timer_add( 100, 0, this, this._onTimer ); + break; + + case X_EVENT_KILL_INSTANCE : + this.playing && this.disatcher[ 'dispatch' ]( X_EVENT_MEDIA_ENDED ); + this.playing && this.actualPause(); + this.wmp.stop(); + this.xnodeObject[ 'kill' ](); + break; + }; + }, + + // WMPAudio.play + actualPlay : function(){ + var begin, offset, end; + + if( this._readyState < 2 ){ + this._playReserved = true; + return; + }; + + end = X_Audio_getEndTime( this ); + begin = this._beginTime = X_Audio_getStartTime( this, end, true ) | 0; + + console.log( '[play] ' + begin + ' -> ' + end ); + + if( !this.playing ){ + this.setVolume(); + this.wmp.play(); + + this.playing = true; + } else { + this._seekDirection = this.getActualCurrentTime() < begin ? 1 : -1; + }; + + // 1 秒以下は指定できないため四捨五入 + //begin = ( begin / 1000 | 0 ) * 1000 + ( 500 < begin % 1000 ? 1000 : 0 ); + this.wmp[ 'CurrentPosition' ] = begin / 1000; + + if( !this._timerID ) this._timerID = X_Timer_add( 100, 0, this, this._onTimer ); + }, + + _onTimer : function(){ + var progress, time; + + // road 中の場合 + if( this._readyState === 1 ){ + if( 7 <= X_Pulgin_WMP_VERSION ){ + progress = this._wmp[ 'network' ][ 'downloadProgress' ]; + } else { + progress = this.wmp[ 'BufferingProgress' ]; + }; + if( progress < 100 ){ + this.disatcher[ 'dispatch' ]( { type : X_EVENT_PROGRESS, 'percent' : progress } ); + } else { + this._readyState = 2; + if( 7 <= X_Pulgin_WMP_VERSION ){ + this.duration = this._wmp[ 'currentMedia' ].duration * 1000 | 0; + } else { + this.duration = this.wmp[ 'Duration' ] * 1000 | 0; + }; + this.disatcher[ 'dispatch' ]( X_EVENT_READY ); + }; + } else + // ended の判定 + if( this.playing ){ + time = this.getActualCurrentTime(); + + // waiting + if( this._seekDirection ){ + if( this._seekDirection === 1 ? ( time < this._beginTime ) : ( this._lastCurrentTime <= time ) ){ + this.disatcher[ 'dispatch' ]( X_EVENT_MEDIA_SEEKING ); + return; + }; + delete this._seekDirection; + }; + if( time === this._lastCurrentTime ){ + this.disatcher[ 'dispatch' ]( X_EVENT_MEDIA_WAITING ); + return; + }; + this._lastCurrentTime = time; + + // ended ではない + if( time - X_Audio_getEndTime( this ) < -50 ){ + this.disatcher[ 'dispatch' ]( X_EVENT_MEDIA_PLAYING ); + return; + }; + + // ended + if( this.autoLoop ){ + if( !( this.disatcher[ 'dispatch' ]( X_EVENT_MEDIA_BEFORE_LOOP ) & X_CALLBACK_PREVENT_DEFAULT ) ){ + this.looped = true; + this.disatcher[ 'dispatch' ]( X_EVENT_MEDIA_LOOPED ); + this.actualPlay(); + }; + } else { + this.actualPause(); + this.disatcher[ 'dispatch' ]( X_EVENT_MEDIA_ENDED ); + delete this._timerID; + return X_CALLBACK_UN_LISTEN; + }; + }; + }, + + // WMPAudio.pause + actualPause : function(){ + this.playing = false; + this._timerID && X_Timer_remove( this._timerID ); + delete this._timerID; + + this.wmp.pause(); + }, + + setVolume : function(){ + if( 7 <= X_Pulgin_WMP_VERSION ){ + this._wmp[ 'settings' ][ 'Volume' ] = this.gain * 100; + } else { + this.wmp[ 'Volume' ] = ( 1 - this.gain ) * 10000; + }; + }, + + getActualCurrentTime : function(){ + return this.wmp[ 'CurrentPosition' ] * 1000 | 0; + }, + + afterUpdateState : function( result ){ + if( result & 3 ){ // seek + this.actualPlay(); + } else + if( result & 4 ){ + this.setVolume(); + }; + } + + } + ); + + X_Audio_BACKENDS.push( { + backendID : 16, + + backendName : 'WMP' + X_Pulgin_WMP_VERSION, + + canPlay : { + 'mp3' : true, + 'wma' : true, + 'wav' : true, + 'mid' : true, + 'midi' : true, + 'snd' : true, + 'au' : true, + 'aif' : true, + 'aicf' : true, + 'aiff' : true + }, + + detect : function( proxy, source, ext ){ + proxy[ 'asyncDispatch' ]( { type : X_EVENT_COMPLETE, canPlay : ext === 'mp3' || ext === 'wma' || ext === 'wav' } ); + }, + + klass : X_WMPAudio + + } ); + +}; \ No newline at end of file diff --git a/0.6.x/js/07_audio/10_XAudioSprite.js b/0.6.x/js/07_audio/10_XAudioSprite.js index 57e5d41..763eca7 100644 --- a/0.6.x/js/07_audio/10_XAudioSprite.js +++ b/0.6.x/js/07_audio/10_XAudioSprite.js @@ -17,7 +17,6 @@ var X_AudioSprite_shouldUse = X_HTMLAudio && ( X_UA[ 'iOS' ] || X_UA[ 'A X_AudioSprite_lengthSilence = 10000, // 一番最初の無音部分の長さ X_AudioSprite_lengthDistance = 5000, // 音間の無音の長さ X_AudioSprite_uid = 0, - X_AudioSprite_members = {}, X_AudioSprite_TEMP = { presets : {}, BGMs : {}, @@ -30,7 +29,7 @@ var X_AudioSprite_shouldUse = X_HTMLAudio && ( X_UA[ 'iOS' ] || X_UA[ 'A bgmLooped : false, bgmPlaying : false }, - X_AudioSprite_instance, + X_AudioSprite, X_AudioSprite_numTracks, X_AudioSprite_useVideo; @@ -61,18 +60,12 @@ X[ 'AudioSprite' ] = function( setting ){ urls = setting[ 'urls' ], video = setting[ 'useVideo' ], n = video ? 1 : setting[ 'numTracks' ] || 1, - option = { - volume : setting[ 'volume' ] || 0.5, - autoplay : true, - startTime : 0, - endTime : X_AudioSprite_lengthSilence, - loop : true - }, - k, i, v, track; + volume = setting[ 'volume' ], + k, i, v, track; - if( !X_AudioSprite_instance ){ - X_AudioSprite_instance = X_Class_override( X_EventDispatcher(), X_AudioSprite_members ); - X_ViewPort[ 'listen' ]( [ X_EVENT_VIEW_ACTIVATE, X_EVENT_VIEW_DEACTIVATE ], X_AudioSprite_instance, X_AudioSprite_handleEvent ); + if( !X_AudioSprite ){ + X_AudioSprite = X_Class_override( X_EventDispatcher(), X_AudioSprite_members ); + X_ViewPort[ 'listen' ]( [ X_EVENT_VIEW_ACTIVATE, X_EVENT_VIEW_DEACTIVATE, X_EVENT_UNLOAD ], X_AudioSprite, X_AudioSprite_handleEvent ); }; n = n <= X_AudioSprite_maxTracks ? n : X_AudioSprite_maxTracks; @@ -96,15 +89,25 @@ X[ 'AudioSprite' ] = function( setting ){ }; }; - X_Audio_startDetectionBackend( X_Audio_BACKENDS[ 0 ], X_AudioSprite_instance, X_Array_copy( urls ), option ); + X_Audio_startDetectionBackend( + X_Audio_BACKENDS[ 0 ], + X_AudioSprite, + X_Array_copy( urls ), + { + 'volume' : 0 <= volume && volume <= 1 ? volume : 1, + 'autoplay' : true, + 'startTime' : 0, + 'endTime' : X_AudioSprite_lengthSilence, + 'loop' : true + }); - X_AudioSprite_instance[ 'listenOnce' ]( [ X_EVENT_BACKEND_READY, X_EVENT_BACKEND_NONE ], X_AudioSprite_backendHandler ); - X_AudioSprite_instance[ 'listenOnce' ]( X_EVENT_KILL_INSTANCE, X_AudioSprite_handleEvent ); + X_AudioSprite[ 'listenOnce' ]( [ X_EVENT_BACKEND_READY, X_EVENT_BACKEND_NONE ], X_AudioSprite_backendHandler ); + X_AudioSprite[ 'listenOnce' ]( X_EVENT_KILL_INSTANCE, X_AudioSprite_handleEvent ); X_AudioSprite_useVideo = video; - X_AudioSprite_numTracks = X_AudioSprite_instance[ 'numTracks' ] = n; + X_AudioSprite_numTracks = X_AudioSprite[ 'numTracks' ] = n; - return X_AudioSprite_instance; + return X_AudioSprite; }; X[ 'AudioSprite' ][ 'shouldUse' ] = X_AudioSprite_shouldUse; @@ -114,7 +117,7 @@ X[ 'AudioSprite' ][ 'enableMultiTrack' ] = !X_AudioSprite_disableMultiTrack; // TODO 終わりかけのもの、と一番古いもの、どちらを再利用するか?これ以上に細かい実装を望む場合は X.AudioSprite は使わず自力で実装 function X_AudioSprite_getTrackEnded(){ var tracks = X_AudioSprite_TEMP.tracks, - l = tracks.length, + l = X_AudioSprite_numTracks, i = 0, track, state, last = 1 / 0, _last, index; for( ; i < l; ++i ){ @@ -132,7 +135,7 @@ function X_AudioSprite_getTrackEnded(){ return tracks[ index ]; }; -X_AudioSprite_members = +var X_AudioSprite_members = /** @lends X.AudioSprite.prototype */ { /** @@ -141,21 +144,6 @@ X_AudioSprite_members = 'numTracks' : 0, /** - * モバイル用タッチイベント中に呼び出す - */ - 'on1stTouch' : function(){ - var i = 0, l = X_AudioSprite_TEMP.tracks.length; - - for( ; i < l; ++i ){ - //if( X_UA[ 'iOS' ] ){ - // X_AudioSprite_TEMP.tracks[ i ][ '_rawObject' ].load(); - //} else { - X_AudioSprite_instance[ 'pause' ]( i ); - //}; - }; - }, - - /** * 再生 * @param {string} name トラック名 * @return {number} uid @@ -182,13 +170,13 @@ X_AudioSprite_members = if( bgm ){ track = bgm; } else - if( 1 < tracks.length ){ + if( 1 < X_AudioSprite_numTracks ){ track = X_AudioSprite_TEMP.bgmTrack = X_AudioSprite_getTrackEnded(); } else { track = X_AudioSprite_TEMP.bgmTrack = tracks[ 0 ]; }; - if( track[ 'listen' ]( [ X_EVENT_MEDIA_PLAYING, X_EVENT_MEDIA_WAITING, X_EVENT_MEDIA_SEEKING, X_EVENT_MEDIA_BEFORE_LOOP ], X_AudioSprite_instance, X_AudioSprite_handleEvent ).playing ){ + if( track[ 'listen' ]( [ X_EVENT_MEDIA_PLAYING, X_EVENT_MEDIA_WAITING, X_EVENT_MEDIA_SEEKING, X_EVENT_MEDIA_BEFORE_LOOP ], X_AudioSprite, X_AudioSprite_handleEvent ).playing ){ track.setState({ 'loop' : true, 'looped' : X_AudioSprite_TEMP.bgmLooped, @@ -205,10 +193,10 @@ X_AudioSprite_members = }; } else { - if( 1 < tracks.length ){ + if( 1 < X_AudioSprite_numTracks ){ track = X_AudioSprite_getTrackEnded( X_AudioSprite_TEMP.bgmPlaying ); track - [ 'listen' ]( [ X_EVENT_MEDIA_PLAYING, X_EVENT_MEDIA_WAITING, X_EVENT_MEDIA_SEEKING, X_EVENT_MEDIA_BEFORE_LOOP ], X_AudioSprite_instance, X_AudioSprite_handleEvent ) + [ 'listen' ]( [ X_EVENT_MEDIA_PLAYING, X_EVENT_MEDIA_WAITING, X_EVENT_MEDIA_SEEKING, X_EVENT_MEDIA_BEFORE_LOOP ], X_AudioSprite, X_AudioSprite_handleEvent ) .setState( { 'looped' : false } ); track.play( preset[ 0 ], preset[ 1 ], true, 0, X_AudioSprite_lengthSilence ); } else { @@ -220,11 +208,11 @@ X_AudioSprite_members = }; track = tracks[ 0 ]; - if( track[ 'listen' ]( [ X_EVENT_MEDIA_PLAYING, X_EVENT_MEDIA_WAITING, X_EVENT_MEDIA_SEEKING, X_EVENT_MEDIA_BEFORE_LOOP ], X_AudioSprite_instance, X_AudioSprite_handleEvent ).playing ){ + if( track[ 'listen' ]( [ X_EVENT_MEDIA_PLAYING, X_EVENT_MEDIA_WAITING, X_EVENT_MEDIA_SEEKING, X_EVENT_MEDIA_BEFORE_LOOP ], X_AudioSprite, X_AudioSprite_handleEvent ).playing ){ track.setState({ 'loop' : true, 'looped' : false, - //'currentTime' : preset[ 0 ], + 'currentTime' : preset[ 0 ], 'startTime' : preset[ 0 ], 'endTime' : preset[ 1 ], 'loopStartTime' : 0, @@ -242,26 +230,34 @@ X_AudioSprite_members = }, /** - * ポーズ - * @param {number} uid トラックID - * @return {number} uid + * ポーズ, uid を指定しない、または '*' で呼び出した場合、全てのトラックを pause する。 + * @param {number} uid=undefined トラックID, '*' + * @return {AudioSprite} */ 'pause' : function( uid ){ - var track = X_AudioSprite_TEMP.tracks[ uid ]; + var tracks = X_AudioSprite_TEMP.tracks, + i, l, track; - if( X_AudioSprite_TEMP.bgmTrack === track ){ - X_AudioSprite_TEMP.bgmPosition = track.currentTime(); - X_AudioSprite_TEMP.bgmPlaying = false; - X_AudioSprite_TEMP.bgmTrack = null; + if( uid === '*' || uid === undefined ){ + for( i = 0, l = X_AudioSprite_numTracks; i < l; ++i ){ + X_AudioSprite[ 'pause' ]( i ); + }; + } else + if( track = tracks[ uid ] ){ + if( X_AudioSprite_TEMP.bgmTrack === track ){ + X_AudioSprite_TEMP.bgmPosition = track.currentTime(); + X_AudioSprite_TEMP.bgmPlaying = false; + X_AudioSprite_TEMP.bgmTrack = null; + }; + track.play( 0, X_AudioSprite_lengthSilence, true, 0, X_AudioSprite_lengthSilence ); + track.seek( 0 ); + X_AudioSprite[ 'asyncDispatch' ]( X_EVENT_MEDIA_PAUSED ); }; - track && track.play( 0, X_AudioSprite_lengthSilence, true, 0, X_AudioSprite_lengthSilence ); - track && track.seek( 0 ); - X_AudioSprite_instance[ 'asyncDispatch' ]( X_EVENT_MEDIA_PAUSED ); - return X_AudioSprite_instance; + return X_AudioSprite; }, /** - * シーク + * シーク, 現在のトラックの長さ内で相対指定する * @param {number} uid トラックID * @param {number} position ms * @return {AudioSprite} @@ -275,7 +271,7 @@ X_AudioSprite_members = start = X_Audio_getStartTime( track, end ); 0 <= position && position <= ( end - start ) && track.seek( start + position ); }; - return X_AudioSprite_instance; + return X_AudioSprite; }, /** @@ -291,17 +287,17 @@ X_AudioSprite_members = if( opt_volume === undefined ){ return X_AudioSprite_TEMP.volume; }; - for( i = X_AudioSprite_TEMP.tracks.length; i; ){ + for( i = X_AudioSprite_numTracks; i; ){ X_AudioSprite_TEMP.tracks[ --i ].volume( opt_volume ); }; - return X_AudioSprite_instance; + return X_AudioSprite; }; track = X_AudioSprite_TEMP.tracks[ uid ]; if( opt_volume === undefined ){ return track ? track.gain : -1; }; track && track.volume( opt_volume ); - return X_AudioSprite_instance; + return X_AudioSprite; }, /** @@ -329,12 +325,12 @@ X_AudioSprite_members = return { 'volume' : X_AudioSprite_TEMP.volume, 'playing' : false }; }; track && track.setState( opt_obj ); - return X_AudioSprite_instance; + return X_AudioSprite; } }; function X_AudioSprite_backendHandler( e ){ - var i, backend, option, src, name, last, _e; + var i, backend, option, src, name, last, _e, track; switch( e.type ){ case X_EVENT_BACKEND_READY : @@ -342,19 +338,21 @@ function X_AudioSprite_backendHandler( e ){ backend = X_Audio_BACKENDS[ e[ 'backendID' ] ]; option = e[ 'option' ]; - X_AudioSprite_instance[ 'unlisten' ]( X_EVENT_BACKEND_NONE, X_AudioSprite_backendHandler ); - X_AudioSprite_instance[ 'source' ] = src = e[ 'source' ]; - X_AudioSprite_instance[ 'backendName' ] = name = backend.backendName; + X_AudioSprite[ 'unlisten' ]( X_EVENT_BACKEND_NONE, X_AudioSprite_backendHandler ); + X_AudioSprite[ 'source' ] = src = e[ 'source' ]; + X_AudioSprite[ 'backendName' ] = name = backend.backendName; //console.log( i + ' / ' + X_AudioSprite_numTracks ); for( i = 0; i < X_AudioSprite_numTracks; ++i ){ if( X_AudioSprite_useVideo || ( i === 1 && X_AudioSprite_useVideoForMulti ) ){ + option = X_Object_deepCopy( option ); option[ 'useVideo' ] = true; console.log( 'use video' ); }; // Audiobackend の owner として null を渡すとAudioBackend 自身へ dispatch する - X_AudioSprite_TEMP.tracks.push( last = backend.klass( null, e[ 'source' ], option )[ 'listen' ]( X_EVENT_DEBUG, X_AudioSprite_instance, X_AudioSprite_handleEvent ) ); + X_AudioSprite_TEMP.tracks.push( + last = backend.klass( null, e[ 'source' ], option )[ 'listen' ]( X_EVENT_DEBUG, X_AudioSprite, X_AudioSprite_handleEvent ) ); }; _e = { @@ -363,51 +361,33 @@ function X_AudioSprite_backendHandler( e ){ 'backendName' : name }; // touch 可能で backend ready - - if( name === 'WebAudio' ){ - if( _e[ 'needTouchForPlay' ] = X_WebAudio_need1stTouch ){ - last[ 'listenOnce' ]( X_EVENT_READY, X_AudioSprite_instance, X_AudioSprite_instance[ 'asyncDispatch' ], [ _e ] ); - } else { - X_AudioSprite_instance[ 'asyncDispatch' ]( _e ); - }; - last[ 'listenOnce' ]( X_EVENT_READY, X_AudioSprite_instance, X_AudioSprite_backendHandler ); + // WebAudio + if( backend.backendID === 1 && ( _e[ 'needTouchForPlay' ] = X_WebAudio_need1stTouch ) ){ + last[ 'listenOnce' ]( X_EVENT_READY, X_AudioSprite, X_AudioSprite[ 'asyncDispatch' ], [ _e ] ); } else - if( name === 'HTMLAudio' ){ - if( _e[ 'needTouchForLoad' ] = X_HTMLAudio_need1stTouch ){ - last[ 'listenOnce' ]( X_EVENT_MEDIA_TOUCH_FOR_LOAD, X_AudioSprite_instance, X_AudioSprite_instance[ 'asyncDispatch' ], [ _e ] ); - last[ 'listenOnce' ]( X_EVENT_READY, X_AudioSprite_instance, X_AudioSprite_backendHandler ); - } else { - X_AudioSprite_instance[ 'asyncDispatch' ]( _e ); - last[ 'listenOnce' ]( X_EVENT_READY, X_AudioSprite_instance, X_AudioSprite_backendHandler ); - - // READY, needTouchForPlay, needTouchForLoad - if( X_HTMLAudio_durationFix ){ - for( i = 0; i < X_AudioSprite_TEMP.tracks.length; ++i ){ - X_AudioSprite_instance[ 'pause' ]( i ); - }; - }; - }; - + // HTMLAudio + if( backend.backendID === 2 && ( _e[ 'needTouchForLoad' ] = X_HTMLAudio_need1stTouch ) ){ + last[ 'listenOnce' ]( X_EVENT_MEDIA_TOUCH_FOR_LOAD, X_AudioSprite, X_AudioSprite[ 'asyncDispatch' ], [ _e ] ); } else { - X_AudioSprite_instance[ 'asyncDispatch' ]( _e ); - - console.log( 'AudioSprite - X_EVENT_BACKEND_READY' ); - - last[ 'listenOnce' ]( X_EVENT_READY, X_AudioSprite_instance, X_AudioSprite_backendHandler ); + X_AudioSprite[ 'asyncDispatch' ]( _e ); }; + + last[ 'listenOnce' ]( X_EVENT_READY, X_AudioSprite, X_AudioSprite_backendHandler ); return X_CALLBACK_STOP_NOW; case X_EVENT_BACKEND_NONE : - X_AudioSprite_instance[ 'unlisten' ]( X_EVENT_BACKEND_READY, X_AudioSprite_instance, X_AudioSprite_backendHandler ) + X_AudioSprite[ 'unlisten' ]( X_EVENT_BACKEND_READY, X_AudioSprite, X_AudioSprite_backendHandler ) [ 'asyncDispatch' ]( X_EVENT_BACKEND_NONE ); return X_CALLBACK_STOP_NOW; case X_EVENT_READY : console.log( 'X.AudioSprite - Ready!' ); - for( i = 0; i < X_AudioSprite_TEMP.tracks.length; ++i ){ - X_AudioSprite_instance[ 'pause' ]( i ); + for( i = 0; i < X_AudioSprite_numTracks; ++i ){ + track = X_AudioSprite_TEMP.tracks[ i ]; + ( track.autoplay || track._playReserved ) && track.actualPlay(); + delete track._playReserved; }; - X_AudioSprite_instance[ 'asyncDispatch' ]( X_EVENT_READY ); + X_AudioSprite[ 'asyncDispatch' ]( X_EVENT_READY ); break; }; }; @@ -418,22 +398,22 @@ function X_AudioSprite_handleEvent( e ){ switch( e.type ){ case X_EVENT_MEDIA_PLAYING : - ( e.target === X_AudioSprite_TEMP.bgmTrack || !e.target.looped ) && X_AudioSprite_instance[ 'asyncDispatch' ]( X_EVENT_MEDIA_PLAYING ); + ( e.target === X_AudioSprite_TEMP.bgmTrack || !e.target.looped ) && X_AudioSprite[ 'asyncDispatch' ]( X_EVENT_MEDIA_PLAYING ); break; case X_EVENT_MEDIA_WAITING : case X_EVENT_MEDIA_SEEKING : - ( e.target === X_AudioSprite_TEMP.bgmTrack || !e.target.looped ) && X_AudioSprite_instance[ 'asyncDispatch' ]( e.type ); + ( e.target === X_AudioSprite_TEMP.bgmTrack || !e.target.looped ) && X_AudioSprite[ 'asyncDispatch' ]( e.type ); break; case X_EVENT_MEDIA_BEFORE_LOOP : if( e.target === X_AudioSprite_TEMP.bgmTrack ){ X_AudioSprite_TEMP.bgmLooped = true; - X_AudioSprite_instance[ 'asyncDispatch' ]( X_EVENT_MEDIA_LOOPED ); // TODO uid + X_AudioSprite[ 'asyncDispatch' ]( X_EVENT_MEDIA_LOOPED ); // TODO uid } else { if( e.target.looped ){ - // X_AudioSprite_instance[ 'asyncDispatch' ]( X_EVENT_MEDIA_LOOPED ); // TODO uid + // X_AudioSprite[ 'asyncDispatch' ]( X_EVENT_MEDIA_LOOPED ); // TODO uid } else { - X_AudioSprite_instance[ 'asyncDispatch' ]( X_EVENT_MEDIA_ENDED ); // TODO uid + X_AudioSprite[ 'asyncDispatch' ]( X_EVENT_MEDIA_ENDED ); // TODO uid }; //console.log( '[AudioSprite] bgmPlaying:' + X_AudioSprite_TEMP.bgmPlaying + ' ' + !X_AudioSprite_TEMP.bgmTrack ); @@ -441,7 +421,7 @@ function X_AudioSprite_handleEvent( e ){ // single track | iOS if( X_AudioSprite_TEMP.bgmPlaying && !X_AudioSprite_TEMP.bgmTrack ){ X_AudioSprite_TEMP.bgmTrack = e.target; - X_AudioSprite_instance.play( X_AudioSprite_TEMP.bgmName ); + X_AudioSprite.play( X_AudioSprite_TEMP.bgmName ); return X_CALLBACK_PREVENT_DEFAULT; }; }; @@ -452,7 +432,7 @@ function X_AudioSprite_handleEvent( e ){ i = X_AudioSprite_TEMP.tracks.indexOf( e.target ); if( 0 <= i ){ e[ 'trackID' ] = i; - X_AudioSprite_instance[ 'dispatch' ]( e ); + X_AudioSprite[ 'dispatch' ]( e ); }; break; @@ -468,15 +448,17 @@ function X_AudioSprite_handleEvent( e ){ console.log( '■ デアクティブ' ); // track.pause(); tracks = X_AudioSprite_TEMP.tracks; - i = tracks.length; + i = X_AudioSprite_numTracks; for( ; i; ){ track = tracks[ --i ]; track.playing && X_AudioSprite_TEMP.pauseTracks.push( track ) && track.pause(); }; break; + case X_EVENT_UNLOAD : + console.log( '■ unload' ); + case X_EVENT_KILL_INSTANCE : - while( X_AudioSprite_TEMP.tracks.length ){ X_AudioSprite_TEMP.tracks.pop()[ 'kill' ](); }; @@ -494,7 +476,7 @@ function X_AudioSprite_handleEvent( e ){ X_AudioSprite_TEMP.bgmLooped = false; X_AudioSprite_TEMP.bgmPlaying = false; - X_ViewPort[ 'unlisten' ]( [ X_EVENT_VIEW_ACTIVATE, X_EVENT_VIEW_DEACTIVATE ], X_AudioSprite_instance, X_AudioSprite_handleEvent ); + X_ViewPort[ 'unlisten' ]( [ X_EVENT_VIEW_ACTIVATE, X_EVENT_VIEW_DEACTIVATE, X_EVENT_UNLOAD ], X_AudioSprite, X_AudioSprite_handleEvent ); break; }; }; -- 2.11.0