android - 如何在 React Native 中播放多个音频?
问题描述
我想在我的 React Native 应用程序中播放多个音频文件。目前,一次播放一个音频,我也希望一次播放单个音频。我想要的是,如果一个音频正在播放并且用户突然点击第二个音频按钮,第一个音频按钮将暂停,第二个音频按钮应该播放。当用户再次点击第一个时,暂停的音频将从暂停的位置重新开始。类似于 whatsapp 音频消息。
我正在使用react-native-audio-recorder-player在我的应用程序中录制和播放音频。 检查应用程序设计
我的 FlatList 项目设计:
{ { this.toggleMediaPlayer(item.audiourl, index) } }}>
<TouchableOpacity
style={styles.viewBarWrapper}
onPress={this.onStatusPress}
>
<View style={styles.viewBar}>
<View style={styles.viewBarPlay} />
</View>
</TouchableOpacity>
<Text style={styles.txtCounter}>
{/* {this.state.playTime} / {this.state.duration} */}
</Text>
</View>
媒体播放器功能:
`toggleMediaPlayer(mediaPath, index) {
if (this.state.mediaFlag[index] == false) {
this.onStartPlay(mediaPath, index)
this.state.mediaFlag[index] = true;
var cloneObj = Object.assign({}, this.state.mediaFlag);
this.setState({ mediaFlag: cloneObj });
console.log(this.state.mediaFlag)
}
else {
this.onPausePlay(mediaPath)
this.state.mediaFlag[index] = false;
var cloneObj = Object.assign({}, this.state.mediaFlag);
this.setState({ mediaFlag: cloneObj });
console.log(this.state.mediaFlag)
}
}
`
休息代码
audioRecorderPlayer = new AudioRecorderPlayer();
async onStartPlay(path, index) {
console.log('onStartPlay');
this.audioRecorderPlayer.stopPlayer();
const msg = await this.audioRecorderPlayer.startPlayer(path);
console.log(msg);
this.audioRecorderPlayer.addPlayBackListener(async (e) => {
if (e.current_position === e.duration) {
console.log('finished');
// await this.setState({ mediaFlag: !this.state.mediaFlag });
this.state.mediaFlag[index] = false;
var cloneObj = Object.assign({}, this.state.mediaFlag);
this.setState({ mediaFlag: cloneObj });
console.log(this.state.mediaFlag)
this.audioRecorderPlayer.stopPlayer();
this.audioRecorderPlayer.removePlayBackListener();
}
else {
this.setState({
currentPositionSec: e.current_position,
currentDurationSec: e.duration,
playTime: this.audioRecorderPlayer.mmssss(Math.floor(e.current_position)),
duration: this.audioRecorderPlayer.mmssss(Math.floor(e.duration)),
})
}
return;
});
};
onPausePlay = async () => {
await this.audioRecorderPlayer.pausePlayer();
};
async onStopPlay(index) {
console.log('onStopPlay');
this.audioRecorderPlayer.stopPlayer();
this.audioRecorderPlayer.removePlayBackListener();
};
解决方案
截至v2.4.3
,它不是react-native-audio-recorder-player的功能(请参阅https://github.com/dooboolab/react-native-audio-recorder-player/issues/130)
但我必须自己做,所以这是我设法做到的:
要点是拥有所有玩家的父组件(或商店 - 如redux或react context),它知道玩家的状态(玩家是否在阅读它的声音?哪个?)
然后,当播放器播放声音时,它会调用父组件,父组件将停止当前正在阅读的任何其他播放器 - 必须按特定顺序完成以避免奇怪的行为
这是我的代码简化:
const ParentComponent = () => {
const [playerRecording, setPlayerRecording] = useState(false); // Which recording is currently playing?
const onPlay = async (onStartPlay, playerId) => {
// No player are reading or it is the same player
if (!playerRecording || playerRecording === playerId)
return onStartPlay();
// Another player is reading - stop it before starting the new one
audioRecorderPlayer.removePlayBackListener();
await audioRecorderPlayer.resumePlayer();
await audioRecorderPlayer.stopPlayer();
// Start the new player
onStartPlay();
};
}
const PlayerComponent = ({onPlay, setPlayerRecording, playerId}) => {
const onStartPlay = async () => {
setPlayerRecording(playerId);
audioRecorderPlayer.startPlayer(path);
...
}
return (
<PlayButton onPress={() => onPlay(onStartPlay, playerId)} />
)
}
推荐阅读
- bash - 代码必须在子目录中找到所有 MP4 文件才能使用 ffmpeg 进行压缩
- sql - SQL Server 2005 如何使用联合语法?
- r - 从 R 中的 CSV 文件中读取“...”中定义的函数输入值
- android - 日期选择器的 Android Spinner
- angular - 打字稿-导入后未定义导出的变量(字典)
- c# - 仅在第二次 API 调用的测试中重新创建数据库时出现 404 Not Found
- html - HTML元素高度计算规则
- mysql - 当我尝试在表中插入时,为什么插入前的触发器会出现错误 1054?
- html - 如何编辑页脚?
- javascript - 从工具提示中的按钮调用 Ajax