diff --git a/vocodes/package-lock.json b/vocodes/package-lock.json index 03b026e756..6e121096ce 100644 --- a/vocodes/package-lock.json +++ b/vocodes/package-lock.json @@ -1697,6 +1697,12 @@ "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" }, + "@types/debounce": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/debounce/-/debounce-1.2.0.tgz", + "integrity": "sha512-bWG5wapaWgbss9E238T0R6bfo5Fh3OkeoSt245CM7JJwVwpw6MEBCbIxLq5z8KzsE3uJhzcIuQkyiZmzV3M/Dw==", + "dev": true + }, "@types/eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", @@ -1925,6 +1931,15 @@ "integrity": "sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ==", "dev": true }, + "@types/wavesurfer.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@types/wavesurfer.js/-/wavesurfer.js-5.2.0.tgz", + "integrity": "sha512-K9wnw6D9yDRdazRbYdQnWZ1W6z+1eHiinW2vFO/UWKX86TuOwAbNmmt+S79jbzKizA24ufI9NuqJcav6cKE4XA==", + "dev": true, + "requires": { + "@types/debounce": "*" + } + }, "@types/yargs": { "version": "13.0.9", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.9.tgz", @@ -13865,6 +13880,11 @@ } } }, + "wavesurfer.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/wavesurfer.js/-/wavesurfer.js-5.2.0.tgz", + "integrity": "sha512-SkPlTXfvKy+ZnEA7f7g7jn6iQg5/8mAvWpVV5vRbIS/FF9TB2ak9J7VayQfzfshOLW/CqccTiN6DDR/fZA902g==" + }, "wbuf": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", diff --git a/vocodes/package.json b/vocodes/package.json index e9361e1af1..b9c0091652 100644 --- a/vocodes/package.json +++ b/vocodes/package.json @@ -28,7 +28,8 @@ "react-router-dom": "^5.2.0", "react-scripts": "3.4.1", "typescript": "^3.7.5", - "uuid": "^8.3.2" + "uuid": "^8.3.2", + "wavesurfer.js": "^5.2.0" }, "scripts": { "start": "BROWSER=none react-scripts start", @@ -56,6 +57,7 @@ }, "devDependencies": { "@types/react-router-dom": "^5.1.7", - "@types/uuid": "^8.3.0" + "@types/uuid": "^8.3.0", + "@types/wavesurfer.js": "^5.2.0" } } diff --git a/vocodes/src/v2/view/tts/tts_result_view/TtsResultAudioPlayerFc.tsx b/vocodes/src/v2/view/tts/tts_result_view/TtsResultAudioPlayerFc.tsx index 3840733c0e..328cbc215f 100644 --- a/vocodes/src/v2/view/tts/tts_result_view/TtsResultAudioPlayerFc.tsx +++ b/vocodes/src/v2/view/tts/tts_result_view/TtsResultAudioPlayerFc.tsx @@ -1,9 +1,43 @@ +import React from 'react'; +import WaveSurfer from 'wavesurfer.js'; +import { useEffect, useState } from 'react'; +import { BucketConfig } from '../../../../common/BucketConfig'; +import { TtsResult } from '../../../api/tts/GetTtsResult'; interface Props { + ttsResult: TtsResult, } function TtsResultAudioPlayerFc(props: Props) { + let [isPlaying, setIsPlaying] = useState(false); + let [waveSurfer, setWaveSurfer] = useState(null); + useEffect(() => { + setWaveSurfer(WaveSurfer.create({ + container: '#waveform' + })) + }, []) + + useEffect(() => { + const audioLink = new BucketConfig().getGcsUrl(props.ttsResult?.public_bucket_wav_audio_path); + if(waveSurfer) { + waveSurfer.load(audioLink) + } + }, [waveSurfer, props.ttsResult]) + + const togglePlayPause = () => { + if (waveSurfer) { + waveSurfer.playPause() + setIsPlaying(!isPlaying) + } + } + + return ( +
+
+ +
+ ) } export { TtsResultAudioPlayerFc } diff --git a/vocodes/src/v2/view/tts/tts_result_view/TtsResultViewFc.tsx b/vocodes/src/v2/view/tts/tts_result_view/TtsResultViewFc.tsx index 280832ae65..f2851161e5 100644 --- a/vocodes/src/v2/view/tts/tts_result_view/TtsResultViewFc.tsx +++ b/vocodes/src/v2/view/tts/tts_result_view/TtsResultViewFc.tsx @@ -9,6 +9,7 @@ import { FrontendUrlConfig } from '../../../../common/FrontendUrlConfig'; import { HiddenIconFc } from '../../_icons/HiddenIcon'; import { VisibleIconFc } from '../../_icons/VisibleIcon'; import { GetTtsResult, TtsResult } from '../../../api/tts/GetTtsResult'; +import { TtsResultAudioPlayerFc } from './TtsResultAudioPlayerFc'; interface Props { sessionWrapper: SessionWrapper, @@ -174,6 +175,10 @@ function TtsResultViewFc(props: Props) {

{headingTitle}

{subtitle} + + +
+