1.整理录音内容的获取。
This commit is contained in:
parent
1030f285dc
commit
80b494b6b1
@ -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": {
|
||||||
|
21
src/App.js
21
src/App.js
@ -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 => {
|
||||||
|
@ -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 />
|
||||||
|
@ -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={{
|
||||||
|
@ -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>
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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
|
@ -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}
|
||||||
|
@ -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}
|
||||||
|
Loading…
Reference in New Issue
Block a user