Skip to content

Commit

Permalink
allow customizing how audio is played by passing in an optional custo…
Browse files Browse the repository at this point in the history
…m sound hook
  • Loading branch information
Florian Gyger committed Apr 6, 2020
1 parent 8fad241 commit d2cee5c
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 18 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ You can replace the whole speech output handling by using your own React compone

If you choose to use your own component, make sure it uses the `SpeechOutputProps` exported from this plugin.

### Custom `useSound` hook

In case you would like to manage playing sounds by yourself you can pass an optional hook to the `useCustomSoundHook` prop of the `SpeechOutput` component. It has to follow the `UseSoundHookSignature` type as exported from `UseSound.ts` (which is the default sound hook).

## Event listeners

To be able to react to certain events you can register the following event listeners:
Expand Down
24 changes: 6 additions & 18 deletions src/SpeechOutput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as React from "react";
import isomorphicFetch from "isomorphic-fetch";
import useSpeechMarks, { SpeechMark } from "./internals/hooks/UseSpeechMarks";
import WordMarker from "./internals/components/WordMarker";
import useSound, { UseSoundHookSignature } from "./internals/hooks/UseSound";

export interface PlayButtonProps {
isPlaying: boolean;
Expand All @@ -16,16 +17,16 @@ export interface SpeechOutputProps {
id: string;
customPlayButton?: React.FunctionComponent<PlayButtonProps>;
onWordMarked?: (word: string) => void;
useCustomSoundHook?: UseSoundHookSignature;
}

const SpeechOutput: React.FunctionComponent<SpeechOutputProps> = props => {
const [isPlaying, setPlaying] = React.useState<boolean>(false);
const useSoundHook: UseSoundHookSignature =
props.useCustomSoundHook || useSound;
const [isPlaying, setPlaying] = useSoundHook(`/tts/${props.id}.mp3`);
const [speechMarks, setSpeechmarks] = React.useState<SpeechMark[]>([]);
const soundFileHandle = React.useRef<HTMLAudioElement>();

React.useEffect(() => {
soundFileHandle.current = new Audio(`/tts/${props.id}.mp3`);
soundFileHandle.current.addEventListener("ended", () => setPlaying(false));
const fetchSpeechMarks = async () => {
const response: any = await isomorphicFetch(`/tts/${props.id}.json`);
const speechMarksJson: any = await response.json();
Expand All @@ -41,20 +42,7 @@ const SpeechOutput: React.FunctionComponent<SpeechOutputProps> = props => {
[currentWord, props.onWordMarked]
);

const onPlayStopButtonClicked = () => {
if (isPlaying) {
setPlaying(false);
if (soundFileHandle.current) {
soundFileHandle.current.pause();
soundFileHandle.current.currentTime = 0;
}
} else {
setPlaying(true);
if (soundFileHandle.current) {
soundFileHandle.current.play();
}
}
};
const onPlayStopButtonClicked = () => setPlaying(!isPlaying);

const PlayButton = props.customPlayButton || DefaultPlayButton;

Expand Down
31 changes: 31 additions & 0 deletions src/internals/hooks/UseSound.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as React from "react";

export type UseSoundHookSignature = (
soundFilePath: string
) => [boolean, React.Dispatch<React.SetStateAction<boolean>>];

const useSound: UseSoundHookSignature = (soundFilePath: string) => {
const [isPlaying, setPlaying] = React.useState<boolean>(false);
const soundFileHandle = React.useRef<HTMLAudioElement>();

React.useEffect(() => {
soundFileHandle.current = new Audio(soundFilePath);
soundFileHandle.current.addEventListener("ended", () => setPlaying(false));
}, [soundFilePath]);

React.useEffect(() => {
if (!soundFileHandle.current) {
return;
}
if (isPlaying) {
soundFileHandle.current.play();
} else {
soundFileHandle.current.pause();
soundFileHandle.current.currentTime = 0;
}
}, [isPlaying]);

return [isPlaying, setPlaying];
};

export default useSound;

0 comments on commit d2cee5c

Please sign in to comment.