X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=0.6.x%2Fjs%2F07_audio%2F00_XAudio.js;h=5572486fee13fcc3201bcd22ab7aa46852f1894f;hb=b8b45541169da1fad8e5454c266f837ea3c52961;hp=4675b135a7b1d514d0f557ae6fd6ed1aa685b24f;hpb=7f26e99d39211b5749c4ad62a84855404c7390a3;p=pettanr%2FclientJs.git diff --git a/0.6.x/js/07_audio/00_XAudio.js b/0.6.x/js/07_audio/00_XAudio.js index 4675b13..5572486 100644 --- a/0.6.x/js/07_audio/00_XAudio.js +++ b/0.6.x/js/07_audio/00_XAudio.js @@ -1,64 +1,79 @@  X.Audio = { - HTML5 : 1, - Flash : 2, - Silverlight : 3, - Unity : 4, - WMP : 5, - RealPlayer : 6, - QuickTime : 7, + WebAudio : 1, + HTML5 : 2, + Flash : 3, + Silverlight : 4, + Unity : 5, + WMP : 6, + RealPlayer : 7, + QuickTime : 8, create : function( sourceList, opt_option ){ return new X_AudioProxy( X.Type.isArray( sourceList ) ? X_Object_cloneArray( sourceList ) : [ sourceList ], opt_option || {} ); } }; -var X_Audio_BACKENDS = []; +var X_Audio_BACKENDS = [], + X_Audio_WRAPPER_LIST = []; /* * TODO preplayerror play してみたら error が出た、backend の変更。 */ function X_Audio_detectBackend( proxy, sourceList, option ){ - var source = sourceList.shift() || '', - parts = source.split( '?' )[ 0 ].split( '#' )[ 0 ].split( '.' ), - ext = parts[ parts.length - 1 ], - backend, ext, sup; + var source = sourceList.shift() || '', + parts = X_URL_cleanup( source ).split( '.' ), + ext = parts[ parts.length - 1 ], + backend = X_Audio_BACKENDS[ 0 ], + ext, sup; - if( source && X_Audio_BACKENDS.length ){ + if( source && backend ){ sup = [ proxy, option, sourceList, source, ext ]; sup[ 5 ] = sup; - X_Audio_BACKENDS[ 0 ] - .detect( source, ext ) - .listenOnce( [ 'support', 'nosupport' ], X_Audio_detectComplete, sup ); + + proxy.listenOnce( [ 'support', 'nosupport' ], backend, X_Audio_detectComplete, sup ); + backend.detect( proxy, source, ext ); } else { - proxy.asyncDispatch( 0, 'nobackend' ); + proxy.asyncDispatch( 'nobackend' ); }; }; function X_Audio_detectComplete( e, proxy, option, sourceList, source, ext, sup ){ var i = X_Audio_BACKENDS.indexOf( this ), backend; - this.unlisten( [ 'support', 'nosupport' ], X_Audio_detectComplete, sup ); + proxy.unlisten( [ 'support', 'nosupport' ], backend, X_Audio_detectComplete, sup ); switch( e.type ){ case 'support' : proxy._backend = i; - proxy.asyncDispatch( 0, { type : 'backendfound', option : option, source : source } ); + proxy.asyncDispatch( { + type : 'backendfound', + option : option, + source : source, + backendName : this.backendName + } ); break; case 'nosupport' : if( backend = X_Audio_BACKENDS[ i + 1 ] ){ - backend.detect( source, ext ).listen( [ 'support', 'nosupport' ], X_Audio_detectComplete, sup ); + proxy.listenOnce( [ 'support', 'nosupport' ], backend, X_Audio_detectComplete, sup ); + backend.detect( proxy, source, ext ); } else if( sourceList.length ){ X_Audio_detectBackend( proxy, sourceList, option ); } else { - proxy.asyncDispatch( 0, 'nobackend' ); + proxy.asyncDispatch( 'nobackend' ); }; break; }; }; +function X_AudioProxy_getAudioWrapper( proxy ){ + var i = X_Audio_WRAPPER_LIST.length; + for( ; i; ){ + if( X_Audio_WRAPPER_LIST[ --i ].proxy === proxy ) return X_Audio_WRAPPER_LIST[ i ]; + }; +}; var X_AudioProxy = X.EventDispatcher.inherits( 'X.AV.AudioProxy', @@ -74,44 +89,93 @@ var X_AudioProxy = X.EventDispatcher.inherits( }, close : function(){ - return this._backend !== -1 && X_Audio_BACKENDS[ this._backend ].close.call( this ); + return this._backend !== -1 && X_AudioProxy_getAudioWrapper( this ).close(); }, - play : function( position ){ - //console.log( 'proxy play ' + this._backend ); - return this._backend !== -1 && X_Audio_BACKENDS[ this._backend ].play.call( this, position ); + play : function( startTime, endTime, loop, loopStartTime, loopEndTime ){ + var state, duration; + if( 0 <= startTime ){ + this.state( { + currentTime : startTime, + startTime : startTime, + endTime : endTime, + loop : loop, + loopStartTime : loopStartTime, + loopEndTime : loopEndTime + } ); + }; + this._backend !== -1 && X_AudioProxy_getAudioWrapper( this ).play(); + return this; }, - pause : function(){ - return this._backend !== -1 && X_Audio_BACKENDS[ this._backend ].pause.call( this ); + seek : function( seekTime ){ + var state = this.state(), + end = X_AudioWrapper_getEndTime( X_AudioProxy_getAudioWrapper( this ) ); + if( seekTime < end ){ + this.state( { currentTime : seekTime } ); + }; + return this; }, - stop : function(){ - return this._backend !== -1 && X_Audio_BACKENDS[ this._backend ].stop.call( this ); + pause : function(){ + this.state().playing && X_AudioProxy_getAudioWrapper( this ).pause(); + return this; }, - loop : function( v ){ - return this._backend !== -1 && X_Audio_BACKENDS[ this._backend ].loop.call( this, v ); - }, + state : function( obj ){ + var backend = this._backend !== -1 && X_AudioProxy_getAudioWrapper( this ); - state : function(){ - return this._backend !== -1 && X_Audio_BACKENDS[ this._backend ].state.call( this ); + if( obj === undefined ){ + return backend ? + backend.state() : + { + startTime : -1, + endTime : -1, + loopStartTime : -1, + loopEndTime : -1, + currentTime : -1, + loop : false, + looded : false, + error : false, + playing : false, + + source : this.source || '', + duration : 0 + }; + }; + backend && backend.state( obj ); + return this; + }, + + loop : function( v ){ + var backend = this._backend !== -1 && X_AudioProxy_getAudioWrapper( this ); + if( v === undefined ){ + return backend && backend.state().loop; + }; + backend && backend.state( { loop : v } ); + return this; }, volume : function( v ){ - return this._backend !== -1 && X_Audio_BACKENDS[ this._backend ].volume.call( this, v ); - }, - - startTime : function( time ){ - return this._backend !== -1 && X_Audio_BACKENDS[ this._backend ].startTime.call( this, time ); + var backend = this._backend !== -1 && X_AudioProxy_getAudioWrapper( this ); + if( v === undefined ){ + return backend && backend.state().volume; + }; + backend && backend.state( { volume : v } ); + return this; }, - currentTime : function( time ){ - return this._backend !== -1 && X_Audio_BACKENDS[ this._backend ].currentTime.call( this, time ); + currentTime : function( v ){ + var backend = this._backend !== -1 && X_AudioProxy_getAudioWrapper( this ); + if( v === undefined ){ + return backend && backend.state().currentTime; + }; + backend && backend.state( { currentTime : v } ); + return this; }, isPlaying : function(){ - return this._backend !== -1 && X_Audio_BACKENDS[ this._backend ].isPlaying.call( this ); + return this._backend !== -1 && X_AudioProxy_getAudioWrapper( this ).state().playing; } } @@ -123,7 +187,7 @@ function X_AudioProxy_handleEvent( e ){ this.unlisten( 'nobackend', X_AudioProxy_handleEvent ); this.source = e.source; this.backendName = X_Audio_BACKENDS[ this._backend ].backendName; - X_Audio_BACKENDS[ this._backend ].register( this, e.source, e.option ); + X_Audio_WRAPPER_LIST.push( new X_Audio_BACKENDS[ this._backend ].klass( this, e.source, e.option ) ); break; case 'nobackend' : @@ -136,4 +200,146 @@ function X_AudioProxy_handleEvent( e ){ }; }; +function X_AudioWrapper_updateStates( audioWrapper, obj ){ + var playing = audioWrapper.playing, + k, v, + end = 0, seek = 0, volume = 0; + + for( k in obj ){ + v = obj[ k ]; + switch( k ){ + case 'currentTime' : + v = X_AudioWrapper_timeStringToNumber( v ); + if( X.Type.isNumber( v ) ){ + if( playing ){ + if( audioWrapper.state().currentTime !== v ){ + audioWrapper.seekTime = v; + seek = 2; + }; + } else { + audioWrapper.seekTime = v; + }; + } else { + continue; + }; + break; + + case 'startTime' : + case 'endTime' : + case 'loopStartTime' : + case 'loopEndTime' : + v = X_AudioWrapper_timeStringToNumber( v ); + console.log( k + ' ' + v ); + if( v || v === 0 ){ + if( audioWrapper[ k ] !== v ){ + audioWrapper[ k ] = v; + + // 再生中の endTime の変更 + if( playing && ( k === 'endTime' || k === 'loopEndTime' ) ) end = 1; + }; + } else { + delete audioWrapper[ k ]; + if( playing && ( k === 'endTime' || k === 'loopEndTime' ) ) end = 1; + }; + break; + + case 'looped' : + if( playing ) seek = 2; + case 'loop' : + case 'autoplay' : + if( X.Type.isBoolean( v ) && audioWrapper[ k ] !== v ){ + audioWrapper[ k ] = v; + }; + break; + + case 'volume' : + if( X.Type.isNumber( v ) ){ + v = v < 0 ? 0 : 1 < v ? 1 : v; + if( audioWrapper[ k ] !== v ){ + audioWrapper[ k ] = v; + // if playing -> update + if( playing ) volume = 4; + }; + }; + break; + }; + }; + + if( audioWrapper.endTime < audioWrapper.startTime || + ( audioWrapper.loopEndTime < 0 ? audioWrapper.endTime : audioWrapper.loopEndTime ) < ( audioWrapper.loopStartTime < 0 ? audioWrapper.startTime : audioWrapper.loopStartTime ) || + X_AudioWrapper_getEndTime( audioWrapper ) < audioWrapper.seekTime// || + //audioWrapper.duration < audioWrapper.endTime + ){ + console.log( 'error @updateStateObject() begin:' + audioWrapper.startTime + ' end:' + audioWrapper.endTime + ' d:' + audioWrapper.duration + ' ls:' + audioWrapper.loopStartTime ); + return 0; + }; + + return end + seek + volume; +}; + +function X_AudioWrapper_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; + + ary = time.split( '.' ); + ms = parseInt( ( ary[ 1 ] + '000' ).substr( 0, 3 ) ) || 0; + + ary = ary[ 0 ].split( ':' ); + if( 3 < ary.length ) return; + + switch( ary.length ){ + case 0 : + break; + case 1 : + s = parseInt( ary[ 0 ] ) || 0; + break; + case 2 : + m = parseInt( ary[ 0 ] ) || 0; + s = parseInt( ary[ 1 ] ) || 0; + if( 60 <= s ) alert( 'invalid time string ' + time ); + break; + case 3 : + h = parseInt( ary[ 0 ] ) || 0; + m = parseInt( ary[ 1 ] ) || 0; + s = parseInt( ary[ 2 ] ) || 0; + if( 60 <= s ) alert( 'invalid time string ' + time ); + if( 60 <= m ) alert( 'invalid time string ' + time ); + break; + default : + alert( 'invalid time string ' + time ); + }; + ms = ( h * 3600 + m * 60 + s ) * 1000 + ms; + return ms < 0 ? 0 : ms; +}; + +function X_AudioWrapper_getStartTime( audioWrapper, endTime, delSeekTime ){ + var seek = audioWrapper.seekTime; + if( delSeekTime ) delete audioWrapper.seekTime; + + if( 0 <= seek ){ + if( audioWrapper.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( audioWrapper.startTime < 0 || audioWrapper.duration <= audioWrapper.startTime ) return 0; + return audioWrapper.startTime; +}; + +function X_AudioWrapper_getEndTime( audioWrapper ){ + var duration = audioWrapper.duration; + + if( audioWrapper.looped && 0 <= audioWrapper.loopEndTime ){ + if( duration <= audioWrapper.loopEndTime ) return duration; + return audioWrapper.loopEndTime; + }; + + if( audioWrapper.endTime < 0 || duration <= audioWrapper.endTime ) return duration; + return audioWrapper.endTime; +};