hookehuyr

测试音频功能

<!--
* @Date: 2023-06-12 11:23:10
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2023-06-12 14:51:13
* @LastEditTime: 2024-09-20 17:40:03
* @FilePath: /map-demo/src/components/audioBackground.vue
* @Description: 文件描述
-->
......
/*
* @Date: 2023-05-29 11:10:19
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-09-18 09:38:42
* @LastEditTime: 2024-09-20 17:29:12
* @FilePath: /map-demo/src/route.js
* @Description: 文件描述
*/
......@@ -64,7 +64,7 @@ export default [
},
{
path: '/bieyuan/info',
component: () => import('@/views/bieyuan/info.vue'),
component: () => import('@/views/bieyuan/info_w.vue'),
meta: {
title: '详情页',
},
......
<!--
* @Date: 2024-09-15 22:08:49
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-09-20 15:56:20
* @LastEditTime: 2024-09-20 17:35:46
* @FilePath: /map-demo/src/views/bieyuan/info.vue
* @Description: 文件描述
-->
......@@ -73,14 +73,14 @@
</div>
<div class="van-hairline--bottom" style="margin: 0 1rem;"></div>
</div>
<div class="audio-wrapper">
<!--<div class="audio-wrapper">
<div :class="['audio-item', play_audio_index === index ? 'click' : '']" v-for="(item, index) in audioList" :key="index">
<div>{{ item.text }}</div>
<!-- <div :class="['audio-icon', play_audio_index === index ? 'click' : '']"></div> -->
<!~~ <div :class="['audio-icon', play_audio_index === index ? 'click' : '']"></div> ~~>
<van-icon @click="stopAudio(item, index)" v-if="item.play" size="2rem" name="stop-circle-o" color="#DD7850" />
<van-icon v-else @click="playAudio(item, index)" size="2rem" name="https://cdn.ipadbiz.cn/bieyuan/map/icon/audio_icon.png" />
</div>
</div>
</div>-->
<div style="padding: 0 1rem;">
<img src="https://cdn.ipadbiz.cn/bieyuan/map/xcx.png" style="width: 100%;">
</div>
......@@ -100,9 +100,15 @@
</template>
<script setup>
import { ref } from 'vue'
import { ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { storeToRefs } from 'pinia'
import { mainStore } from '@/store';
const store = mainStore();
const { audio_status } = storeToRefs(store);
const $route = useRoute();
const $router = useRouter();
......@@ -121,15 +127,15 @@ const play_audio_index = ref(null);
const audioList = ref([{
text: '5分钟观呼吸',
src: 'https://cdn.ipadbiz.cn/bieyuan/map/1130958712.mp3',
src: 'https://cdn.ipadbiz.cn/bieyuan/map/audio/%E6%AD%A3%E5%BF%B5%E5%91%BC%E5%90%B8%EF%BC%8810%E5%88%86%E9%92%9F%EF%BC%89.mp3',
play: false,
}, {
text: '10分钟正念静坐',
src: 'https://cdn.ipadbiz.cn/bieyuan/map/1130958712.mp3',
src: 'https://cdn.ipadbiz.cn/bieyuan/map/audio/%E5%8D%81%E5%88%86%E9%92%9F%E6%AD%A3%E5%BF%B5%E9%9D%99%E5%9D%9020210510.mp3',
play: false,
}, {
text: '15分钟正念静坐',
src: 'https://cdn.ipadbiz.cn/bieyuan/map/1130958712.mp3',
src: 'https://cdn.ipadbiz.cn/bieyuan/map/audio/%E5%8D%81%E5%88%86%E9%92%9F%E6%AD%A3%E5%BF%B5%E9%9D%99%E5%9D%9020210510.mp3',
play: false,
}])
......@@ -143,6 +149,9 @@ const playAudio = (item, index) => {
play_status.then(() => {
console.warn('success');
item.play = true;
// 存放到pinia里面控制
store.changeAudioSrc(audio.value.src);
store.changeAudioStatus('play');
}).catch((e) => {
// 失败
console.log('Operation is too fast, audio play fails')
......@@ -157,6 +166,19 @@ const stopAudio = (item, index) => {
const audio = ref(new Audio());
onMounted(() => {
// 存放到pinia里面控制
if (store.changeAudio(audio.value)){
store.changeAudio(audio.value);
store.changeAudioStatus('pause');
}
})
// onUnmounted(() => {
// audio.value.pause();
// store.changeAudioStatus('pause');
// })
const audio_play = (src, index) => {
audio.value.src = src;
}
......@@ -183,6 +205,22 @@ const goTo = () => { // 打开标记地图显示
}
}
const voicePause = () => {
audio.value.pause();
store.changeAudioStatus('pause');
}
watch(
() => audio_status.value,
(v) => {
if (v === 'pause') {
voicePause();
audioList.value.forEach(item => item.play = false);
}
},
{ immediate: true }
);
defineExpose({
outerStopAudio
})
......
<!--
* @Date: 2024-09-15 22:08:49
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-09-20 17:44:30
* @FilePath: /map-demo/src/views/bieyuan/info_w.vue
* @Description: 文件描述
-->
<template>
<div class="info-page">
<div>
<van-config-provider :theme-vars="themeVars">
<van-swipe class="my-swipe" indicator-color="#DD7850" lazy-render :autoplay="5000">
<van-swipe-item v-for="image in images" :key="image">
<van-image fit="cover" width="100%" height="13rem" :src="image" />
</van-swipe-item>
</van-swipe>
</van-config-provider>
</div>
<div class="info-content-wrapper">
<div class="info-header">
<div>
<p class="info-title">选佛场</p>
<p class="info-sub-title">南楼2层</p>
</div>
<div @click="goTo()" class="info-btn">前往</div>
</div>
<div class="van-hairline--bottom">
<van-tabs v-model:active="active" color="#DD7850" title-active-color="#DD7850" sticky>
<van-tab title="介 绍">
<div class="info-content">
<p style="line-height: 1.75; padding: 0 0.85rem; color: #47525F;">选佛场是一个宗教活动场所,集禅堂与讲堂功能于一体。其设计仿制古代石窟样式,把古代人修行的场所“石窟”搬进室内。禅堂内的释迦牟尼佛像,仿麦积山石窟第44号特窟“东方的微笑”的造型。禅堂设计自然古朴,匠心独运,星光、烛光、月光三光辉映,营造出“一个人不孤单,一千人不喧闹”的宁静祥和的氛围。禅堂可容纳千人,开展讲经、禅修、法会等多种活动,提供礼佛、供灯、静坐等体验。</p>
<div class="van-hairline--bottom" style="margin: 1rem 0;"></div>
<div style="padding: 1rem;">
<div style="color: #DD7850;">•&nbsp;五方塔</div>
<div style="color: #47525F; margin-top: 1rem; line-height: 1.75;">禅堂外的草坪,安立着大小不一五座佛塔。信众可绕塔或悬挂风铃祝愿祈福,在肃静庄严的氛围中得到佛力加持,自净其意,心想事成。</div>
</div>
</div>
</van-tab>
<van-tab title="故 事">
<div style="padding: 0 1rem;">
<div style="padding: 1rem;">
<div style="color: #DD7850;">•&nbsp;选官何如选佛</div>
</div>
<div style="padding: 0 1rem;">
<van-image width="100%" height="11rem" fit="cover" src="https://cdn.ipadbiz.cn/bieyuan/map/Mix_20230612_201951.png" />
</div>
<div style="padding: 1rem;">
<p style="color: #47525F; line-height: 1.75;">过去把禅堂叫作选佛场,意思是选择作佛的场所。这个典故与丹霞禅师有关。 <br />他原本是一个秀才,赴京赶考的途中遇到一位禅师,这位禅师跟他讲,选官何如选佛?考官还不如成佛利益更大。世间功名如过眼云烟,即便追求得到也是暂时利益,执著于此就会烦恼重重,甚至不断造业。而学佛修行,考佛就是要成佛,成就生命永恒的福祉。这是永久的利益,尽未来际的利益。每个生命原本具备觉悟的潜质,具有无尽的功德宝藏,取之不尽用之不竭。成佛,可以断除一切迷惑烦恼,可以彻底地开发我们生命的潜质,全然觉醒,这个利益无量无边。丹霞禅师深具慧根,一经点拨,马上出家。</p>
</div>
<div class="van-hairline--bottom" style="margin: 0 1rem;"></div>
</div>
<div style="padding: 0 1rem;">
<div style="padding: 1rem;">
<div style="color: #DD7850;">•&nbsp;把洞窟搬进讲堂</div>
</div>
<div style="padding: 0 1rem;">
<van-image width="100%" height="11rem" fit="cover" src="https://cdn.ipadbiz.cn/bieyuan/map/Mix_20240815_211927.png" />
</div>
<div style="padding: 1rem;">
<p style="color: #47525F; line-height: 1.75;">洞窟,是传统的佛教建筑形式,最早在印度盛行,古代僧人喜欢在崇山峻岭的幽僻处开凿洞窟,遁世修行。选佛场集禅堂与讲堂的功能于一体,把洞窟搬进讲堂,既有回归佛教本怀的宁静温暖,又体现出融入泰宁岩穴文化的祥和之气。</p>
</div>
<div class="van-hairline--bottom" style="margin: 0 1rem;"></div>
</div>
</van-tab>
<van-tab title="体 验">
<div style="padding: 0 1rem;">
<div style="padding: 1rem;">
<div style="color: #DD7850;">•&nbsp;供灯</div>
<div style="color: #47525F; margin-top: 1rem; line-height: 1.75;">禅堂内自助供灯。</div>
</div>
<div style="padding: 0 1rem;">
<van-image width="100%" height="11rem" fit="cover" src="https://cdn.ipadbiz.cn/bieyuan/map/Mix_20240815_211927.png" />
</div>
<div class="van-hairline--bottom" style="margin: 0 1rem;"></div>
</div>
<div class="audio-wrapper">
<div :class="['audio-item', play_audio_index === index ? 'click' : '']" v-for="(item, index) in audioList" :key="index">
<div>{{ item.text }}</div>
<!-- <div :class="['audio-icon', play_audio_index === index ? 'click' : '']"></div> -->
<van-icon @click="stopAudio(item, index)" v-if="item.play" size="2rem" name="stop-circle-o" color="#DD7850" />
<van-icon v-else @click="playAudio(item, index)" size="2rem" name="https://cdn.ipadbiz.cn/bieyuan/map/icon/audio_icon.png" />
</div>
</div>
<div style="padding: 0 1rem;">
<img src="https://cdn.ipadbiz.cn/bieyuan/map/xcx.png" style="width: 100%;">
</div>
</van-tab>
</van-tabs>
</div>
</div>
<div style="display: flex; justify-content: center; margin: 3rem;">
<van-image
width="3rem"
height="3rem"
fit="contain"
src="https://cdn.ipadbiz.cn/bieyuan/map/icon/scan_logo.png"
/>
</div>
</div>
</template>
<script setup>
import { ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { storeToRefs } from 'pinia'
import { mainStore } from '@/store';
const store = mainStore();
const { audio_status, audio_entity } = storeToRefs(store);
const $route = useRoute();
const $router = useRouter();
const themeVars = ref({
swipeIndicatorInactiveBackground: '#fff',
});
const images = ref([
'https://cdn.ipadbiz.cn/bieyuan/map/swiper_img.png',
'https://cdn.ipadbiz.cn/bieyuan/map/Mix_20230612_201951.png',
'https://cdn.ipadbiz.cn/bieyuan/map/Mix_20240815_211927.png',
]);
const active = ref(0);
const play_audio_index = ref(null);
const audioList = ref([{
text: '5分钟观呼吸',
src: 'https://cdn.ipadbiz.cn/bieyuan/map/audio/%E6%AD%A3%E5%BF%B5%E5%91%BC%E5%90%B8%EF%BC%8810%E5%88%86%E9%92%9F%EF%BC%89.mp3',
play: false,
}, {
text: '10分钟正念静坐',
src: 'https://cdn.ipadbiz.cn/bieyuan/map/audio/%E5%8D%81%E5%88%86%E9%92%9F%E6%AD%A3%E5%BF%B5%E9%9D%99%E5%9D%9020210510.mp3',
play: false,
}, {
text: '15分钟正念静坐',
src: 'https://cdn.ipadbiz.cn/bieyuan/map/audio/%E5%8D%81%E5%88%86%E9%92%9F%E6%AD%A3%E5%BF%B5%E9%9D%99%E5%9D%9020210510.mp3',
play: false,
}])
const playAudio = (item, index) => {
audioList.value.forEach(item => item.play = false);
audio.value.src = item.src;
play_audio_index.value = index;
let play_status = audio.value.play() // 播放
if (play_status) {
console.warn('start');
// if (audio_status.value === 'play') {
// audio_entity.value.pause();
// }
play_status.then(() => {
console.warn('success');
item.play = true;
// 存放到pinia里面控制
// store.changeAudioSrc(audio.value.src);
// store.changeAudioStatus('play');
}).catch((e) => {
// 失败
console.log('Operation is too fast, audio play fails')
})
}
}
const stopAudio = (item, index) => {
item.play = false;
audio.value.pause();
}
const audio = ref(new Audio());
onMounted(() => {
// 存放到pinia里面控制
store.changeAudio(audio.value);
// store.changeAudioStatus('pause');
})
onUnmounted(() => {
audio.value.pause();
store.changeAudioStatus('pause');
})
const audio_play = (src, index) => {
audio.value.src = src;
}
const outerStopAudio = () => {
audio.value.pause();
}
const emit = defineEmits(["closeFloat", 'route']);
const goTo = () => { // 打开标记地图显示
if ($router.currentRoute.value.path === '/bieyuan/info') { // 详情页
$router.push({
path: '/bieyuan/map',
query: {
id: $route.query.id,
marker_id: '12345'
}
})
} else { // 地图页
//
emit("closeFloat", false);
//
emit("route", 'marker_id');
}
}
const voicePause = () => {
audio.value.pause();
store.changeAudioStatus('pause');
}
watch(
() => audio_status.value,
(v) => {
if (v === 'pause') {
voicePause();
audioList.value.forEach(item => item.play = false);
}
},
{ immediate: true }
);
defineExpose({
outerStopAudio
})
</script>
<style lang="less">
.info-page {
background-color: #EBEBEB;
height: 100vh;
overflow: scroll;
position: relative;
.info-content-wrapper {
// position: absolute;
// top: 14.9rem;
margin: 1rem;
margin-top: 0;
// padding: 1rem;
border-radius: 0.5rem;
background-color: white;
.info-header {
padding: 1rem 2rem 0;
display: flex;
justify-content: space-between;
// align-items: center;
.info-title {
font-size: 1.25rem;
margin-bottom: 0.5rem;
}
.info-sub-title {
font-size: 0.85rem;
color: #A0A8B1;
}
.info-btn {
width: 3rem;
height: 1.5rem;
border: 1px solid #DD7850;
color: #DD7850;
border-radius: 0.8rem;
font-size: 0.85rem;
text-align: center;
line-height: 1.5rem;
}
}
.info-content {
padding: 1rem;
}
.audio-wrapper {
padding: 1rem;
.audio-item {
color: #47525F;
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
background-color: #FFF;
border-radius: 0.25rem;
margin: 1rem;
box-shadow: 0 0 0.5rem rgba(0, 0, 0, 0.1);
&.click {
border: 1px solid #DD7850;
}
.audio-icon {
width: 2rem;
height: 2rem;
background-image: url('https://cdn.ipadbiz.cn/bieyuan/map/icon/audio_icon.png'); /* 使用上传的图标 */
background-size: cover;
&.click {
animation: pulse 1.5s infinite;
}
}
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.2);
}
100% {
transform: scale(1);
}
}
}
}
}
}
</style>
<!--
* @Date: 2023-05-19 14:54:27
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-09-20 16:14:21
* @LastEditTime: 2024-09-20 17:45:35
* @FilePath: /map-demo/src/views/bieyuan/map.vue
* @Description: 公众地图主体页面
-->
......@@ -56,6 +56,8 @@
<van-dialog v-model:show="dialog_show" title="温馨提示">
<div style="padding: 1rem; text-align: center;">{{ dialog_text }}</div>
</van-dialog>
<!-- <audioBackground></audioBackground> -->
</div>
</template>
......@@ -70,6 +72,9 @@ import { useRect } from '@vant/use';
import { mapAPI } from '@/api/map.js'
import wx from 'weixin-js-sdk'
import pageInfo from '@/views/bieyuan/info.vue'
import audioBackground from '@/components/audioBackground'
import { mapState, mapActions } from 'pinia'
import { mainStore } from '@/store'
const GPS = {
PI: 3.14159265358979324,
......@@ -128,7 +133,7 @@ const GPS = {
};
export default {
components: { pageInfo },
components: { pageInfo, audioBackground },
data() {
return {
map: '',
......@@ -257,7 +262,11 @@ export default {
// deep: true // 如果 query 是嵌套对象,可以设置 deep 监听深层变化
// }
},
computed: {
...mapState(mainStore, ['audio_entity', 'audio_src', 'audio_status'])
},
methods: {
...mapActions(mainStore, ['changeAudio', 'changeAudioSrc', 'changeAudioStatus']),
initMap() {
// 初始化地图
this.map = new AMap.Map('container', {
......@@ -609,6 +618,10 @@ export default {
// // 浮动面板样式
// $('.van-floating-panel__content').css('borderRadius', '0');
// this.showClose = true;
// 清空设置
// this.changeAudio('');
// this.changeAudioStatus('pause');
//
this.$router.push({
path: '/bieyuan/info',
query: {
......
<!--
* @Date: 2023-05-19 14:54:27
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2024-09-12 16:28:53
* @LastEditTime: 2024-09-20 16:30:49
* @FilePath: /map-demo/src/views/index.vue
* @Description: 公众地图主体页面
-->
......