taro填坑之路
音频InnerAudioContext
技术栈=>hooks+TS
人狠话不多,直接上代码
坑代码
import { View } from '@tarojs/components';
import Taro from '@tarojs/taro';
import React, { useEffect, useState } from 'react';
import { AtSlider } from 'taro-ui';
interface RecordLineLayoutProps {}
// 进度条录音布局
const RecordLineLayout: React.FC<RecordLineLayoutProps> = ({
}) => {
const [playing, setPlaying] = useState(false) // 是否播放中
const [timeText, setTimeText] = useState('') // 总时长
const [sliderVal, setSliderVal] = useState(0) // 进度条位置
// 创建音频
let innerAudioContext = Taro.createInnerAudioContext()
innerAudioContext.src = ''// 音頻url
innerAudioContext.onPlay(() => { // 开始
console.log('开始播放')
setPlaying(true)
})
innerAudioContext.onPause(() => { // 暂停
console.log('暂停播放');
setPlaying(false)
})
innerAudioContext.onStop(() => {
console.log('停止');
setPlaying(false)
})
innerAudioContext.onSeeked(() => {
console.log('跳转');
innerAudioContext.play()
})
innerAudioContext.onTimeUpdate(() => {
console.log('时间更新', innerAudioContext.currentTime);
setSliderVal(innerAudioContext.currentTime)
})
innerAudioContext.onError((res) => {
console.log(res.errMsg)
console.log(res.errCode)
innerAudioContext.stop()
setPlaying(false)
})
// 切换播放状态
const changeStatus = () => {
if (playing) {
innerAudioContext.pause()
} else {
innerAudioContext.play()
}
}
// 拖拽进度条
const onChange = (e) => {
console.log('拖拽进度===', e);
innerAudioContext.seek(e)
}
useEffect(() => {
return () => {
innerAudioContext.destroy()
}
}, []);
return (
<View className="recordLineLayoutMap">
<View className="playBtn" onClick={changeStatus}>开始</View>
<View className="progressBarBox">
<AtSlider value={sliderVal} min={0} max={1000} blockSize={15} onChange={onChange} ></AtSlider>
</View>
<View className="time" >
{timeText}
</View>
</View>
);
};
export default RecordLineLayout;
后面发现每次使用useState,都是创建一个新的innerAudioContext实例,导致无法操作到原来的innerAudioContext实例,于是....
正确代码,将innerAudioContext 用useState保存起来,再调用暂停和停止
import { View } from '@tarojs/components';
import Taro from '@tarojs/taro';
import React, { useEffect, useState } from 'react';
import { AtSlider } from 'taro-ui';
import './RecordLineLayout.scss';
interface RecordLineLayoutProps {
}
// 进度条录音布局
const RecordLineLayout: React.FC<RecordLineLayoutProps> = ({
}) => {
const [playing, setPlaying] = useState(false) // 是否播放中
const [timeText, setTimeText] = useState('') // 总时长
const [sliderVal, setSliderVal] = useState(0) // 进度条位置
// 创建音频
let innerAudioContext = Taro.createInnerAudioContext()
innerAudioContext.src = ''// 音頻url
innerAudioContext.onPlay(() => { // 开始
console.log('开始播放')
setPlaying(true)
})
innerAudioContext.onPause(() => { // 暂停
console.log('暂停播放');
setPlaying(false)
})
innerAudioContext.onStop(() => {
console.log('停止');
setPlaying(false)
})
innerAudioContext.onSeeked(() => {
console.log('跳转');
innerAudioContext.play()
})
innerAudioContext.onTimeUpdate(() => {
console.log('时间更新', audioContextIns.currentTime);
setSliderVal(audioContextIns.currentTime)
})
innerAudioContext.onError((res) => {
console.log(res.errMsg)
console.log(res.errCode)
innerAudioContext.stop()
setPlaying(false)
})
const [audioContextIns, setAudioContextIns] = useState(innerAudioContext)// 音频实例持久化
// 切换播放状态
const changeStatus = () => {
if (playing) {
audioContextIns.pause()
} else {
audioContextIns.play()
}
}
// 拖拽进度条
const onChange = (e) => {
console.log('拖拽进度===', e);
innerAudioContext.seek(e)
}
useEffect(() => {
return () => {
innerAudioContext.destroy()
}
}, []);
return (
<View className="recordLineLayoutMap">
<View className="playBtn" onClick={changeStatus}>开始</View>
<View className="progressBarBox">
<AtSlider value={sliderVal} min={0} max={1000} blockSize={15} onChange={onChange} ></AtSlider>
</View>
<View className="time" >
{timeText}
</View>
</View>
);
};
export default RecordLineLayout;