* Windows 版 Safari は QuickTime のインストールが必要\r
* \r
* 1. iOS4(iPod 2G) で ended に達すると音が鳴らなくなる fix で解決\r
- * 2. iOS6(iPod 4G) で ended に達すると音が鳴らなくなる fix で頻度が改善\r
+ * 2. iOS6(iPod 4G) で ended に達すると音が鳴らなくなる fix で頻度が改善 emded イベントは発しないので、timeupdate 時に currentTime で判断する\r
* 3. WP7(IS12T) で最後の方にある音が鳴らない? mp3 cbr を使えばいい? 裏に回っても音が鳴り続ける\r
- * 4. Android 3.x で ended に達すると音が鳴らなくなる -> リロード(audio.src='';audio.sr=src)で解決\r
+ * 4. Android 3.x で ended に達すると音が鳴らなくなる -> リロード(audio.src='';audio.sr=src)で解決、但し 2.x 4.x より遅延が大きく 1 秒弱程度ある\r
* 5. Android 2.x で ended に達すると音が鳴らなくなる -> リロード(audio.src='';audio.src=src;audio.load())でで解決\r
- * 6. Android 4.4.2- は ended に達した際に currentTime が変更できなくなり、リロードが必要になる\r
+ * 6. Android 4.4.2- は ended に達した際に currentTime が変更できなくなり、リロードが必要になる, 4.0, 4.1, 4.2, 4.3 で確認\r
+ * 7. Blink5 Opera32 Win8 は HTMLAudio が壊れている、WebAudio は mp3 がデコードに失敗、ogg が動作\r
+ * \r
+ * memo\r
+ * 1. Android4.1 iframe 内の Audio は親に focus が移っても再生を継続する\r
*/\r
\r
var X_HTMLAudio_playTrigger =\r
6 <= X_UA[ 'iOS' ] ? 'loadeddata' :\r
X_UA[ 'iOS' ] < 5 ? 'stalled' :\r
- X_UA[ 'iOS' ] ? 'suspend' :\r
+ X_UA[ 'iOS' ] ? 'suspend' :\r
X_UA[ 'Safari' ] < 4 ? 'canplaythrough' :\r
- X_UA[ 'AndroidChromeBrowser' ] ? 'canplaythrough' :\r
+ X_UA[ 'ChromeWK' ] ? 'canplaythrough' :\r
// Android 2.3.5(SBM101SH) では stalled は発生しない,,, ので必ず loadeddata もチェックする\r
- X_UA[ 'AndroidBrowser' ] ? 'stalled' :\r
+ X_UA[ 'AOSP' ] ? 'stalled' :\r
X_UA[ 'OperaMobile' ] || X_UA[ 'OperaTablet' ] ? 'loadeddata' :\r
'loadeddata', //'canplay',\r
X_HTMLAudio,\r
- X_Audio_constructor = X_UA[ 'Safari' ] < 4 ? function(a){ a = document.createElement( 'audio' ); return a; } : window[ 'Audio' ] || window.HTMLAudioElement,\r
\r
// ended が発生しない timeupdate 内で play() を呼ぶ (未検証) 不具合確認は iOS4,6\r
X_HTMLAudio_endedFixIOS = X_UA[ 'iOS' ] < 7,\r
// Android 2.3.5 で ended 時に audio.src='';audio.src=src;audio.load() を実施。 2.3.4 でも問題なし。\r
- X_HTMLAudio_endedFixAOSP2 = X_UA[ 'AndroidBrowser' ] < 3,\r
+ X_HTMLAudio_endedFixAOSP2 = X_UA[ 'AOSP' ] < 3,\r
// Android 3.1 で ended 時に src='';src=src を実施。\r
- X_HTMLAudio_endedFixAOSP3 = !X_HTMLAudio_endedFixAOSP2 && X_UA[ 'AndroidBrowser' ] < 4,\r
+ X_HTMLAudio_endedFixAOSP3 = !X_HTMLAudio_endedFixAOSP2 && X_UA[ 'AOSP' ] < 4,\r
// ended 時に play() を実施, currentTime が duration に張り付き更新されなければ src='';src=src を実施。\r
- X_HTMLAudio_endedFixAOSP4 = !X_UA[ 'AndroidChromeBrowser' ] && 4 <= X_UA[ 'AndroidBrowser' ],\r
+ X_HTMLAudio_endedFixAOSP4 = 4 <= X_UA[ 'AOSP' ],\r
\r
// Opera Mobile 12 は 2回目以降の currentTime へのセットで currentTime が更新されなくなるため、タイマーを使用する\r
X_HTMLAudio_currentTimeFix = !!X_UA[ 'OperaMobile' ] || !!X_UA[ 'OperaTablet' ],\r
- // Android1.6+MobileOpera12では無理っぽい、、、\r
- X_HTMLAudio_badOperaAndroid = X_HTMLAudio_currentTimeFix && X_UA[ 'Android' ] < 2,\r
\r
X_HTMLAudio_volumeFix = X_UA[ 'Chrome' ],\r
/*\r
X_HTMLAudio_pauseFix = ( X_UA[ 'Windows' ] && 12 <= X_UA[ 'Opera' ] && 0 < ' XP XPSP2 2003|XP64'.indexOf( X_UA[ 'Windows' ] ) ), // XP + Opera12 のみ?\r
/*\r
* durationFix\r
- * duration が取得できるタイミングが遅くそれまでは infinity(PC Opera12), NaN(WP9), 0(AndroidBrowser Chrome 系) が入っている\r
+ * duration が取得できるタイミングが遅くそれまでは infinity(PC Opera12), NaN(WP9), 0(AOSP Chrome 系) が入っている\r
* \r
* 1. touch が不要の場合、自動で再生を開始して duration を取得するまで再生する\r
* -> 取得後に pause or 通常再生\r
* -> その際には timeupdate が発行されない、、、 iframe+image+audio で使わないときは破棄する、とか。\r
* -> opera11、10.54 WinXP はまとも、、、 portable が怪しい??\r
*/\r
- X_HTMLAudio_need1stTouch = X_UA[ 'iOS' ] || X_UA[ 'AndroidChromeBrowser' ] || ( X_UA[ 'WinPhone' ] && X_UA[ 'IE9' ] ), \r
- X_HTMLAudio_durationFix = ( X_UA[ 'Windows' ] && 12 <= X_UA[ 'Opera' ] ) || X_UA[ 'AndroidChromeBrowser' ] || ( X_UA[ 'WinPhone' ] && X_UA[ 'IE9' ] ),\r
+ X_HTMLAudio_need1stTouch = X_UA[ 'iOS' ] || X_UA[ 'ChromeWK' ] || ( X_UA[ 'WinPhone' ] && X_UA[ 'IE9' ] ), \r
+ X_HTMLAudio_durationFix = ( X_UA[ 'Windows' ] && 12 <= X_UA[ 'Opera' ] ) || X_UA[ 'ChromeWK' ] || ( X_UA[ 'WinPhone' ] && X_UA[ 'IE9' ] ),\r
\r
- X_HTMLAudio_shortPlayFix = !X_UA[ 'AndroidChromeBrowser' ] && X_UA[ 'AndroidBrowser' ], // Android 4.1.1 でも遭遇(ただしm4a, mp3は優秀, oggはシークが乱れる)\r
+ X_HTMLAudio_shortPlayFix = X_UA[ 'AOSP' ]; // Android 4.1.1 でも遭遇(ただしm4a, mp3は優秀, oggはシークが乱れる)\r
\r
- X_Audio_codecs;\r
-\r
-if( X_Audio_constructor && !X_HTMLAudio_badOperaAndroid ){\r
- //http://himaxoff.blog111.fc2.com/blog-entry-97.html\r
- //引数なしで new Audio() とすると、Operaでエラーになるそうなので注意。\r
- X_TEMP.rawAudio = new X_Audio_constructor( '' );\r
\r
- // https://html5experts.jp/miyuki-baba/3766/\r
- // TODO Chrome for Android31 で HE-AAC が低速再生されるバグ\r
- // TODO Android4 標準ブラウザで ogg のシークが正しくない!\r
- if( X_TEMP.rawAudio.canPlayType ){\r
- X_Audio_codecs = {\r
- 'mp3' : X_TEMP.rawAudio.canPlayType('audio/mpeg'),\r
- 'opus' : X_TEMP.rawAudio.canPlayType('audio/ogg; codecs="opus"'),\r
- 'ogg' : X_TEMP.rawAudio.canPlayType('audio/ogg; codecs="vorbis"'),\r
- 'wav' : X_TEMP.rawAudio.canPlayType('audio/wav; codecs="1"'),\r
- 'aac' : X_TEMP.rawAudio.canPlayType('audio/aac'),\r
- 'm4a' : X_TEMP.rawAudio.canPlayType('audio/x-m4a') + X_TEMP.rawAudio.canPlayType('audio/m4a') + X_TEMP.rawAudio.canPlayType('audio/aac'),\r
- 'mp4' : X_TEMP.rawAudio.canPlayType('audio/x-mp4') + X_TEMP.rawAudio.canPlayType('audio/mp4') + X_TEMP.rawAudio.canPlayType('audio/aac'),\r
- 'weba' : X_TEMP.rawAudio.canPlayType('audio/webm; codecs="vorbis"')\r
- };\r
- (function( X_Audio_codecs, k, v ){\r
- for( k in X_Audio_codecs ){\r
- //if( X_EMPTY_OBJECT[ k ] ) continue;\r
- v = X_Audio_codecs[ k ];\r
- v = v && !!( v.split( 'no' ).join( '' ) );\r
- if( v ){\r
- console.log( k + ' ' + X_Audio_codecs[ k ] );\r
- X_Audio_codecs[ k ] = true;\r
- } else {\r
- delete X_Audio_codecs[ k ];\r
- };\r
- };\r
- })( X_Audio_codecs );\r
- } else {\r
- // iOS3.2.3\r
- X_Audio_codecs = {\r
- 'mp3' : X_UA[ 'IE' ] || X_UA[ 'Chrome' ] || ( X_UA[ 'Windows' ] && X_UA[ 'Safari' ] ),\r
- 'ogg' : 5 <= X_UA[ 'Gecko' ] || X_UA[ 'Chrome' ] || X_UA[ 'Opera' ] ,\r
- 'wav' : X_UA[ 'Gecko' ] || X_UA[ 'Opera' ] || ( X_UA[ 'Windows' ] && X_UA[ 'Safari' ] ),\r
- 'aac' : X_UA[ 'IE' ] || X_UA[ 'WebKit' ],\r
- 'm4a' : X_UA[ 'IE' ] || X_UA[ 'WebKit' ],\r
- 'mp4' : X_UA[ 'IE' ] || X_UA[ 'WebKit' ],\r
- 'weba' : 2 <= X_UA[ 'Gecko' ] || 10.6 <= X_UA[ 'Opera' ] // firefox4+(Gecko2+)\r
- };\r
- (function( X_Audio_codecs, k ){\r
- for( k in X_Audio_codecs ){\r
- //if( X_EMPTY_OBJECT[ k ] ) continue;\r
- if( X_Audio_codecs[ k ] ){\r
- console.log( k + ' ' + X_Audio_codecs[ k ] );\r
- X_Audio_codecs[ k ] = true;\r
- } else {\r
- delete X_Audio_codecs[ k ];\r
- };\r
- };\r
- })( X_Audio_codecs );\r
- };\r
+\r
+if( X_Audio_constructor ){\r
\r
- X_HTMLAudio = X_Audio_AbstractAudioBackend[ 'inherits' ](\r
- 'X.AV.HTML5AudioWrapper',\r
+ X_HTMLAudio = X_AudioBase[ 'inherits' ](\r
+ 'X.HTMLAudio',\r
X_Class.POOL_OBJECT,\r
{\r
_closed : true,\r
_durationFixSkip : X_HTMLAudio_durationFix && !X_HTMLAudio_need1stTouch, \r
_lastCurrentTime : 0,\r
\r
-\r
_shortPlayFixON : false,\r
_shortPlayFixTime : 0,\r
\r
\r
if( X_TEMP.rawAudio ){\r
raw.src = source;\r
- raw.load(); // 要る?\r
- X_TEMP.rawAudio = null;\r
+ raw.load(); // AOSP2 で必要\r
+ delete X_TEMP.rawAudio;\r
};\r
},\r
\r
handleEvent : function( e ){\r
var raw = this[ '_rawObject' ],\r
- _ended = e.type === 'ended',\r
- ended = _ended,\r
- ready = e.type === X_HTMLAudio_playTrigger,\r
+ actualEnded = e.type === 'ended',\r
+ ended = actualEnded,\r
+ ready = e.type === X_HTMLAudio_playTrigger,\r
eventType, duration, end, now;\r
\r
// global に公開\r
//case 'loadstart' : // ブラウザがコンテンツの検索を開始した場合に発生\r
//break;\r
case 'progress' : // ブラウザがコンテンツの取得を実行した場合に発生\r
- console.log( e.loaded + ' ' + e.total * 100 + '%' );\r
+ // console.log( e.loaded + ' ' + e.total * 100 + '%' );\r
// iem9 で常に0 raw.networkState;\r
// opera Android 12 で buffered.end() へのアクセスはエラー try catch も無効、iem9 は常に end(0) = 0\r
//console.log( 'buffered.end ' + raw.buffered && raw.buffered.end(0) ); \r
};\r
case 'canplaythrough' : // 今すぐに再生を開始してもバッファリングで停止することなく最後まで表示できると予測している場合に発生\r
if( this._endedFixON ){\r
+ console.log( '▽ onEndedFix の終了 @' + e.type );\r
this._endedFixON = false;\r
this.actualPlay();\r
- console.log( '▽ onEndedFix @' + e.type );\r
};\r
case 'loadedmetadata' : // ブラウザがメディアリソースの長さと寸法を判定した場合に発生\r
case 'durationchange' : // duration属性が更新された場合に発生\r
this._lastCurrentTime = raw.currentTime;\r
\r
if( this.playing ){\r
- end = X_AudioWrapper_getEndTime( this ) + this._shortPlayFixTime;\r
+ end = X_Audio_getEndTime( this ) + this._shortPlayFixTime;\r
now = this.getActualCurrentTime();\r
//console.log( now + ' / ' + end );\r
if( 0 + end <= 0 + now ){ // 0+ なぜか iem9 で必要,,,\r
if( this.autoLoop ){\r
- console.log( '☆★☆ 曲の最後に到達 @timeupdate' );\r
+ console.log( '☆★☆ 曲の最後に到達 @timeupdate now-end:' + ( now - end ) );\r
ended = true;\r
- if( X_HTMLAudio_endedFixIOS ) _ended = true;\r
+ if( X_HTMLAudio_endedFixIOS ) actualEnded = true;\r
} else {\r
this.actualPause();\r
eventType = X_EVENT_MEDIA_ENDED;\r
if( !( this.target[ 'dispatch' ]( X_EVENT_MEDIA_BEFORE_LOOP ) & X_CALLBACK_PREVENT_DEFAULT ) ){\r
this.looped = true;\r
this.target[ 'dispatch' ]( X_EVENT_MEDIA_LOOPED );\r
- ( X_HTMLAudio_endedFixAOSP3 || X_HTMLAudio_endedFixAOSP4 || X_HTMLAudio_endedFixIOS ) && _ended && console.log( '☆★☆ 音声の継続用の play() @ended' );\r
- this.actualPlay( ( X_HTMLAudio_endedFixAOSP4 || X_HTMLAudio_endedFixIOS ) && _ended, ( X_HTMLAudio_endedFixAOSP3 || X_HTMLAudio_endedFixAOSP2 ) && _ended );\r
+ ( X_HTMLAudio_endedFixAOSP3 || X_HTMLAudio_endedFixAOSP4 || X_HTMLAudio_endedFixIOS ) && actualEnded && console.log( '☆★☆ 音声の継続用の play() @ended' );\r
+ this.actualPlay(\r
+ ( X_HTMLAudio_endedFixAOSP4 || X_HTMLAudio_endedFixIOS ) && actualEnded,\r
+ ( X_HTMLAudio_endedFixAOSP3 || X_HTMLAudio_endedFixAOSP2 ) && actualEnded );\r
};\r
- // Android4.1.1 ended 後に曲の再生が継続できない\r
} else {\r
this.seekTime = 0;\r
delete this.playing;\r
- this.target[ 'dispatch' ]( X_EVENT_MEDIA_ENDED ); \r
+ this.target[ 'dispatch' ]( X_EVENT_MEDIA_ENDED );\r
};\r
} else\r
if( this._loaded && this.duration && !this._ready ){\r
this._durationFixPhase = 2;\r
};\r
\r
- end = X_AudioWrapper_getEndTime( this );\r
- begin = X_AudioWrapper_getStartTime( this, end, true );\r
+ end = X_Audio_getEndTime( this );\r
+ begin = X_Audio_getStartTime( this, end, true );\r
\r
this._lastCurrentTime = begin / 1000;\r
\r
\r
// Android4.0.5 で ended イベント時に currentTime が duration に張り付いたまま変更できない\r
if( forceReload || ( raw.duration && raw.currentTime === raw.duration ) ){\r
- console.log( '△ onEndedFix の開始' );\r
raw.src = '';\r
raw.src = this._src;\r
- raw.currentTime = this._lastCurrentTime;\r
this.playing = false;\r
this._endedFixON = true;\r
+ console.log( '△ onEndedFix の開始' );\r
+ raw.currentTime = this._lastCurrentTime;\r
this.target[ 'dispatch' ]( X_EVENT_MEDIA_WAITING ); \r
X_HTMLAudio_endedFixAOSP2 && raw.load();\r
}; \r
};\r
\r
- /* if( X_HTMLAudio_durationFix ){\r
- this._currentFixBegin = begin;\r
- } else */\r
if( X_HTMLAudio_currentTimeFix ){\r
this._currentFixBegin = begin;\r
this._currentFixStart = X_Timer_now();\r
}\r
);\r
\r
- X_Audio_BACKENDS.push(\r
+ X_HTMLAudio && X_Audio_BACKENDS.push(\r
{\r
- backendName : 'HTML Audio',\r
+ backendID : 2,\r
+ \r
+ backendName : 'HTMLAudio',\r
\r
canPlay : X_Audio_codecs,\r
/*\r