1.整理录音内容的获取。

This commit is contained in:
amass 2023-06-16 16:01:06 +08:00
parent 1030f285dc
commit 80b494b6b1
9 changed files with 74 additions and 71 deletions

View File

@ -23,6 +23,7 @@
"react-scripts": "5.0.1", "react-scripts": "5.0.1",
"sha1": "^1.1.1", "sha1": "^1.1.1",
"sha256": "^0.2.0", "sha256": "^0.2.0",
"uuid": "^9.0.0",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
}, },
"scripts": { "scripts": {

View File

@ -1,7 +1,6 @@
import { useEffect } from 'react';
import { Routes, Route, Navigate, useNavigate } from 'react-router-dom' import { Routes, Route, Navigate, useNavigate } from 'react-router-dom'
import { useSelector, useDispatch } from 'react-redux' import { useDispatch } from 'react-redux'
import { setUdid, setAccessToken, setUserInfo, setSelectInfo } from "./business/userSlice.js" import { setAccessToken, setUserInfo, setSelectInfo } from "./business/userSlice.js"
import { useCookies } from 'react-cookie'; import { useCookies } from 'react-cookie';
import LoginPage from './LoginPage'; import LoginPage from './LoginPage';
import MainPage from './MainPage'; import MainPage from './MainPage';
@ -11,24 +10,12 @@ function App() {
const dispatch = useDispatch(); const dispatch = useDispatch();
const navigate = useNavigate(); const navigate = useNavigate();
const [cookies, setCookie, removeCookie] = useCookies(['accessToken']); const [cookies, setCookie, removeCookie] = useCookies(['accessToken']);
const udid = useSelector(state => state.user.udid)
const getIp = async () => {
const response = await fetch("https://ipapi.co/json/")
const data = await response.json()
dispatch(setUdid(data.ip));
}
// Run `getIP` function above just once when the page is rendered
useEffect(() => {
getIp()
}, [])
if (cookies.accessToken) { if (cookies.accessToken) {
dispatch(setAccessToken(cookies.accessToken)); dispatch(setAccessToken(cookies.accessToken));
yzs.get_user_info(udid, cookies.accessToken).then(info => { yzs.get_user_info(yzs.uniqueDeviceIdentifier(), cookies.accessToken).then(info => {
dispatch(setUserInfo(info)); dispatch(setUserInfo(info));
yzs.user_select(udid, cookies.accessToken).then(info => { yzs.user_select(yzs.uniqueDeviceIdentifier(), cookies.accessToken).then(info => {
dispatch(setSelectInfo(info)); dispatch(setSelectInfo(info));
}); });
}).catch(error => { }).catch(error => {

View File

@ -4,7 +4,7 @@ import Button from '@mui/material/Button';
import yzs from "./business/request.js"; import yzs from "./business/request.js";
import styles from './LoginPage.module.css'; import styles from './LoginPage.module.css';
import { useSelector, useDispatch } from 'react-redux' import { useSelector, useDispatch } from 'react-redux'
import { setUdid, setFlushToken, setAccessToken, setUserInfo } from "./business/userSlice.js" import { setFlushToken, setAccessToken, setUserInfo } from "./business/userSlice.js"
import logo from './assets/logo.png'; import logo from './assets/logo.png';
import { Container, Tab, Box } from '@mui/material'; import { Container, Tab, Box } from '@mui/material';
import TabPanel from '@mui/lab/TabPanel'; import TabPanel from '@mui/lab/TabPanel';
@ -46,30 +46,27 @@ export default function () {
const accessToken = useSelector(state => state.user.accessToken) const accessToken = useSelector(state => state.user.accessToken)
const flushToken = useSelector(state => state.user.flushToken) const flushToken = useSelector(state => state.user.flushToken)
const udid = useSelector(state => state.user.udid)
const debug_test = () => { const debug_test = () => {
console.log("accessToken", accessToken); console.log("accessToken", accessToken, yzs.uniqueDeviceIdentifier());
} }
const handleSubmit = (event) => { const handleSubmit = (event) => {
event.preventDefault(); event.preventDefault();
console.log(`account: ${account}\nPassword: ${password} udid: ${udid}`, value);
let result = null; let result = null;
if (value === "1") { if (value === "1") {
result = yzs.dynamic_code_login(udid, account, verificationCode); result = yzs.dynamic_code_login(yzs.uniqueDeviceIdentifier(), account, verificationCode);
} else if (value === "2") { } else if (value === "2") {
result = yzs.login(udid, account, password); result = yzs.login(yzs.uniqueDeviceIdentifier(), account, password);
} }
result.then(token => { result.then(token => {
dispatch(setFlushToken(token)); dispatch(setFlushToken(token));
yzs.get_access_token(udid, token).then(token => { yzs.get_access_token(yzs.uniqueDeviceIdentifier(), token).then(token => {
// yzs.update_access_token(ip.payload, token); // yzs.update_access_token(ip.payload, token);
dispatch(setAccessToken(token)); dispatch(setAccessToken(token));
setCookie("accessToken", token) setCookie("accessToken", token)
yzs.get_user_info(udid, token).then(info => { yzs.get_user_info(yzs.uniqueDeviceIdentifier(), token).then(info => {
dispatch(setUserInfo(info)); dispatch(setUserInfo(info));
yzs.user_select(udid, token).then(info => { yzs.user_select(yzs.uniqueDeviceIdentifier(), token).then(info => {
navigate("/"); navigate("/");
}) })
@ -111,7 +108,7 @@ export default function () {
</Box> </Box>
<TabPanel value="1" > <TabPanel value="1" >
<DynamicCodeForm udid={udid} /> <DynamicCodeForm udid={yzs.uniqueDeviceIdentifier()} />
</TabPanel> </TabPanel>
<TabPanel value="2" > <TabPanel value="2" >
<PasswordForm /> <PasswordForm />

View File

@ -4,9 +4,10 @@ import AppBar from './AppBar';
import RecordList from './RecordList'; import RecordList from './RecordList';
import PlayerBar from './PlayerBar'; import PlayerBar from './PlayerBar';
import styles from './MainPage.module.css'; import styles from './MainPage.module.css';
import store from './business/store';
import yzs from "./business/request.js"; import yzs from "./business/request.js";
import { setList } from "./business/recorderSlice.js" import { setList, setCurrentLyric, setCurrentBlob, setCurrentWaveData } from "./business/recorderSlice.js"
import { CssBaseline, Box, Container, Typography } from '@mui/material'; import { CssBaseline, Box } from '@mui/material';
import RecordLyrics from './RecordLyrics'; import RecordLyrics from './RecordLyrics';
import { createTheme, ThemeProvider } from '@mui/material/styles'; import { createTheme, ThemeProvider } from '@mui/material/styles';
@ -30,6 +31,35 @@ const theme = createTheme({
}); });
function fetchRecord(accessToken, record) {
yzs.download(accessToken, record.transResultUrl).then(
blob => blob.text()
).then(text => {
console.log("type", record.type, text);
let payload = record.type === 1 ? JSON.parse(text) : text;
store.dispatch(setCurrentLyric(payload));
});
yzs.download(accessToken, record.audioUrl).then(blob => {
store.dispatch(setCurrentBlob(URL.createObjectURL(blob)));
blob.arrayBuffer().then(arrayBuffer => {
let context = new (window.AudioContext || window.webkitAudioContext)();
context.decodeAudioData(arrayBuffer).then(audioBuffer => {
let interval = audioBuffer.sampleRate / 1000 * 100;
let waveData = audioBuffer.getChannelData(0);
let wave = [];
let amplitude = 0;
for (let i = 0; i < waveData.length; i++) {
amplitude += Math.abs(waveData[i]);
if (i % interval == 0) {
wave.push(Math.floor(amplitude * 500 / interval));
amplitude = 0;
}
}
store.dispatch(setCurrentWaveData(wave));
})
});
});
}
export default function () { export default function () {
const dispatch = useDispatch() const dispatch = useDispatch()
@ -39,6 +69,9 @@ export default function () {
useEffect(() => { useEffect(() => {
yzs.get_record_list(accessToken, passportId).then(list => { yzs.get_record_list(accessToken, passportId).then(list => {
dispatch(setList(list.result)); dispatch(setList(list.result));
if (list.result.length > 0) {
fetchRecord(accessToken, list.result.at(0));
}
}).catch(error => { }).catch(error => {
console.log("get list failed", error); console.log("get list failed", error);
}); });
@ -47,7 +80,7 @@ export default function () {
<ThemeProvider theme={theme}> <ThemeProvider theme={theme}>
<CssBaseline /> <CssBaseline />
<AppBar /> <AppBar />
<RecordList /> <RecordList fetchRecord={fetchRecord} />
<Box <Box
component="main" component="main"
sx={{ sx={{

View File

@ -6,13 +6,14 @@ import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem'; import ListItem from '@mui/material/ListItem';
import ListItemButton from '@mui/material/ListItemButton'; import ListItemButton from '@mui/material/ListItemButton';
import ListItemText from '@mui/material/ListItemText'; import ListItemText from '@mui/material/ListItemText';
import Typography from '@mui/material/Typography';
import Toolbar from '@mui/material/Toolbar'; import Toolbar from '@mui/material/Toolbar';
import { setCurrentIndex, setCurrentLyric, setCurrentBlob, setCurrentWaveData } from "./business/recorderSlice.js" import { setCurrentIndex } from "./business/recorderSlice.js"
import yzs from "./business/request.js"; import AccessTimeFilledIcon from '@mui/icons-material/AccessTimeFilled';
const drawerWidth = 240; const drawerWidth = 240;
export default function () { export default function ({ fetchRecord }) {
const dispatch = useDispatch(); const dispatch = useDispatch();
const accessToken = useSelector(state => state.user.accessToken); const accessToken = useSelector(state => state.user.accessToken);
const currentIndex = useSelector(state => state.recorder.currentIndex); const currentIndex = useSelector(state => state.recorder.currentIndex);
@ -20,34 +21,7 @@ export default function () {
const onSelected = (event, index) => { const onSelected = (event, index) => {
console.log("onSelected", index, recordList.at(index).transResultUrl) console.log("onSelected", index, recordList.at(index).transResultUrl)
dispatch(setCurrentIndex(index)); dispatch(setCurrentIndex(index));
yzs.download(accessToken, recordList.at(index).transResultUrl).then( fetchRecord(accessToken, recordList.at(index));
blob => blob.text()
).then(text => {
console.log("type", recordList.at(index).type, 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)));
blob.arrayBuffer().then(arrayBuffer => {
let context = new (window.AudioContext || window.webkitAudioContext)();
context.decodeAudioData(arrayBuffer).then(audioBuffer => {
let interval = audioBuffer.sampleRate / 1000 * 100;
let waveData = audioBuffer.getChannelData(0);
let wave = [];
let amplitude = 0;
for (let i = 0; i < waveData.length; i++) {
amplitude += Math.abs(waveData[i]);
if (i % interval == 0) {
wave.push(Math.floor(amplitude * 500 / interval));
amplitude = 0;
}
}
dispatch(setCurrentWaveData(wave));
})
});
});
} }
return <Drawer return <Drawer
variant="permanent" variant="permanent"
@ -57,7 +31,7 @@ export default function () {
[`& .MuiDrawer-paper`]: { width: drawerWidth, boxSizing: 'border-box' }, [`& .MuiDrawer-paper`]: { width: drawerWidth, boxSizing: 'border-box' },
}} }}
> >
<Toolbar /> <Toolbar variant="dense" />
<Box sx={{ overflow: 'auto' }}> <Box sx={{ overflow: 'auto' }}>
<List> <List>
{recordList === undefined ? <React.Fragment /> : recordList.map((item, index) => ( {recordList === undefined ? <React.Fragment /> : recordList.map((item, index) => (
@ -65,8 +39,10 @@ export default function () {
<ListItemButton selected={currentIndex === index} onClick={(event) => onSelected(event, index)}> <ListItemButton selected={currentIndex === index} onClick={(event) => onSelected(event, index)}>
<ListItemText primary={item.editName} secondary={ <ListItemText primary={item.editName} secondary={
<React.Fragment> <React.Fragment>
<div>{item.content.slice(0, 50) + '......'}</div> <Typography component="span" variant="body1">{item.content.slice(0, 50) + '......'}</Typography>
<div>更新于 {new Date(item.createTime).toLocaleString()}</div> <br />
<AccessTimeFilledIcon sx={{ fontSize: 12 }} />
<Typography component="span" variant="body2"> 更新于 {new Date(item.createTime).toLocaleString()}</Typography>
</React.Fragment> </React.Fragment>
} /> } />
</ListItemButton> </ListItemButton>

View File

@ -1,4 +1,5 @@
import { json } from 'react-router-dom'; import { v4 as uuidv4 } from 'uuid';
// UAT环境 // UAT环境
// const appKey = "k5hfiei5eevouvjohkapjaudpk2gakpaxha22fiy"; // const appKey = "k5hfiei5eevouvjohkapjaudpk2gakpaxha22fiy";
@ -231,6 +232,14 @@ const yzs = {
}).catch(error => { }).catch(error => {
console.log(error); console.log(error);
}); });
},
uniqueDeviceIdentifier: function () {
let udid = localStorage.getItem('uniqueDeviceIdentifier');
if (!udid) {
udid = uuidv4();
localStorage.setItem('uniqueDeviceIdentifier', udid);
}
return udid;
} }
}; };

View File

@ -3,7 +3,6 @@ import { createSlice } from '@reduxjs/toolkit'
export const userSlice = createSlice({ export const userSlice = createSlice({
name: 'user', name: 'user',
initialState: { initialState: {
udid: "", // web端使用ip地址作为udid
flushToken: "", flushToken: "",
accessToken: "", accessToken: "",
passportId: 0, passportId: 0,
@ -17,9 +16,6 @@ export const userSlice = createSlice({
verificationCode: "", verificationCode: "",
}, },
reducers: { reducers: {
setUdid: (state, action) => {
state.udid = action.payload;
},
setFlushToken: (state, token) => { setFlushToken: (state, token) => {
state.flushToken = token.payload; state.flushToken = token.payload;
}, },
@ -48,6 +44,6 @@ export const userSlice = createSlice({
}) })
// Action creators are generated for each case reducer function // Action creators are generated for each case reducer function
export const { setUdid, setFlushToken, setAccessToken, setUserInfo, setSelectInfo, setAccount, setPassword, setVerificationCode } = userSlice.actions export const { setFlushToken, setAccessToken, setUserInfo, setSelectInfo, setAccount, setPassword, setVerificationCode } = userSlice.actions
export default userSlice.reducer export default userSlice.reducer

View File

@ -49,6 +49,7 @@ export default function ({ udid }) {
> >
<TextField <TextField
name="username" name="username"
autoComplete="username"
label="请输入手机号码" label="请输入手机号码"
variant="outlined" variant="outlined"
value={account} value={account}
@ -70,6 +71,7 @@ export default function ({ udid }) {
name="password" name="password"
label="请输入验证码" label="请输入验证码"
type="password" type="password"
autoComplete="current-password"
variant="outlined" variant="outlined"
value={verificationCode} value={verificationCode}
onChange={handleInputChange} onChange={handleInputChange}

View File

@ -23,6 +23,7 @@ export default function () {
> >
<TextField <TextField
name="username" name="username"
autoComplete="username"
label="请输入手机号码" label="请输入手机号码"
variant="outlined" variant="outlined"
value={account} value={account}
@ -43,6 +44,7 @@ export default function () {
name="password" name="password"
label="请输入密码" label="请输入密码"
type="password" type="password"
autoComplete="current-password"
variant="outlined" variant="outlined"
value={password} value={password}
onChange={handleInputChange} onChange={handleInputChange}