1.需求介绍
- 在uniapp中获取上传的音频文件的时长,根据时长来校验提交规则。
2.实现
2.1 在微信小程序中获取音频文件时长。
根据 uni.createInnerAudioContext()来获取音频文化时长,点击可直达该api的官方文档说明。
2.1.1 不兼容的写法
- 基于 uni.createInnerAudioContext() 封装的方法
- 在ios微信小程序中可以获取到音频文件时长,在android微信小程序中就获取不到音频文件时长。
const getAudioDurationByWx = (filePath) => {
return new Promise((resolve, reject) => {
// 创建并返回内部 audio 上下文 `innerAudioContext` 对象。
const audioContext = uni.createInnerAudioContext();
audioContext.src = filePath
let retryCount = 0 // 当前重试获取音频文件时长的次数
const maxRetries = 3 // 最大次数重试获取音频文件时长的次数
const checkDuration = () => {
if (audioContext.duration > 0) {
const duration = audioContext.duration // 获取音频文件的时长
audioContext.destroy() // 获取到音频文件的时长后, 直接销毁 `innerAudioContext`对象
resolve(duration) // 音频文件的时长返回出去,供外面使用。
} else if (retryCount < maxRetries) { // 重新试着获取时长。
retryCount++
setTimeout(checkDuration, 500) // 每500ms检查一次
} else {
audioContext.destroy(); // 超过了最大重试获取音频文件时长的次数后,直接销毁 `innerAudioContext`对象
reject(new Error('无法获取音频时长'))
}
}
// 等待一段时间后开始获取时长。
setTimeout(() => {
checkDuration()
}, 100)
// 监听`innerAudioContext`对象的错误回调方法
audioContext.onError((err) => {
audioContext.destroy()
reject(err)
})
})
}
2.1.2 微信小程序中的兼容写法
- 参考博客,点击也可直达文档。
- 如下列出代码
const getAudioDurationByWx = (filePath) => {
return new Promise((resolve, reject) => {
const audioContext = uni.createInnerAudioContext()
audioContext.volume = 0; // 音量0
audioContext.autoplay = true; // 自动播放
audioContext.src = filePath
audioContext.onTimeUpdate(() => {
if (audioContext.duration > 0) {
const duration = audioContext.duration
audioContext.destroy()
resolve(duration)
} else {
audioContext.destroy()
reject('无法获取音频时长')
}
audioContext.destroy(); // 销毁实例
})
audioContext.onError((err) => {
audioContext.destroy()
reject(err)
})
})
}
2.2 在Android中获取音频文件时长
2.2.1 在Android中如下获取
- 注意: 因为是音频文件上传,记得要去manifest.json中配置文件上传权限
const getAudioDurationByApp = (filePath) => {
return new Promise((resolve, reject) => {
try {
if(plus.os.name.toLowerCase() === 'android') {
const MediaMetadataRetriever = plus.android.importClass('android.media.MediaMetadataRetriever')
const retriever = new MediaMetadataRetriever()
retriever.setDataSource(filePath)
const duration = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)
const durationInSeconds = Math.floor(parseInt(duration) / 1000)
retriever.release()
resolve(durationInSeconds)
}
} catch (e) {
console.error('获取音频时长失败:', e)
reject(e)
}
})
}
最后
- 如有不正之处,请佬不吝赐教,万分感谢。
- 祝大家向上!