OSDN Git Service

Version 0.6.208, bug fixes.
[pettanr/clientJs.git] / 0.6.x / js / 07_audio / 01_XWebAudio.js
index bded21f..5e97299 100644 (file)
@@ -1,8 +1,8 @@
 var X_Audio_constructor = 3.1 <= X_UA[ 'Safari' ] && X_UA[ 'Safari' ] < 4 ?
                                                                function( s, a ){
-                                                                       a = document.createElement( 'audio' );
-                                                                       a.src = s;
-                                                                       a.load();
+                                                                       //a = document.createElement( 'audio' );
+                                                                       //a.src = s;
+                                                                       //a.load();
                                                                        return a;
                                                                } :
                                                // Android1.6 + MobileOpera12 HTMLAudio はいるが呼ぶとクラッシュする
@@ -78,14 +78,23 @@ if( X_Audio_constructor ){
 };
 
 
-var X_WebAudio_context = !X_UA[ 'iPhone_4s' ]  && !X_UA[ 'iPad_2Mini1' ]  && !X_UA[ 'iPod_4' ]  &&
-                                                               // TODO なんで fennec を禁止?
-                                                               !( X_UA[ 'Gecko' ] && X_UA[ 'Android' ] ) &&
+var X_WebAudio_context      =  // 4s 以下ではない iPad 2G または iPad mini 1G 以下ではない, iPod touch 4G 以下ではない
+                                                               !X_UA[ 'iPhone_4s' ] && !X_UA[ 'iPad_2Mini1' ] && !X_UA[ 'iPod_4' ] &&
+                                                               // iOS7 以上で HTML Audio が鳴らない問題を見ていくよ
+                                                               // !X_UA[ 'iOS' ] &&
+                                                               // Android2 + Gecko で WebAudio が極めて不安定
+                                                               !( X_UA[ 'Fennec' ] && X_UA[ 'Android' ] < 3 ) &&
+                                                               // AOSP でも WebAudio を不完全に実装するものがある, touch の有無も不明のため一律に切ってしまう
+                                                               !X_UA[ 'AOSP' ] && !( X_UA[ 'ChromeWV' ] < 5 ) &&
+                                                               // Blink HTMLAudio 調査用
+                                                               //!X_UA[ 'Blink' ] &&
                                                                // Firefox40.0.5 + Windows8 で音声が途中から鳴らなくなる
                                                                // Firefox41.0.1 + Windows8 で音声が途中から鳴らなくなる
-                                                               !( 40 <= X_UA[ 'Gecko' ] && X_UA[ 'Gecko' ] < 42 && X_UA[ 'Windows' ] ) &&
+                                                               !( 40 <= X_UA[ 'Gecko' ] && X_UA[ 'Gecko' ] < 45 && X_UA[ 'Windows' ] ) &&
                                                                ( window[ 'AudioContext' ] || window[ 'webkitAudioContext' ] ),
-       X_WebAudio_BUFFER_LIST      = [],
+       X_WebAudio_BUFFER_LIST  = [],
+       X_WebAudio_need1stTouch = X_UA[ 'iOS' ],
+       X_WebAudio_touchState   = X_WebAudio_need1stTouch,
        X_WebAudio,
        X_WebAudio_BufferLoader,
        X_WebAudio_fpsFix;
