React 在同一页面上管理多个音频并使用基于函数的组件一次播放一个
React Manage Multiple Audios on Same Page and play one at a time using function based components
我正在制作一个新的 React 应用程序,它在同一页面上有多个音乐卡。我想在更新新卡状态之前更改以前卡的状态。简而言之,我想在播放新音频之前暂停之前的音频。
import React, { useState , useEffect , useRef} from "react";
import Card from '@mui/material/Card';
import CardContent from '@mui/material/CardContent';
import CardMedia from '@mui/material/CardMedia';
import Typography from '@mui/material/Typography';
import { CardActionArea } from '@mui/material';
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
import IconButton from '@mui/material/IconButton';
import PauseICon from "@mui/icons-material/Pause";
import { logDOM } from "@testing-library/react";
export default function ActionAreaCard(props) {
const audioRef = useRef(new Audio("http://myinstants.org/games/22ecaa5e-f90f-4e81-96b1-b240751439fa.mp3"));
const [clicked, setClicked] = useState(false);
useEffect(() => {
audioRef.current.addEventListener('ended', () => setClicked(false));
if (clicked) {
audioRef.current.play();
} else {
audioRef.current.pause();
}
},[clicked]);
return (
<Card sx={{ maxWidth: 256 }} >
<CardMedia
component="img"
height="140"
image="https://picsum.photos/400/200"
alt="green iguana"
/>
<CardContent style={{ display: 'flex', flexDirection: 'column' }}>
<Typography gutterBottom variant="h5" component="div" style={{ textAlign: 'center', overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis' }}>
lorem Spem kjb j kl lk n lkn lk nlk n kln lkn kln kln kl nlk n vdr rtgvrt rtwbtr rtbvrt vbwrt vwretvw
</Typography>
{/* <PlayArrowIcon sx={{ height: 38, width: 38}}/> */}
<IconButton onClick={() => setClicked(!clicked)}>
{
clicked ? <PauseICon sx={{ height: 38, width: 38 }} /> : <PlayArrowIcon sx={{ height: 38, width: 38 }} />
}
</IconButton>
</CardContent>
</Card>
);
}
上面那个是我的扑克牌组件
上面的 GIF 是正在运行的应用程序。其中,当我播放第二个音频时,它会在停止旧音频之前启动它。我的背景来自 android 开发,其中我们只有一个媒体播放器对象,我们可以使用该对象进行管理。但是我在这里找不到解决方案,我们可以通过访问其他组件中的其他组件状态或者可能使用钩子等来实现。
在父存储活动播放中创建一个公共状态:
const [activePlaying,setActivePlaying]=useState(null);
为它创建一个处理程序:
const activePlayerhandler=useCallback((id)=>{
setActivePlaying(id);
},[id]);
将此处理程序作为 prop 传递:
...
{players.map((player,index)=>(
< ActionAreaCard onPlay={()=>activePlayerhandler(index)} playing={activePlaying===index}/>
))
...
现在你只需要在点击播放按钮时调用这个道具。
我正在制作一个新的 React 应用程序,它在同一页面上有多个音乐卡。我想在更新新卡状态之前更改以前卡的状态。简而言之,我想在播放新音频之前暂停之前的音频。
import React, { useState , useEffect , useRef} from "react";
import Card from '@mui/material/Card';
import CardContent from '@mui/material/CardContent';
import CardMedia from '@mui/material/CardMedia';
import Typography from '@mui/material/Typography';
import { CardActionArea } from '@mui/material';
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
import IconButton from '@mui/material/IconButton';
import PauseICon from "@mui/icons-material/Pause";
import { logDOM } from "@testing-library/react";
export default function ActionAreaCard(props) {
const audioRef = useRef(new Audio("http://myinstants.org/games/22ecaa5e-f90f-4e81-96b1-b240751439fa.mp3"));
const [clicked, setClicked] = useState(false);
useEffect(() => {
audioRef.current.addEventListener('ended', () => setClicked(false));
if (clicked) {
audioRef.current.play();
} else {
audioRef.current.pause();
}
},[clicked]);
return (
<Card sx={{ maxWidth: 256 }} >
<CardMedia
component="img"
height="140"
image="https://picsum.photos/400/200"
alt="green iguana"
/>
<CardContent style={{ display: 'flex', flexDirection: 'column' }}>
<Typography gutterBottom variant="h5" component="div" style={{ textAlign: 'center', overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis' }}>
lorem Spem kjb j kl lk n lkn lk nlk n kln lkn kln kln kl nlk n vdr rtgvrt rtwbtr rtbvrt vbwrt vwretvw
</Typography>
{/* <PlayArrowIcon sx={{ height: 38, width: 38}}/> */}
<IconButton onClick={() => setClicked(!clicked)}>
{
clicked ? <PauseICon sx={{ height: 38, width: 38 }} /> : <PlayArrowIcon sx={{ height: 38, width: 38 }} />
}
</IconButton>
</CardContent>
</Card>
);
}
上面那个是我的扑克牌组件
上面的 GIF 是正在运行的应用程序。其中,当我播放第二个音频时,它会在停止旧音频之前启动它。我的背景来自 android 开发,其中我们只有一个媒体播放器对象,我们可以使用该对象进行管理。但是我在这里找不到解决方案,我们可以通过访问其他组件中的其他组件状态或者可能使用钩子等来实现。
在父存储活动播放中创建一个公共状态:
const [activePlaying,setActivePlaying]=useState(null);
为它创建一个处理程序:
const activePlayerhandler=useCallback((id)=>{
setActivePlaying(id);
},[id]);
将此处理程序作为 prop 传递:
...
{players.map((player,index)=>(
< ActionAreaCard onPlay={()=>activePlayerhandler(index)} playing={activePlaying===index}/>
))
...
现在你只需要在点击播放按钮时调用这个道具。