Buckets:
| import { Object3D } from '../core/Object3D.js'; | |
| class Audio extends Object3D { | |
| constructor( listener ) { | |
| super(); | |
| this.type = 'Audio'; | |
| this.listener = listener; | |
| this.context = listener.context; | |
| this.gain = this.context.createGain(); | |
| this.gain.connect( listener.getInput() ); | |
| this.autoplay = false; | |
| this.buffer = null; | |
| this.detune = 0; | |
| this.loop = false; | |
| this.loopStart = 0; | |
| this.loopEnd = 0; | |
| this.offset = 0; | |
| this.duration = undefined; | |
| this.playbackRate = 1; | |
| this.isPlaying = false; | |
| this.hasPlaybackControl = true; | |
| this.source = null; | |
| this.sourceType = 'empty'; | |
| this._startedAt = 0; | |
| this._progress = 0; | |
| this._connected = false; | |
| this.filters = []; | |
| } | |
| getOutput() { | |
| return this.gain; | |
| } | |
| setNodeSource( audioNode ) { | |
| this.hasPlaybackControl = false; | |
| this.sourceType = 'audioNode'; | |
| this.source = audioNode; | |
| this.connect(); | |
| return this; | |
| } | |
| setMediaElementSource( mediaElement ) { | |
| this.hasPlaybackControl = false; | |
| this.sourceType = 'mediaNode'; | |
| this.source = this.context.createMediaElementSource( mediaElement ); | |
| this.connect(); | |
| return this; | |
| } | |
| setMediaStreamSource( mediaStream ) { | |
| this.hasPlaybackControl = false; | |
| this.sourceType = 'mediaStreamNode'; | |
| this.source = this.context.createMediaStreamSource( mediaStream ); | |
| this.connect(); | |
| return this; | |
| } | |
| setBuffer( audioBuffer ) { | |
| this.buffer = audioBuffer; | |
| this.sourceType = 'buffer'; | |
| if ( this.autoplay ) this.play(); | |
| return this; | |
| } | |
| play( delay = 0 ) { | |
| if ( this.isPlaying === true ) { | |
| console.warn( 'THREE.Audio: Audio is already playing.' ); | |
| return; | |
| } | |
| if ( this.hasPlaybackControl === false ) { | |
| console.warn( 'THREE.Audio: this Audio has no playback control.' ); | |
| return; | |
| } | |
| this._startedAt = this.context.currentTime + delay; | |
| const source = this.context.createBufferSource(); | |
| source.buffer = this.buffer; | |
| source.loop = this.loop; | |
| source.loopStart = this.loopStart; | |
| source.loopEnd = this.loopEnd; | |
| source.onended = this.onEnded.bind( this ); | |
| source.start( this._startedAt, this._progress + this.offset, this.duration ); | |
| this.isPlaying = true; | |
| this.source = source; | |
| this.setDetune( this.detune ); | |
| this.setPlaybackRate( this.playbackRate ); | |
| return this.connect(); | |
| } | |
| pause() { | |
| if ( this.hasPlaybackControl === false ) { | |
| console.warn( 'THREE.Audio: this Audio has no playback control.' ); | |
| return; | |
| } | |
| if ( this.isPlaying === true ) { | |
| // update current progress | |
| this._progress += Math.max( this.context.currentTime - this._startedAt, 0 ) * this.playbackRate; | |
| if ( this.loop === true ) { | |
| // ensure _progress does not exceed duration with looped audios | |
| this._progress = this._progress % ( this.duration || this.buffer.duration ); | |
| } | |
| this.source.stop(); | |
| this.source.onended = null; | |
| this.isPlaying = false; | |
| } | |
| return this; | |
| } | |
| stop() { | |
| if ( this.hasPlaybackControl === false ) { | |
| console.warn( 'THREE.Audio: this Audio has no playback control.' ); | |
| return; | |
| } | |
| this._progress = 0; | |
| if ( this.source !== null ) { | |
| this.source.stop(); | |
| this.source.onended = null; | |
| } | |
| this.isPlaying = false; | |
| return this; | |
| } | |
| connect() { | |
| if ( this.filters.length > 0 ) { | |
| this.source.connect( this.filters[ 0 ] ); | |
| for ( let i = 1, l = this.filters.length; i < l; i ++ ) { | |
| this.filters[ i - 1 ].connect( this.filters[ i ] ); | |
| } | |
| this.filters[ this.filters.length - 1 ].connect( this.getOutput() ); | |
| } else { | |
| this.source.connect( this.getOutput() ); | |
| } | |
| this._connected = true; | |
| return this; | |
| } | |
| disconnect() { | |
| if ( this._connected === false ) { | |
| return; | |
| } | |
| if ( this.filters.length > 0 ) { | |
| this.source.disconnect( this.filters[ 0 ] ); | |
| for ( let i = 1, l = this.filters.length; i < l; i ++ ) { | |
| this.filters[ i - 1 ].disconnect( this.filters[ i ] ); | |
| } | |
| this.filters[ this.filters.length - 1 ].disconnect( this.getOutput() ); | |
| } else { | |
| this.source.disconnect( this.getOutput() ); | |
| } | |
| this._connected = false; | |
| return this; | |
| } | |
| getFilters() { | |
| return this.filters; | |
| } | |
| setFilters( value ) { | |
| if ( ! value ) value = []; | |
| if ( this._connected === true ) { | |
| this.disconnect(); | |
| this.filters = value.slice(); | |
| this.connect(); | |
| } else { | |
| this.filters = value.slice(); | |
| } | |
| return this; | |
| } | |
| setDetune( value ) { | |
| this.detune = value; | |
| if ( this.source.detune === undefined ) return; // only set detune when available | |
| if ( this.isPlaying === true ) { | |
| this.source.detune.setTargetAtTime( this.detune, this.context.currentTime, 0.01 ); | |
| } | |
| return this; | |
| } | |
| getDetune() { | |
| return this.detune; | |
| } | |
| getFilter() { | |
| return this.getFilters()[ 0 ]; | |
| } | |
| setFilter( filter ) { | |
| return this.setFilters( filter ? [ filter ] : [] ); | |
| } | |
| setPlaybackRate( value ) { | |
| if ( this.hasPlaybackControl === false ) { | |
| console.warn( 'THREE.Audio: this Audio has no playback control.' ); | |
| return; | |
| } | |
| this.playbackRate = value; | |
| if ( this.isPlaying === true ) { | |
| this.source.playbackRate.setTargetAtTime( this.playbackRate, this.context.currentTime, 0.01 ); | |
| } | |
| return this; | |
| } | |
| getPlaybackRate() { | |
| return this.playbackRate; | |
| } | |
| onEnded() { | |
| this.isPlaying = false; | |
| } | |
| getLoop() { | |
| if ( this.hasPlaybackControl === false ) { | |
| console.warn( 'THREE.Audio: this Audio has no playback control.' ); | |
| return false; | |
| } | |
| return this.loop; | |
| } | |
| setLoop( value ) { | |
| if ( this.hasPlaybackControl === false ) { | |
| console.warn( 'THREE.Audio: this Audio has no playback control.' ); | |
| return; | |
| } | |
| this.loop = value; | |
| if ( this.isPlaying === true ) { | |
| this.source.loop = this.loop; | |
| } | |
| return this; | |
| } | |
| setLoopStart( value ) { | |
| this.loopStart = value; | |
| return this; | |
| } | |
| setLoopEnd( value ) { | |
| this.loopEnd = value; | |
| return this; | |
| } | |
| getVolume() { | |
| return this.gain.gain.value; | |
| } | |
| setVolume( value ) { | |
| this.gain.gain.setTargetAtTime( value, this.context.currentTime, 0.01 ); | |
| return this; | |
| } | |
| } | |
| export { Audio }; | |
Xet Storage Details
- Size:
- 6.07 kB
- Xet hash:
- c4bfc406a765e001fa0bbc838baefc1b14d302ac408731fb536c6271b6002b9a
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.