1.解决Firefox浏览器 canvas太长无法绘制的问题 2.解决云端返回列表格式不一致问题
This commit is contained in:
parent
8bd230ba0b
commit
69b07afc78
@ -1,7 +1,7 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useSelector, useDispatch } from 'react-redux'
|
||||
import AppBar from './AppBar';
|
||||
import RecordList from './RecordList';
|
||||
import RecordList from './components/RecordList';
|
||||
import PlayerBar from './PlayerBar';
|
||||
import store from './business/store';
|
||||
import yzs from "./business/request.js";
|
||||
@ -33,15 +33,24 @@ const theme = createTheme({
|
||||
},
|
||||
});
|
||||
|
||||
const lyricsBrowserStyle = {
|
||||
marginTop: 16,
|
||||
paddingBottom: 40,
|
||||
padding: 24,
|
||||
}
|
||||
|
||||
|
||||
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));
|
||||
});
|
||||
if (record.transResultUrl) {
|
||||
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)));
|
||||
});
|
||||
@ -96,8 +105,11 @@ export default function () {
|
||||
const passportId = useSelector(state => state.user.passportId);
|
||||
const currentTime = useSelector(state => state.recorder.currentTime);
|
||||
const currentLyric = useSelector(state => state.recorder.currentLyric);
|
||||
const currentIndex = useSelector(state => state.recorder.currentIndex);
|
||||
const recordList = useSelector(state => state.recorder.list);
|
||||
const [playerBarWidth, setPlayerBarWidth] = useState(0);
|
||||
const [open, setOpen] = useState(true);
|
||||
const [hasLyric, setHasLyric] = useState(true);
|
||||
useEffect(() => {
|
||||
if (passportId <= 0) return;
|
||||
yzs.get_record_list(accessToken, passportId).then(list => {
|
||||
@ -110,6 +122,14 @@ export default function () {
|
||||
});
|
||||
}, [passportId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (recordList.length <= 0) {
|
||||
setHasLyric(false);
|
||||
return;
|
||||
}
|
||||
setHasLyric((recordList.at(currentIndex).transResultUrl));
|
||||
}, [currentIndex, currentLyric]);
|
||||
|
||||
const onClick = () => {
|
||||
setOpen(!open);
|
||||
setPlayerBarWidth(document.documentElement.clientWidth - 240 - 48); // 防止中途底部出现scrollbar
|
||||
@ -138,13 +158,15 @@ export default function () {
|
||||
<ThemeProvider theme={theme}>
|
||||
<CssBaseline />
|
||||
<AppBar />
|
||||
<RecordList open={open} fetchRecord={fetchRecord} />
|
||||
<RecordList open={open} recordList={recordList} currentIndex={currentIndex} fetchRecord={fetchRecord} />
|
||||
<ClickHanlde open={open} onClick={onClick} />
|
||||
<Main open={open}
|
||||
onTransitionEnd={onTransitionEnd}
|
||||
>
|
||||
<PlayerBar width={playerBarWidth} currentTime={currentTime} />
|
||||
<RecordLyrics currentLyric={currentLyric} currentTime={currentTime} />
|
||||
{hasLyric ? <RecordLyrics style={lyricsBrowserStyle} currentLyric={currentLyric} currentTime={currentTime} /> :
|
||||
<div style={lyricsBrowserStyle}
|
||||
/>}
|
||||
</Main>
|
||||
</ThemeProvider>
|
||||
</Box >
|
||||
|
@ -5,7 +5,7 @@ import pauseIcon from "./assets/play.png";
|
||||
import playIcon from "./assets/pause.png";
|
||||
import downloadIcon from "./assets/download.png";
|
||||
import { setCurrentTime, setPauseState, togglePauseState, setCurrentWaveData } from "./business/recorderSlice.js"
|
||||
import { audioWaveData } from "./business/utilities"
|
||||
import { audioWaveData, sampleInterval } from "./business/utilities"
|
||||
import ProgressBar from "./components/ProgressBar";
|
||||
|
||||
const durationFormat = (time) => {
|
||||
@ -33,7 +33,7 @@ export default function ({ width, currentTime }) {
|
||||
|
||||
useEffect(() => {
|
||||
if (currentBlob.length <= 0) return;
|
||||
audioWaveData(currentBlob, (duration > 20 * 60) ? 200 : 100)
|
||||
audioWaveData(currentBlob, sampleInterval(duration))
|
||||
.then(data => dispatch(setCurrentWaveData(data)));
|
||||
}, [duration]);
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
import React from "react";
|
||||
import { Typography, Paper } from "@mui/material";
|
||||
import styles from './RecordLyrics.module.css';
|
||||
import { useSelector, useDispatch } from 'react-redux'
|
||||
|
||||
function isHighlight(currentTime, { start, end }) {
|
||||
@ -8,17 +7,15 @@ function isHighlight(currentTime, { start, end }) {
|
||||
return (currentTime > start) && (currentTime <= end);
|
||||
}
|
||||
|
||||
|
||||
|
||||
export default function ({ currentLyric, currentTime }) {
|
||||
export default function ({ style, currentLyric, currentTime }) {
|
||||
const currentIndex = useSelector(state => state.recorder.currentIndex);
|
||||
const recordList = useSelector(state => state.recorder.list);
|
||||
|
||||
if (recordList.length === 0) return <React.Fragment />;
|
||||
|
||||
return <Paper className={styles.lyricsBrowser}>
|
||||
return <Paper style={style}>
|
||||
{recordList.at(currentIndex).type === 1 ? (typeof currentLyric === "object" ? currentLyric.map((lyric, index) => {
|
||||
return <div className={styles.lyricItem}>
|
||||
return <div style={{ paddingBottom: 40 }}>
|
||||
<Typography align="left" color={isHighlight(currentTime, lyric) ? "red" : "black"}>{lyric.text}</Typography>
|
||||
</div>
|
||||
}) : <React.Fragment />) : <div style={{ whiteSpace: "pre-wrap" }}>{typeof currentLyric === "string" ? currentLyric : ""}</div>}
|
||||
|
@ -1,9 +0,0 @@
|
||||
.lyricsBrowser {
|
||||
margin-top: 16px;
|
||||
padding-bottom: 40px;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.lyricItem {
|
||||
padding-bottom: 40px;
|
||||
}
|
@ -183,10 +183,11 @@ const yzs = {
|
||||
'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
|
||||
},
|
||||
}).then(response => response.json()).then((json) => {
|
||||
console.log("flushToken: ", json.result.flushToken);
|
||||
if (json.returnCode != "uc_0000") {
|
||||
throw json.message;
|
||||
}
|
||||
// console.log("flushToken: ", json.result.flushToken);
|
||||
return json.result.flushToken;
|
||||
}).catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
dynamic_code_login: function (udid, userCell, phoneCode) {
|
||||
|
@ -1,3 +1,12 @@
|
||||
// 间隔多长时间取一个采样点
|
||||
// duration 秒,有小数点
|
||||
const sampleInterval = (duration) => {
|
||||
let interval = (duration > 20 * 60) ? 200 : 100;
|
||||
let isFirefox = window.navigator.userAgent.includes("Firefox");
|
||||
if (isFirefox && (interval < 400)) interval = 400; // firefox canvas width 不能过长
|
||||
return interval;
|
||||
}
|
||||
|
||||
// interval 间隔ms采点
|
||||
function audioWaveData(url, interval) {
|
||||
if (url.length <= 0) return;
|
||||
@ -24,4 +33,4 @@ function audioWaveData(url, interval) {
|
||||
});
|
||||
}
|
||||
|
||||
export { audioWaveData };
|
||||
export { sampleInterval, audioWaveData };
|
@ -1,4 +1,6 @@
|
||||
import { useRef, useCallback, useState, useEffect } from "react";
|
||||
import { sampleInterval } from "../business/utilities"
|
||||
import { useMemo } from "react";
|
||||
|
||||
const pointWidth = 2;
|
||||
const pointMargin = 3;
|
||||
@ -82,7 +84,7 @@ const paintCanvas = ({
|
||||
|
||||
// duration ms
|
||||
export default function ({ width, duration, currentTime, playing, seek, waveData }) {
|
||||
const interval = (duration > 20 * 60 * 1000) ? 200 : 100; // ms
|
||||
const interval = useMemo(() => sampleInterval(duration / 1000), [duration]);
|
||||
const container = useRef(null);
|
||||
const canvas = useRef(null);
|
||||
const [scrollLeft, setScrollLeft] = useState(0);
|
||||
|
@ -8,16 +8,14 @@ import ListItemButton from '@mui/material/ListItemButton';
|
||||
import ListItemText from '@mui/material/ListItemText';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import Toolbar from '@mui/material/Toolbar';
|
||||
import { setCurrentIndex } from "./business/recorderSlice.js"
|
||||
import { setCurrentIndex } from "../business/recorderSlice.js"
|
||||
import AccessTimeFilledIcon from '@mui/icons-material/AccessTimeFilled';
|
||||
|
||||
const drawerWidth = 240;
|
||||
|
||||
export default function ({ open, fetchRecord }) {
|
||||
export default function ({ open, recordList, currentIndex, fetchRecord }) {
|
||||
const dispatch = useDispatch();
|
||||
const accessToken = useSelector(state => state.user.accessToken);
|
||||
const currentIndex = useSelector(state => state.recorder.currentIndex);
|
||||
const recordList = useSelector(state => state.recorder.list);
|
||||
const onSelected = (event, index) => {
|
||||
console.log("onSelected", index, recordList.at(index).transResultUrl)
|
||||
dispatch(setCurrentIndex(index));
|
Loading…
Reference in New Issue
Block a user