Skip to content
This repository has been archived by the owner on Jan 7, 2021. It is now read-only.

Commit

Permalink
Feat/streaming audio playback (#112)
Browse files Browse the repository at this point in the history
Feat/streaming audio playback
  • Loading branch information
germanattanasio authored Jun 24, 2019
2 parents bb4644a + 4092ba6 commit 23165b0
Showing 1 changed file with 32 additions and 20 deletions.
52 changes: 32 additions & 20 deletions views/demo.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ export default class Demo extends Component {
loading: false,
};

this.audioElementRef = React.createRef();

this.onTabChange = this.onTabChange.bind(this);
this.onTextChange = this.onTextChange.bind(this);
this.onSsmlChange = this.onSsmlChange.bind(this);
Expand All @@ -66,10 +68,26 @@ export default class Demo extends Component {
this.onSpeak = this.onSpeak.bind(this);
this.onResetClick = this.onResetClick.bind(this);
this.onVoiceChange = this.onVoiceChange.bind(this);
this.onAudioLoaded = this.onAudioLoaded.bind(this);
this.setupParamsFromState = this.setupParamsFromState.bind(this);
this.downloadDisabled = this.downloadDisabled.bind(this);
this.speakDisabled = this.speakDisabled.bind(this);
this.downloadAllowed = this.downloadAllowed.bind(this);
this.handleAudioError = this.handleAudioError.bind(this);
}

componentDidMount() {
if (this.audioElementRef.current) {
this.audioElementRef.current.addEventListener('play', this.onAudioLoaded);
this.audioElementRef.current.addEventListener('error', this.handleAudioError);
}
}

componentWillUnmount() {
if (this.audioElementRef.current) {
this.audioElementRef.current.removeEventListener('play', this.onAudioLoaded);
this.audioElementRef.current.removeEventListener('error', this.handleAudioError);
}
}

onTabChange(idx) {
Expand All @@ -88,6 +106,10 @@ export default class Demo extends Component {
this.setState({ ssml_voice: event.target.value });
}

onAudioLoaded() {
this.setState({ loading: false, hasAudio: true });
}

onDownload(event) {
event.target.blur();
const params = this.setupParamsFromState(true);
Expand All @@ -97,28 +119,12 @@ export default class Demo extends Component {
onSpeak(event) {
event.target.blur();
const params = this.setupParamsFromState(true);
const audio = document.getElementById('audio');
audio.setAttribute('src', '');

const audio = this.audioElementRef.current;
audio.setAttribute('type', 'audio/ogg;codecs=opus');
audio.setAttribute('src', `/api/v1/synthesize?${params.toString()}`);

this.setState({ loading: true, hasAudio: false });
fetch(`/api/v1/synthesize?${params.toString()}`).then((response) => {
if (response.ok) {
response.blob().then((blob) => {
const url = window.URL.createObjectURL(blob);
this.setState({ loading: false, hasAudio: true });

audio.setAttribute('src', url);
audio.setAttribute('type', 'audio/ogg;codecs=opus');
});
} else {
this.setState({ loading: false });
response.json().then((json) => {
this.setState({ error: json });
setTimeout(() => this.setState({ error: null, loading: false }), 5000);
});
}
});
}

onResetClick() {
Expand Down Expand Up @@ -177,6 +183,12 @@ export default class Demo extends Component {
return params;
}

handleAudioError(error) {
console.error(error);
this.setState({ error: { error: 'Could not play audio' }, loading: false });
setTimeout(() => this.setState({ error: null }), 5000);
}

downloadDisabled() {
return !this.downloadAllowed();
}
Expand Down Expand Up @@ -272,7 +284,7 @@ export default class Demo extends Component {
<div className={`text-center loading ${loading ? '' : 'hidden'}`}>
<Icon type="loader" />
</div>
<audio autoPlay id="audio" className={`audio ${hasAudio ? '' : 'hidden'}`} controls="controls">
<audio ref={this.audioElementRef} autoPlay id="audio" className={`audio ${hasAudio ? '' : 'hidden'}`} controls="controls">
Your browser does not support the audio element.
</audio>
</div>
Expand Down

0 comments on commit 23165b0

Please sign in to comment.