欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > 小程序中实现音频播放(原生 + uniapp)

小程序中实现音频播放(原生 + uniapp)

2025/4/13 2:11:39 来源:https://blog.csdn.net/qq_57952018/article/details/147120479  浏览:    关键词:小程序中实现音频播放(原生 + uniapp)

原生:

miniprogram/components/mp-audio/index.wxml

<view class="imt-audio"><view class="top"><view class="audio-control-wrapper"><image src="{{poster}}" mode="aspectFill" class="cover"></image><image src="/static/components/loading.png" wx:if="{{playState ==='loading'}}" class="play loading"></image><block wx:else><image src="/static/components/playbtn.png" alt="play" bind:tap="play" class="play" wx:if="{{playState === 'pause'}}"></image><image src="/static/components/pausebtn.png" alt="pause" bind:tap="pause" class="play" wx:else></image></block></view></view><view class="audio-wrapper"><view class="titlebox"><view class="title text-max1">{{name}}</view></view><slider class="audio-slider" block-size="12" max="{{duration}}" value="{{currentTime}}" bindchange="sliderChange" block-color="#999999" bindchanging="sliderChanging"></slider><view class="slidebox"><view>{{showCurrentTime}} / {{showDuration}}</view></view></view>
</view>

miniprogram/components/mp-audio/index.ts

