From bf11df50e93ddf374f4188a4e2631853b4af0d24 Mon Sep 17 00:00:00 2001 From: amass <168062547@qq.com> Date: Wed, 14 Jun 2023 10:17:57 +0800 Subject: [PATCH] =?UTF-8?q?1.=E5=AE=9E=E7=8E=B0=E9=A2=91=E8=B0=B1=E8=BF=9B?= =?UTF-8?q?=E5=BA=A6=E6=9D=A1=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 3 +- src/MainPage.js | 7 +- src/MainPage.module.css | 4 + src/PlayerBar.js | 118 +++++++++++++++---- src/PlayerBar.module.css | 3 + src/RecordList.js | 10 +- src/RecordLyrics.js | 16 ++- src/RecordLyrics.module.css | 2 + src/assets/download.png | Bin 0 -> 340 bytes src/assets/pause.png | Bin 0 -> 631 bytes src/assets/play.png | Bin 0 -> 668 bytes src/business/recorderSlice.js | 13 ++- src/components/Waveform.js | 159 ++++++++++++++++++++++++++ src/components/useSetTrackProgress.js | 32 ++++++ 14 files changed, 332 insertions(+), 35 deletions(-) create mode 100644 src/assets/download.png create mode 100644 src/assets/pause.png create mode 100644 src/assets/play.png create mode 100644 src/components/Waveform.js create mode 100644 src/components/useSetTrackProgress.js diff --git a/package.json b/package.json index 20830d2..8b6efaa 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "react-cookie": "^4.1.1", "react-dom": "^18.2.0", "react-redux": "^8.0.7", + "react-resize-detector": "^9.1.0", "react-router-dom": "^6.11.2", "react-scripts": "5.0.1", "sha1": "^1.1.1", @@ -48,4 +49,4 @@ "last 1 safari version" ] } -} +} \ No newline at end of file diff --git a/src/MainPage.js b/src/MainPage.js index 385c552..2be11b0 100644 --- a/src/MainPage.js +++ b/src/MainPage.js @@ -40,7 +40,7 @@ export default function () { dispatch(setList(list.result)); }); }, [accessToken, passportId]); - return
+ return
@@ -48,10 +48,11 @@ export default function () { - 2022-12-13 14:39_同传翻译 diff --git a/src/MainPage.module.css b/src/MainPage.module.css index b7bf5ff..ea01386 100644 --- a/src/MainPage.module.css +++ b/src/MainPage.module.css @@ -1,3 +1,7 @@ .title { background-color: burlywood; +} + +.mainBody { + background-color: #FAFAFA; } \ No newline at end of file diff --git a/src/PlayerBar.js b/src/PlayerBar.js index 8d6f5ce..321ea35 100644 --- a/src/PlayerBar.js +++ b/src/PlayerBar.js @@ -1,25 +1,101 @@ -import { Grid, MenuItem, Select, FormControl, InputLabel, Button } from "@mui/material" +import { MenuItem, Select, IconButton, Typography, Stack, Container } from "@mui/material" import styles from './PlayerBar.module.css'; +import { useSelector, useDispatch } from 'react-redux' +import { useEffect, useRef, useState, useCallback } from "react"; +import { useResizeDetector } from 'react-resize-detector'; +import pauseIcon from "./assets/play.png"; +import playIcon from "./assets/pause.png"; +import downloadIcon from "./assets/download.png"; +import { togglePauseState } from "./business/recorderSlice.js" +import Waveform from "./components/Waveform"; + +const durationFormat = (time) => { + if (isNaN(time)) return "00:00:00"; + time = parseInt(time); + let second = parseInt(time % 60); + let minute = parseInt((time / 60) % 60); + let hour = parseInt(time / 3600); + return hour.toString().padStart(2, '0') + ":" + minute.toString().padStart(2, '0') + ":" + second.toString().padStart(2, '0'); +} export default function () { - return - -
进度条
- - - 速度 - - - -
+ const dispatch = useDispatch(); + const [duration, setDuration] = useState("00:00:00"); + const [currentTime, setCurrentTime] = useState("00:00:00"); + const [canvasWidth, setCanvasWidth] = useState(0); + const currentIndex = useSelector(state => state.recorder.currentIndex); + const recordList = useSelector(state => state.recorder.list); + const currentBlob = useSelector(state => state.recorder.currentBlob); + const pause = useSelector(state => state.recorder.pause); + const player = useRef(null); + useEffect(() => { + player.current.url = currentBlob + console.log(player.current.url); + }, [currentBlob]); + + const toggleState = () => { + if (pause) { + player.current.play(); + } else { + player.current.pause(); + } + dispatch(togglePauseState()); + }; + + const onDurationChange = (event) => { + setDuration(durationFormat(player.current.duration)); + } + const onTimeUpdate = (event) => { + setCurrentTime(durationFormat(player.current.currentTime)); + } + + const onResize = useCallback((width, height) => { + setCanvasWidth(width - 90 - 60); + }, []); + + const { ref: playerBar } = useResizeDetector({ + onResize: onResize + }); + + return + + {recordList.length > 0 ? recordList.at(currentIndex).editName : ""} + + + + + +
+ + + + +
+ + + {currentTime} / {duration} + + +
} \ No newline at end of file diff --git a/src/PlayerBar.module.css b/src/PlayerBar.module.css index 7efc280..f69ba0a 100644 --- a/src/PlayerBar.module.css +++ b/src/PlayerBar.module.css @@ -1,3 +1,6 @@ .playerBar { display: flex; + background-color: #E6EAEC; + height: 70px; + width: 100%; } \ No newline at end of file diff --git a/src/RecordList.js b/src/RecordList.js index 147ce92..b853bb5 100644 --- a/src/RecordList.js +++ b/src/RecordList.js @@ -7,7 +7,7 @@ import ListItem from '@mui/material/ListItem'; import ListItemButton from '@mui/material/ListItemButton'; import ListItemText from '@mui/material/ListItemText'; import Toolbar from '@mui/material/Toolbar'; -import { setCurrentIndex, setCurrentLyric } from "./business/recorderSlice.js" +import { setCurrentIndex, setCurrentLyric, setCurrentBlob } from "./business/recorderSlice.js" import yzs from "./business/request.js"; const drawerWidth = 240; @@ -19,13 +19,17 @@ export default function () { const recordList = useSelector(state => state.recorder.list); const onSelected = (event, index) => { console.log("onSelected", index, recordList.at(index).transResultUrl) + dispatch(setCurrentIndex(index)); yzs.download(accessToken, recordList.at(index).transResultUrl).then( blob => blob.text() ).then(text => { console.log(text); - dispatch(setCurrentLyric(JSON.parse(text))); + let payload = recordList.at(index).type === 1 ? JSON.parse(text) : text; + dispatch(setCurrentLyric(payload)); + }); + yzs.download(accessToken, recordList.at(index).audioUrl).then(blob => { + dispatch(setCurrentBlob(URL.createObjectURL(blob))); }); - dispatch(setCurrentIndex(index)); } return state.recorder.currentLyric); + const currentIndex = useSelector(state => state.recorder.currentIndex); + const recordList = useSelector(state => state.recorder.list); - return
- {currentLyric.map((lyric, index) => { + + if (recordList.length === 0) return ; + + return + {recordList.at(currentIndex).type === 1 ? (typeof currentLyric === "object" ? currentLyric.map((lyric, index) => { return
{lyric.text} {lyric.translation}
- })} -
+ }) : ) :
{typeof currentLyric === "string" ? currentLyric : ""}
} + } \ No newline at end of file diff --git a/src/RecordLyrics.module.css b/src/RecordLyrics.module.css index 71c0761..13494e3 100644 --- a/src/RecordLyrics.module.css +++ b/src/RecordLyrics.module.css @@ -1,5 +1,7 @@ .lyricsBrowser { + margin-top: 16px; padding-bottom: 40px; + padding: 24px; } .lyricItem { diff --git a/src/assets/download.png b/src/assets/download.png new file mode 100644 index 0000000000000000000000000000000000000000..832819a46978ec5ae1843f37c675435a374685bf GIT binary patch literal 340 zcmV-a0jvIrP)Px$4oO5oR5(xVlD$d;K@^40ne8oXY-|!!`2?|%wY2gjY}|2$z^t$f{(v|^6G@S5 zYQ>jrdU&j1#H995D)P83yVa+x0cCH-nu8~XyF4WO(S0|<)zDqC9!M!kNAf!qUF z{kkZa!!ewW(kk$0sEyrlCEu<`>Fc-Z!H|+$KD5{Cw^bl3jEwytFw2M8wx1Zsr%S*x z#^Zx`U)RRo2@q17z7xp9beM%rU*zkNu``03)aLvdU<;5(K)J=RQvkbw6pRlqx=zX) maabqO_`7vcLWL*AVD}S_O>In@P&U#40000Px%F-b&0R9HvNn7@k?Q4q(!-xncQc-Uww{%905YlM?zJq`;w3%eu>ij6jU2MYcJ zR{jHm!s#_yD0h%(XQ5b#oQZg7Ob|>VD7I&FoJFp<9obDH+4bV?N>*o^W%td@`@A>r zy_tDL!Y6ma*-zu1fsttl4@0;Ylu6%=a08TYpnQVM6>-h8_S@>0Bwa9`u#?Hz;!xx& z02@F|JqUohkaya3R)OkPRDY3%^M%rBm%I(&P?WKV_Kp#`)_n8i#h>Ix0_{6>abnlz zk6VCTPB0@;%mQ$6J-hSz*Ow2v+X-(Al+QbR+zIz7fT^e+{<3}5bj{gjv$_`6{|%@Q z^J)w(iel}Uu9*o#1%P^P+VEh~nwc=<>Uwr^X4riJAgfrp3&@qIp^dkl_ganG+`#59 zp#E-pKE?$cms^a;>|poxft-w0bU*%sbu$XG(`uL_-Z|w1e8pkQa5cDu94Zg+K~jrfgBG+xFTHMs=Y>U2s*IegMi6G;fxarLeugp(@Gu zfYg;izUz8btByi(5b;%&(gP?}mkqPx%R!KxbR9HvNn9pkyK@`WoZz80J7B700YA*_!B|;^MrFbay;4R65rI((xf`a%j z2o_2OL7}bo&_hcLiM{n;tyHAll$IJ31alA+uN7;ohxE{WGMlU>v2nATjm%!>{rK$r zG4o~!F2B$v{WJ;lDg^g|=^U6&fw;>u!?X|LFChK^lh)Z3FY;TdPi|aLbHaKc6l0y3 zZv%({Xi^Uhz+j>$d4p0w>d?ubqv3EQK420(25{ENn8SKOFyF~;F0KAct|3tOm649) z2R|PHe8WXVoR}G)r^R6B-OsOQOGgPG2^0?NC(RCX89=X-2aoI9q9m?mv#H&B{l9=J zFmHTFkrQh{lth0$R1Hu$P5Tn2U6HAW+%5*Y`m57d1EfWhQvly|`Za&oX*!olkJ>hW z168_d#m53}mYW6hpxu2HAU&W(&G-MIZW=)rav5=6?o$>}D3-iV%nQx_Qaj|BXee)_ z7cC$ynpg*LxgCyN*xblvp7+s(-uM}Dj6Qm)o$>qkF!pc;d*6S!@Y_(7`B3zb7D { state.list = action.payload; }, setCurrentIndex: (state, action) => { + state.pause = true; state.currentIndex = action.payload; }, setCurrentLyric: (state, action) => { state.currentLyric = action.payload; - } + }, + setCurrentBlob: (state, action) => { + state.currentBlob = action.payload; + }, + togglePauseState: (state) => { + state.pause = !state.pause; + }, } }) // Action creators are generated for each case reducer function -export const { setCurrentIndex, setList, setCurrentLyric } = recorderSlice.actions +export const { setCurrentIndex, setList, setCurrentLyric, setCurrentBlob, togglePauseState } = recorderSlice.actions export default recorderSlice.reducer \ No newline at end of file diff --git a/src/components/Waveform.js b/src/components/Waveform.js new file mode 100644 index 0000000..4885d71 --- /dev/null +++ b/src/components/Waveform.js @@ -0,0 +1,159 @@ +import { useEffect, useRef, useState, useCallback } from "react"; +import useSetTrackProgress from "./useSetTrackProgress.js" +import { useResizeDetector } from 'react-resize-detector'; + +const pointWidth = 2; +const pointMargin = 3; + +const trackDuration = 60; //