@@ -120,9 +129,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 :
@@ -155,7 +168,7 @@ if( X_WebAudio_context ){
                                _onDecodeSuccess : function( buffer ){
                                        this.onDecodeSuccess && this._onDecodeComplete();
                                        
-                       if ( !buffer ) {
+                       if( !buffer ){
                                this.errorState = 2;
                            this[ 'asyncDispatch' ]( X_EVENT_COMPLETE );
                            return;
@@ -187,9 +200,10 @@ if( X_WebAudio_context ){
                        unregister : function( webAudio ){
                                var list = this.webAudioList,
                                        i    = list.indexOf( webAudio );
+
                                if( 0 < i ){
                                        list.splice( i, 1 );
-                                       if( list.length ){
+                                       if( !list.length ){
                                                this.xhr && this.xhr[ 'kill' ]();
                                                this[ 'kill' ]();
                                        };
@@ -217,7 +231,7 @@ if( X_WebAudio_context ){
             gainNode        : null,
             _onended        : null,
             
-                       'Constructor' : function( target, url, option ){                                
+                       'Constructor' : function( disatcher, url, option ){                             
                                var i = 0,
                                        l = X_WebAudio_BUFFER_LIST.length,
                                        loader;
@@ -245,8 +259,7 @@ if( X_WebAudio_context ){
                                        this.loader = loader = X_WebAudio_BufferLoader( this, url );
                                };
                                
-                               this.target  = target || this;
-                               
+                               this.disatcher = disatcher || this;
                                this.setState( option );
                                
                                this[ 'listenOnce' ]( X_EVENT_KILL_INSTANCE, this.onKill );
@@ -279,8 +292,7 @@ if( X_WebAudio_context ){
                                        
                        if ( !buffer ) {
                                this.error = loader.errorState;
-                               
-                           this.target[ 'dispatch' ]({
+                           this.disatcher[ 'dispatch' ]({
                                                                type    : X_EVENT_ERROR,
                                                                error   : loader.errorState,
                                                                message : loader.errorState === 1 ?
@@ -294,22 +306,31 @@ if( X_WebAudio_context ){
                        this.audioBuffer = buffer;
                        this.duration    = buffer.duration * 1000;
 
-                                       this.target[ 'asyncDispatch' ]( X_EVENT_READY );
-                       
-                       console.log( 'WebAudio buffer ready' );
-                       
-                       this.autoplay && X_Timer_once( 16, this, this.play );
-                                       
+                                       this.disatcher[ 'asyncDispatch' ]( X_WebAudio_touchState ? X_EVENT_MEDIA_TOUCH_FOR_LOAD : X_EVENT_READY );
                                },
                        
                        actualPlay : function(){
-                               var begin, end;
+                               var e, begin, end;
+                               
+                               console.log( '[WebAudio] play abuf:' + !!this.audioBuffer );
                                
                    if( !this.audioBuffer ){
-                       this.autoplay = true;
+                       this._playReserved = true;
                        return;
                    };
                                
+                               if( X_WebAudio_touchState ){
+                                       e = X_EventDispatcher_CURRENT_EVENTS[ X_EventDispatcher_CURRENT_EVENTS.length - 1 ];
+                                       if( !e || !e[ 'pointerType' ] ){
+                                               // alert( 'タッチイベント以外での play! ' + ( e ? e.type : '' ) );
+                                               return;
+                                       };
+                                       // http://qiita.com/uupaa/items/e5856e3cb2a9fc8c5507
+                                       // iOS9 + touchstart で呼んでいた場合、 X_ViewPort['listenOnce']('pointerup',this,this.actualPlay())
+                                       this.disatcher[ 'asyncDispatch' ]( X_EVENT_READY );
+                               };
+                               X_WebAudio_touchState = false;
+                               
                                end   = X_Audio_getEndTime( this );
                                begin = X_Audio_getStartTime( this, end, true );
                                
@@ -328,13 +349,14 @@ if( X_WebAudio_context ){
                    
                    // おかしい、stop 前に外していても呼ばれる、、、@Firefox33.1
                    // 破棄された X.Callback が呼ばれて、obj.proxy() でエラーになる。Firefox では、onended は使わない
-                if( false && this.bufferSource.onended !== undefined ){
+                   // 多くのブラウザで onended は timer を使ったカウントより遅いので使わない
+                //if( this.bufferSource.onended !== undefined ){
                        //console.log( '> use onended' );
-                       this.bufferSource.onended = this._onended || ( this._onended = X_Closure_create( this, this._onEnded ) );
-                } else {
+                       //this.bufferSource.onended = this._onended || ( this._onended = X_Closure_create( this, this._onEnded ) );
+                //} else {
                        this._timerID && X_Timer_remove( this._timerID );
                                        this._timerID = X_Timer_once( end - begin, this, this._onEnded );
-                };
+                //};
        
                    if( this.bufferSource.start ){
                        this.bufferSource.start( 0, begin / 1000, end / 1000 );
@@ -351,7 +373,7 @@ if( X_WebAudio_context ){
                        
                                _sourceDispose : function(){
                            this.bufferSource.disconnect();
-                           delete this.bufferSource.onended;
+                           //delete this.bufferSource.onended;
                            delete this.bufferSource;
                        },
 
@@ -360,7 +382,7 @@ if( X_WebAudio_context ){
                                                delete this._interval;
                                                return X_CALLBACK_UN_LISTEN;
                                        };
-                                       this.target[ 'dispatch' ]( X_EVENT_MEDIA_PLAYING );
+                                       this.disatcher[ 'dispatch' ]( X_EVENT_MEDIA_PLAYING );
                                },
                                                
                                _onEnded : function(){
@@ -383,31 +405,27 @@ if( X_WebAudio_context ){
                                };
                                
                                if( this.autoLoop ){
-                                       if( !( this.target[ 'dispatch' ]( X_EVENT_MEDIA_BEFORE_LOOP ) & X_CALLBACK_PREVENT_DEFAULT ) ){
+                                       if( !( this.disatcher[ 'dispatch' ]( X_EVENT_MEDIA_BEFORE_LOOP ) & X_CALLBACK_PREVENT_DEFAULT ) ){
                                                this.looped = true;
-                                               this.target[ 'dispatch' ]( X_EVENT_MEDIA_LOOPED );
+                                               this.disatcher[ 'dispatch' ]( X_EVENT_MEDIA_LOOPED );
                                                this.actualPlay();
                                        };
                                } else {
                                        this.actualPause();
-                                       this.target[ 'dispatch' ]( X_EVENT_MEDIA_ENDED );
+                                       this.disatcher[ 'dispatch' ]( X_EVENT_MEDIA_ENDED );
                                };
                            };
                                },
                        
                        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;
 
                    if( this.bufferSource ){
-                       if( this.bufferSource.onended ) delete this.bufferSource.onended;
+                       //if( this.bufferSource.onended ) delete this.bufferSource.onended;
                        
                        this.bufferSource.stop ? 
                                this.bufferSource.stop( 0 ) : this.bufferSource[ 'noteOff' ]( 0 );