Component({observers: {currentTime(value) {this.setData({showCurrentTime: this.formatSeconds(value)})},duration(value) {this.setData({showDuration: this.formatSeconds(value)})}},detached(){this.data.audioCtx.destroy()this.setData({audioCtx: null as unknown as WechatMiniprogram.InnerAudioContext})},lifetimes: {created() {this.setData({audioCtx: wx.createInnerAudioContext({useWebAudioImplement: false})})this.data.audioCtx.onTimeUpdate((e) => {const currentTime = this.data.audioCtx.currentTimethis.setData({currentTime,})})this.data.audioCtx.onPlay(() => console.log("播放"))this.data.audioCtx.onPause(() => console.log("暂停"))this.data.audioCtx.onStop(() => console.log("停止"))this.data.audioCtx.onEnded(() => {console.log("结束")this.setData({playState: 'pause',currentTime: 0})this.data.audioCtx.seek(0)})}},/*** 组件的属性列表*/properties: {/*** 音频源地址*/src: {type: String,value: ''},/*** 封面图片地址*/poster: {type: String,value: ''},/*** 音频标题*/name: {type: String,value: '标题'},/*** 歌手名称*/singer: {type: String,value: ''},},/*** 组件的初始数据*/data: {src: "",poster: "",name: "标题",singer: "",duration: 10,currentTime: 0,showCurrentTime: '00:00',showDuration: '00:00',playState: "pause", //"loading"/"playing"/"pause"isSliderChanging: false,audioCtx: null as unknown as WechatMiniprogram.InnerAudioContext},/*** 组件的方法列表*/methods: {setSrc(value: string) {this.data.audioCtx.src = valuelet v1 = setInterval(() => {if (this.data.audioCtx.duration > 0) {this.setData({duration: this.data.audioCtx.duration})clearInterval(v1)}},500)},setPoster(value: string) {this.setData({ poster: value });},setName(value: string) {this.setData({ name: value });},setSinger(value: string) {this.setData({ singer: value });},playerOnPlay() {this.setData({playState: 'playing'})this.triggerEvent('play');},playerOnPause() {this.setData({playState: 'pause'})this.triggerEvent('pause');},playerOnEnded() {this.setData({playState: 'pause'})this.triggerEvent('ended');},playerOnWaiting() {this.setData({playState: 'loading'})},playerOnError(e: WechatMiniprogram.VideoError) {wx.$log.error("playerOnError音频播放失败:" + JSON.stringify(e))this.setData({playState: 'pause'})this.triggerEvent('error', e);},formatSeconds(seconds: number | string): string {var result = typeof seconds === "string" ? parseFloat(seconds) : seconds;if (isNaN(result))return "";let h = Math.floor(result / 3600) < 10 ?"0" + Math.floor(result / 3600) :Math.floor(result / 3600);let m = Math.floor((result / 60) % 60) < 10 ?"0" + Math.floor((result / 60) % 60) :Math.floor((result / 60) % 60) + (Number(h)) * 60;let s = Math.floor(result % 60) < 10 ?"0" + Math.floor(result % 60) :Math.floor(result % 60);return `${m}:${s}`;},stop() {try {if (this.data.audioCtx) {this.data.audioCtx.stop();}this.setData({ currentTime: 0 });} catch (error: any) {console.error('停止失败:', error);this.triggerEvent('error', error);}},seek(t: number) {if (this.data.audioCtx) {this.data.audioCtx.seek(t);}},play() {try {if (this.data.audioCtx) {this.data.audioCtx.play();this.setData({playState: "playing"})}} catch (error: any) {console.error('播放失败:', error);this.triggerEvent('error', error);}},pause() {try {if (this.data.audioCtx) {this.data.audioCtx.pause();this.setData({playState: "pause"})}} catch (error: any) {console.error('暂停失败:', error);this.triggerEvent('error', error);}},sliderChange(e: WechatMiniprogram.SliderChanging) {console.log("sliderChange", e)this.setData({isSliderChanging: false})//就会存在滚动条拖不动的情况if (this.data.audioCtx) {this.data.audioCtx.seek(e.detail.value);this.setData({currentTime: e.detail.value})}},sliderChanging() {this.setData({isSliderChanging: true})},}
})

miniprogram/components/mp-audio/index.scss 

@mixin textoverflow() {display: -webkit-box;overflow: hidden;text-overflow: ellipsis;-webkit-box-orient: vertical;-webkit-line-clamp: 1;
}
@keyframes rowup {0% {-webkit-transform: translate(-50%, -50%) rotate(0deg);transform-origin: center center;}100% {-webkit-transform: translate(-50%, -50%) rotate(360deg);transform-origin: center center;}
}
.imt-audio{background: #ffffff;box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2);width: 100%;overflow: hidden;display: flex;box-sizing: border-box;position:relative;padding: 12rpx;border-radius: 12rpx;.top {width: 140rpx;position: relative;}.audio-wrapper {display: flex;flex-direction: column;justify-content: space-between;flex: 1;color: #fff;margin-left: 20rpx;width: 100%;height: 100%;.titlebox {display: flex;color: #000000;.title {font-size: 30rpx;@include textoverflow;}.singer {margin-left: 20rpx;font-size: 28rpx;max-width: 50%;@include textoverflow;}}}.slidebox {display: flex;justify-content: space-between;width: 96%;color: #333;}.uni-slider-tap-area {padding: 0;}.uni-slider-wrapper {min-height: 0;}.uni-slider-handle-wrapper {height: 6px;}.audio-slider {margin: 0 !important;}.cover {width: 120rpx;height: 120rpx;position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);animation-fill-mode: forwards;-webkit-animation-fill-mode: forwards;}.play {width: 80rpx;height: 80rpx;z-index: 99;background: rgba(0, 0, 0, 0.4);border-radius: 50%;position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);&.loading{width: 60rpx;height: 60rpx;animation: rotating_theme3 2s linear infinite;}}
}@keyframes rotating {0% {transform: rotateZ(0deg)}100% {transform: rotateZ(360deg)}
}
@keyframes rotating_theme3 {0% {transform: translate(-50%, -50%) rotateZ(0deg)}100% {transform: translate(-50%, -50%) rotateZ(360deg)}
}.hItem
{margin-left: 16rpx;
}.extrButton
{font-size: 36rpx;
}

使用:

<mp-audio id="mpAudio" />handleSetSrcInfo() {nextTick(() => {const child = this.selectComponent('#mpAudio');if (child) {child.setSrc(this.data.mission!.Media![0]);child.setName(this.data.mission.Title);}})},

 

uniapp:

components/yz-audio/yz-audio.vue

<template><view class="imt-audio"><view class="top"><view class="audio-control-wrapper"><image :src="poster" mode="aspectFill" class="cover"></image><image :src="require('./static/loading.png')" v-if="playState ==='loading'" class="play loading"></image><block v-else><image :src="require('./static/playbtn.png')" alt="play" @click="play" class="play"v-if="playState === 'pause'"></image><image :src="require('./static/pausebtn.png')" alt="pause" @click="pause" class="play" v-else></image></block></view></view><view class="audio-wrapper"><view class="titlebox"><view class="title text-max1">{{name}}</view></view><slider class="audio-slider" block-size="12" :max="duration" :value="currentTime" @change="sliderChange"block-color="#999999" @changing="sliderChanging"></slider><view class="slidebox"><view>{{formatSeconds(currentTime)}} / {{formatSeconds(duration)}}</view></view></view></view>
</template><script>export default {data() {return {src: "",poster: "",name: "标题",singer: "",duration: 10,currentTime: 0,playState: "pause", //"loading"/"playing"/"pause"isSliderChanging: false,audioCtx: null};},created() {this.audioCtx = uni.createInnerAudioContext()this.audioCtx.onTimeUpdate((e) => {const currentTime = this.audioCtx.currentTimethis.currentTime = currentTime})this.audioCtx.onPlay(() => console.log("播放"))this.audioCtx.onPause(() => console.log("暂停"))this.audioCtx.onStop(() => console.log("停止"))this.audioCtx.onEnded(() => {console.log("结束")this.playState = 'pause',this.currentTime = 0this.audioCtx.seek(0)})},destroyed() {this.audioCtx.destroy()this.audioCtx = null},methods: {setSrc(value) {this.audioCtx.src = valuelet v1 = setInterval(() => {console.log("this.audioCtx.duration", this.audioCtx.duration)if (this.audioCtx.duration > 0) {this.duration = this.audioCtx.durationclearInterval(v1)}}, 500)},setPoster(value) {this.poster = value;},setName(value) {this.name = value;},play() {if (this.audioCtx) {this.audioCtx.play();this.playState = "playing"}},pause() {this.audioCtx.pause();this.playState = "pause"},sliderChange(e) {this.isSliderChanging = false;if (this.audioCtx) {this.audioCtx.seek(e.detail.value);this.currentTime = e.detail.value}},formatSeconds(seconds) {var result = typeof seconds === "string" ? parseFloat(seconds) : seconds;if (isNaN(result))return "";let h = Math.floor(result / 3600) < 10 ?"0" + Math.floor(result / 3600) :Math.floor(result / 3600);let m = Math.floor((result / 60) % 60) < 10 ?"0" + Math.floor((result / 60) % 60) :Math.floor((result / 60) % 60) + (Number(h)) * 60;let s = Math.floor(result % 60) < 10 ?"0" + Math.floor(result % 60) :Math.floor(result % 60);return `${m}:${s}`;},sliderChanging() {this.isSliderChanging = true;},},}
</script><style lang="scss">@import './index.scss';
</style>

components/yz-audio/index.scss 

@mixin textoverflow() {display: -webkit-box;overflow: hidden;text-overflow: ellipsis;-webkit-box-orient: vertical;-webkit-line-clamp: 1;
}
@keyframes rowup {0% {-webkit-transform: translate(-50%, -50%) rotate(0deg);transform-origin: center center;}100% {-webkit-transform: translate(-50%, -50%) rotate(360deg);transform-origin: center center;}
}
.imt-audio{background: #ffffff;box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2);width: 100%;overflow: hidden;display: flex;box-sizing: border-box;position:relative;padding: 12rpx;border-radius: 12rpx;.top {width: 140rpx;position: relative;}.audio-wrapper {display: flex;flex-direction: column;justify-content: space-between;flex: 1;color: #fff;margin-left: 20rpx;width: 100%;height: 100%;.titlebox {display: flex;color: #000000;.title {font-size: 30rpx;@include textoverflow;}.singer {margin-left: 20rpx;font-size: 28rpx;max-width: 50%;@include textoverflow;}}}.slidebox {display: flex;justify-content: space-between;width: 96%;color: #333;}.uni-slider-tap-area {padding: 0;}.uni-slider-wrapper {min-height: 0;}.uni-slider-handle-wrapper {height: 6px;}.audio-slider {margin: 0 !important;}.cover {width: 120rpx;height: 120rpx;position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);animation-fill-mode: forwards;-webkit-animation-fill-mode: forwards;}.play {width: 80rpx;height: 80rpx;z-index: 99;background: rgba(0, 0, 0, 0.4);border-radius: 50%;position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);&.loading{width: 60rpx;height: 60rpx;animation: rotating_theme3 2s linear infinite;}}
}@keyframes rotating {0% {transform: rotateZ(0deg)}100% {transform: rotateZ(360deg)}
}
@keyframes rotating_theme3 {0% {transform: translate(-50%, -50%) rotateZ(0deg)}100% {transform: translate(-50%, -50%) rotateZ(360deg)}
}.hItem
{margin-left: 16rpx;
}.extrButton
{font-size: 36rpx;
}

 使用:

<YzAudio v-if="obj.Media && obj.Media.length" ref="player1" />handleSetAudioSrcInfo() {if (!this.obj.Media) returnthis.$nextTick(() => {const player1 = this.$refs.player1;player1.setSrc(this.obj.Media[0]);player1.setName(this.obj.Title);})}

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词