UNPKG

talkr-tts

Version:

Wraps speechSynthesis calls for applications that want to animate to the voice

170 lines (145 loc) 3.52 kB
import Clip from './clip.js'; import Base from './base.js'; import EventEmitter from 'events'; export default class Scene extends Base { constructor(clipIDs, id) { super('scene', id); if (clipIDs === undefined) { clipIDs = []; } if (Array.isArray(clipIDs)) { clipIDs.forEach((id) => { if (typeof (id) !== 'string') { throw Error('Invalid clip id.'); } }); } else { throw Error('clipIDs were not an array.'); } this._clips = clipIDs; this._stopped = true; this._name = null; } get clipIDs() { return this._clips; } deleteClip(id) { var i = this._clips.indexOf(id); if (i > -1) { let clip = Clip.getByID(id); this._clips.splice(i, 1); if (clip) { clip.delete(); } } } addClip(id) { var clip = Clip.getByID(id); if (clip) { this._clips.push(id); clip.sceneid = this._id; } } get name() { return this._name; } set name(name) { this._name = name; } get text() { var text = ''; this._clips.forEach((clipid)=> { let clip = Clip.getByID(clipid); if (!clip) { throw new Error('Invalid clip ID.'); } text += clip.text + ' '; }); return text.trim(); } get clips() { var clips = []; this._clips.forEach((clipid)=> { let clip = Clip.getByID(clipid); if (!clip) { throw new Error('Invalid clip ID.'); } clips.push(clip); }); return clips; } delete() { this._clips.forEach((clipid)=> { delete Base.objects['clip'][clipid]; }); super.delete(); } playClips(startIndex) { Scene.playing = this; if (startIndex === undefined) { startIndex = 0; } let numclips = this._clips.length; this._stopped = false; if (numclips <= startIndex) { return; } let onPlayUtteranceWithDur = (dur, face) => { Scene.eventEmitter.emit('utterancestart', {'duration': dur, 'face': face}); }; let that = this; let onPlayNextClip = null; let playClipAtIndex = (clipIndex) => { if (this._stopped) { return; } let clip = Clip.getByID(that.clipIDs[clipIndex]); if (clip) { Scene.eventEmitter.emit('clipstart', clip); clip.playUtterances(onPlayUtteranceWithDur, onPlayNextClip); } else { throw new Error('unknown clip ID: ' + that.clipIDs[clipIndex]); } }; let clipIndex = startIndex; onPlayNextClip = () => { if (clipIndex === numclips - 1) { Scene.eventEmitter.emit('scenefinished'); Scene.playing = null; return; } Scene.eventEmitter.emit('clipfinished', clipIndex); clipIndex += 1; playClipAtIndex(clipIndex); }; playClipAtIndex(startIndex); } static stop() { if (Scene.playing) { Scene.playing._stopped = true; } Scene.playing = null; Clip.stop(); } static fromTextAndFace(text, face) { let newClip = new Clip(text, face); return new Scene([newClip.id]); } static getByID(id) { return Base.getByTypeAndID('scene', id); } static fromJSON(json) { if (json['_clips'] && json['_id']) { let scene = new Scene(json['_clips'], json['_id']); let name = json['_name']; if (name) { scene.name = name; } return scene; } return null; } } Scene.playing = null; Scene.eventEmitter = new EventEmitter(); Base.objects['scene'] = {};