1010 */
1111
1212import * as VRAudioBufferManager from './VRAudioBufferManager' ;
13+ import MediaError from './MediaError' ;
1314
1415import type VRAudioContext from './VRAudioContext' ;
1516
17+ type MediaEventType =
18+ | 'canplay'
19+ | 'ended'
20+ | 'durationchange'
21+ | 'timeupdate'
22+ | 'pause'
23+ | 'playing'
24+ | 'error' ;
25+
1626export type MediaEvent = {
17- type : 'canplay' | 'ended' ,
27+ type : MediaEventType ,
1828 timeStamp : number ,
1929 target : any ,
2030} ;
@@ -31,12 +41,16 @@ export default class VRAudioBufferSource {
3141 _playbackTime : number ;
3242 _startTime : number ;
3343 _isPlaying : boolean ;
44+ _error : ?MediaError ;
45+ _ended : boolean ;
3446
3547 constructor ( vrAudioContext : VRAudioContext ) {
3648 this . _vrAudioContext = vrAudioContext ;
3749 this . _playbackTime = 0 ;
3850 this . _startTime = 0 ;
3951 this . _isPlaying = false ;
52+ this . _error = null ;
53+ this . _ended = false ;
4054 this . onMediaEvent = undefined ;
4155 }
4256
@@ -49,23 +63,42 @@ export default class VRAudioBufferSource {
4963 this . stopSourceNode ( ) ;
5064 this . _playbackTime = 0 ;
5165 this . _buffer = null ;
66+ this . _error = null ;
67+ this . _ended = false ;
5268
5369 this . url = url ;
54- VRAudioBufferManager . fetch ( url , this . _vrAudioContext , ( buffer : ? AudioBuffer , error ) => {
55- if ( error ) {
56- console . warn ( 'Failed to fetch audio:' , url ) ;
57- } else {
58- this . _buffer = buffer ;
59- this . _onMediaEvent ( {
60- type : 'canplay' ,
61- timeStamp : Date . now ( ) ,
62- target : {
63- ended : false ,
64- error : null ,
65- } ,
66- } ) ;
70+ VRAudioBufferManager . fetch (
71+ url ,
72+ this . _vrAudioContext ,
73+ ( buffer : ? AudioBuffer , error : ? MediaError ) => {
74+ if ( error ) {
75+ console . warn ( 'Failed to fetch audio:' , url ) ;
76+ this . _error = error ;
77+ this . _onMediaEvent ( this . createMediaEvent ( 'error' ) ) ;
78+ } else {
79+ this . _buffer = buffer ;
80+ this . _onMediaEvent ( this . createMediaEvent ( 'canplay' ) ) ;
81+ this . _onMediaEvent ( this . createMediaEvent ( 'durationchange' ) ) ;
82+ }
6783 }
68- } ) ;
84+ ) ;
85+ }
86+
87+ createMediaEvent ( type : MediaEventType ) : MediaEvent {
88+ const duration = this . _buffer ? this . _buffer . duration : 0 ;
89+ const currentTime = this . _isPlaying
90+ ? this . _vrAudioContext . getWebAudioContext ( ) . currentTime - this . _startTime + this . _playbackTime
91+ : this . _playbackTime ;
92+ return {
93+ type : type ,
94+ timeStamp : Date . now ( ) ,
95+ target : {
96+ currentTime : currentTime ,
97+ duration : duration ,
98+ ended : this . _ended ,
99+ error : this . _error ,
100+ } ,
101+ } ;
69102 }
70103
71104 getSourceNode ( ) {
@@ -81,6 +114,7 @@ export default class VRAudioBufferSource {
81114 play ( ) {
82115 if ( this . _isPlaying ) return ;
83116 this . playSourceNode ( ) ;
117+ this . _onMediaEvent ( this . createMediaEvent ( 'playing' ) ) ;
84118 }
85119
86120 playSourceNode ( ) {
@@ -91,21 +125,16 @@ export default class VRAudioBufferSource {
91125 sourceNode . onended = ( ) => {
92126 this . stopSourceNode ( ) ;
93127 this . _playbackTime = 0 ;
94- this . _onMediaEvent ( {
95- type : 'ended' ,
96- timeStamp : Date . now ( ) ,
97- target : {
98- ended : true ,
99- error : null ,
100- } ,
101- } ) ;
128+ this . _ended = true ;
129+ this . _onMediaEvent ( this . createMediaEvent ( 'ended' ) ) ;
102130 } ;
103131 if ( ! this . _buffer ) {
104132 console . warn ( 'play() called before audio loaded for url' , this . url ) ;
105133 return ;
106134 }
107135 sourceNode . buffer = this . _buffer ;
108136 sourceNode . start ( 0 , this . _playbackTime ) ;
137+ this . _ended = false ;
109138 this . _isPlaying = true ;
110139 this . _startTime = this . _vrAudioContext . getWebAudioContext ( ) . currentTime ;
111140 }
@@ -138,13 +167,16 @@ export default class VRAudioBufferSource {
138167 this . _playbackTime = this . _vrAudioContext . getWebAudioContext ( ) . currentTime -
139168 this . _startTime +
140169 this . _playbackTime ;
170+ this . _onMediaEvent ( this . createMediaEvent ( 'pause' ) ) ;
141171 }
142172
143173 stop ( ) {
144174 if ( ! this . _isPlaying ) return ;
145175
146176 this . stopSourceNode ( ) ;
147177 this . _playbackTime = 0 ;
178+ this . _ended = true ;
179+ this . _onMediaEvent ( this . createMediaEvent ( 'ended' ) ) ;
148180 }
149181
150182 stopSourceNode ( ) {
@@ -157,6 +189,12 @@ export default class VRAudioBufferSource {
157189 this . _isPlaying = false ;
158190 }
159191
192+ frame ( ) {
193+ if ( this . _isPlaying ) {
194+ this . _onMediaEvent ( this . createMediaEvent ( 'timeupdate' ) ) ;
195+ }
196+ }
197+
160198 dispose ( ) {
161199 this . stopSourceNode ( ) ;
162200 if ( this . url && this . _buffer ) {
0 commit comments