Player.onstop is invoked when the buffer has stopped

fixes #519
This commit is contained in:
Yotam Mann 2019-08-09 23:07:09 -04:00
parent b94be3cdc4
commit d507188149
2 changed files with 66 additions and 0 deletions

View file

@ -51,6 +51,51 @@ describe("Player", () => {
});
});
context.only("onstop", () => {
it ("invokes the onstop method when the player is explicitly stopped", () => {
let wasInvoked = false;
return Offline(() => {
const player = new Player({
onstop: () => {
wasInvoked = true;
},
url: buffer,
});
player.start(0).stop(0.1);
}, 0.2).then(() => {
expect(wasInvoked).to.equal(true);
});
});
it ("invokes the onstop method when the file is naturally over", () => {
let wasInvoked = false;
return Offline(() => {
const player = new Player(buffer);
player.start(0);
player.onstop = () => {
wasInvoked = true;
expect(player.state).to.equal("stopped");
};
}, buffer.duration * 1.1).then(() => {
expect(wasInvoked).to.equal(true);
});
});
it ("invokes the onstop method on restart", () => {
let wasInvoked = 0;
return Offline(() => {
const player = new Player(buffer);
player.start(0).restart(0.1).stop(0.2);
player.onstop = () => {
wasInvoked++;
};
}, 0.3).then(() => {
expect(wasInvoked).to.equal(2);
});
});
});
context("Loading", () => {
it("loads a url which was passed in", (done) => {
@ -93,6 +138,13 @@ describe("Player", () => {
context("Reverse", () => {
it ("can get/set reverse", () => {
const player = new Player();
player.reverse = true;
expect(player.reverse).to.equal(true);
player.dispose();
});
it("can be played in reverse", () => {
const audioBuffer = (buffer.get() as AudioBuffer).getChannelData(0);
const jump = 441;

View file

@ -6,6 +6,8 @@ import { isUndef } from "../../core/util/TypeCheck";
import { Source, SourceOptions } from "../Source";
import { ToneBufferSource } from "./BufferSource";
type onStopCallback = (source: Source<any>) => void;
interface PlayerOptions extends SourceOptions {
onload: () => void;
playbackRate: Positive;
@ -17,6 +19,7 @@ interface PlayerOptions extends SourceOptions {
fadeIn: Time;
fadeOut: Time;
url?: ToneAudioBuffer | string | AudioBuffer;
onstop: onStopCallback;
}
/**
@ -86,6 +89,11 @@ export class Player extends Source<PlayerOptions> {
*/
fadeOut: Time;
/**
* The callback to invoke when the source is stopped.
*/
onstop: onStopCallback = noOp;
constructor(options?: Partial<PlayerOptions>);
constructor(url?: string | AudioBuffer | ToneAudioBuffer, onload?: () => void);
constructor() {
@ -105,6 +113,7 @@ export class Player extends Source<PlayerOptions> {
this._playbackRate = options.playbackRate;
this.fadeIn = options.fadeIn;
this.fadeOut = options.fadeOut;
this.onstop = options.onstop;
}
static getDefaults(): PlayerOptions {
@ -116,6 +125,7 @@ export class Player extends Source<PlayerOptions> {
loopEnd : 0,
loopStart : 0,
onload : noOp,
onstop: noOp,
playbackRate : 1,
reverse : false,
});
@ -150,6 +160,10 @@ export class Player extends Source<PlayerOptions> {
* Internal callback when the buffer is done playing.
*/
private _onSourceEnd(source: ToneBufferSource): void {
// invoke the onstop function
this.onstop(this);
// delete the source from the active sources
this._activeSources.delete(source);
if (this._activeSources.size === 0 && !this._synced) {
this._state.setStateAtTime("stopped", this.now());