diff --git a/components/audio-overlay/audio-overlay.js b/components/audio-overlay/audio-overlay.js
new file mode 100644
index 0000000..c24e83b
--- /dev/null
+++ b/components/audio-overlay/audio-overlay.js
@@ -0,0 +1,114 @@
+// 音频播放蒙层组件
+Component({
+ properties: {
+ // 是否显示蒙层
+ isPlaying: {
+ type: Boolean,
+ value: false
+ },
+ // 播放的文本内容
+ audioText: {
+ type: String,
+ value: ''
+ }
+ },
+
+ data: {
+ progress: 0, // 播放进度百分比
+ currentTime: '00:00', // 当前播放时间
+ duration: '00:00', // 总时长
+ timer: null // 定时器
+ },
+
+ lifetimes: {
+ detached() {
+ // 组件销毁时清理定时器
+ this.clearTimer();
+ }
+ },
+
+ methods: {
+ // 初始化音频监听
+ initAudio(audioContext) {
+ if (!audioContext) return;
+
+ this.audioContext = audioContext;
+
+ // 监听音频播放进度
+ audioContext.onTimeUpdate(() => {
+ const currentTime = audioContext.currentTime || 0;
+ const duration = audioContext.duration || 0;
+
+ this.setData({
+ progress: duration > 0 ? (currentTime / duration) * 100 : 0,
+ currentTime: this.formatTime(currentTime),
+ duration: this.formatTime(duration)
+ });
+ });
+
+ // 监听播放结束
+ audioContext.onEnded(() => {
+ this.stopPlaying();
+ });
+
+ // 监听播放错误
+ audioContext.onError(() => {
+ this.stopPlaying();
+ });
+
+ // 监听播放停止
+ audioContext.onStop(() => {
+ this.stopPlaying();
+ });
+ },
+
+ // 格式化时间显示
+ formatTime(seconds) {
+ if (!seconds || isNaN(seconds)) return '00:00';
+
+ const mins = Math.floor(seconds / 60);
+ const secs = Math.floor(seconds % 60);
+ return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
+ },
+
+ // 停止播放
+ stopPlaying() {
+ this.setData({
+ progress: 0,
+ currentTime: '00:00',
+ duration: '00:00'
+ });
+
+ this.clearTimer();
+
+ // 触发父组件的停止事件
+ this.triggerEvent('stop');
+ },
+
+ // 清理定时器
+ clearTimer() {
+ if (this.data.timer) {
+ clearInterval(this.data.timer);
+ this.setData({
+ timer: null
+ });
+ }
+ },
+
+ // 点击蒙层背景
+ onOverlayTap() {
+ // 点击背景关闭蒙层并停止播放
+ this.stopPlaying();
+ },
+
+ // 点击停止按钮
+ onStopTap() {
+ this.stopPlaying();
+ },
+
+ // 阻止事件冒泡
+ stopPropagation() {
+ // 阻止点击内容区域时触发背景点击事件
+ }
+ }
+});
\ No newline at end of file
diff --git a/components/audio-overlay/audio-overlay.json b/components/audio-overlay/audio-overlay.json
new file mode 100644
index 0000000..e8cfaaf
--- /dev/null
+++ b/components/audio-overlay/audio-overlay.json
@@ -0,0 +1,4 @@
+{
+ "component": true,
+ "usingComponents": {}
+}
\ No newline at end of file
diff --git a/components/audio-overlay/audio-overlay.wxml b/components/audio-overlay/audio-overlay.wxml
new file mode 100644
index 0000000..d99655c
--- /dev/null
+++ b/components/audio-overlay/audio-overlay.wxml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{audioText}}
+
+
+
+
+ {{currentTime}} / {{duration}}
+
+
+
+
\ No newline at end of file
diff --git a/components/audio-overlay/audio-overlay.wxss b/components/audio-overlay/audio-overlay.wxss
new file mode 100644
index 0000000..7f413c2
--- /dev/null
+++ b/components/audio-overlay/audio-overlay.wxss
@@ -0,0 +1,117 @@
+/* 音频播放蒙层样式 */
+.audio-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100vw;
+ height: 100vh;
+ background: rgba(0, 0, 0, 0.7);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 9999;
+}
+
+.overlay-content {
+ background: white;
+ border-radius: 16rpx;
+ padding: 60rpx 40rpx;
+ margin: 40rpx;
+ text-align: center;
+ min-width: 500rpx;
+ box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.2);
+}
+
+.audio-icon {
+ margin-bottom: 40rpx;
+}
+
+.sound-wave {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8rpx;
+ height: 80rpx;
+}
+
+.wave {
+ width: 6rpx;
+ background: #1296db;
+ border-radius: 3rpx;
+ animation: wave 1.5s ease-in-out infinite;
+}
+
+.wave:nth-child(1) {
+ height: 20rpx;
+ animation-delay: 0s;
+}
+
+.wave:nth-child(2) {
+ height: 40rpx;
+ animation-delay: 0.1s;
+}
+
+.wave:nth-child(3) {
+ height: 60rpx;
+ animation-delay: 0.2s;
+}
+
+.wave:nth-child(4) {
+ height: 40rpx;
+ animation-delay: 0.3s;
+}
+
+@keyframes wave {
+ 0%, 100% {
+ transform: scaleY(1);
+ }
+ 50% {
+ transform: scaleY(1.5);
+ }
+}
+
+.audio-text {
+ font-size: 32rpx;
+ color: #333;
+ margin-bottom: 40rpx;
+ line-height: 1.4;
+ max-height: 200rpx;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ display: -webkit-box;
+ -webkit-line-clamp: 3;
+ -webkit-box-orient: vertical;
+}
+
+.progress-container {
+ margin-bottom: 40rpx;
+}
+
+.progress-bar {
+ width: 100%;
+ height: 8rpx;
+ background: #f0f0f0;
+ border-radius: 4rpx;
+ overflow: hidden;
+ margin-bottom: 16rpx;
+}
+
+.progress-fill {
+ height: 100%;
+ background: #1296db;
+ transition: width 0.3s ease;
+}
+
+.time-info {
+ font-size: 24rpx;
+ color: #666;
+}
+
+.stop-btn {
+ background: #ff4757;
+ color: white;
+ border: none;
+ border-radius: 50rpx;
+ padding: 20rpx 60rpx;
+ font-size: 30rpx;
+}
\ No newline at end of file
diff --git a/pages/index/index.js b/pages/index/index.js
index aa50d1a..59c4c69 100644
--- a/pages/index/index.js
+++ b/pages/index/index.js
@@ -12,7 +12,9 @@ Page({
placeholder: '点击此处输入文字',
text: '',
typeList,
- selectedIndex: String(selectedIndex) ? selectedIndex : 0
+ selectedIndex: String(selectedIndex) ? selectedIndex : 0,
+ isAudioPlaying: false,
+ currentAudioText: ''
},
onLoad(){
wx.showShareMenu();
@@ -141,6 +143,20 @@ Page({
audio = wx.createInnerAudioContext({useWebAudioImplement: true});
audio.autoplay = true;
+ // 显示播放蒙层
+ this.setData({
+ isAudioPlaying: true,
+ currentAudioText: text
+ });
+
+ // 初始化蒙层组件的音频监听
+ setTimeout(() => {
+ const overlayComponent = this.selectComponent('audio-overlay');
+ if (overlayComponent) {
+ overlayComponent.initAudio(audio);
+ }
+ }, 100);
+
// 检查是否播放过
const audioList = app.globalData.getAudioList();
let played = audioList.find(v => v.text === text && v.type === type);
@@ -153,6 +169,7 @@ Page({
// 播放失败要移除缓存内容
audio.onError(err => {
app.globalData.setAudioList('delete', played.path);
+ this.setData({ isAudioPlaying: false });
wx.showModal({
title: '提示',
content: '该语音播放过但缓存失效,点击确定重新播放',
@@ -189,6 +206,7 @@ Page({
// 不合规结束
if(result.suggest !== 'pass'){
wx.hideLoading();
+ this.setData({ isAudioPlaying: false });
return wx.showToast({
title: '内容不合规',
icon: 'error',
@@ -221,6 +239,7 @@ Page({
fail(err) {
console.log(err);
wx.hideLoading();
+ this.setData({ isAudioPlaying: false });
wx.showToast({
title: '下载失败',
icon: 'none'
@@ -229,6 +248,7 @@ Page({
});
} catch (error) {
wx.hideLoading();
+ this.setData({ isAudioPlaying: false });
// TTS接口调用失败的错误已经在app.js中处理了
}
},
@@ -243,6 +263,15 @@ Page({
audio.destroy();
audio = null;
}
+ this.setData({
+ isAudioPlaying: false,
+ currentAudioText: ''
+ });
+ },
+
+ // 音频停止播放的回调
+ onAudioStop() {
+ this.resetAudio();
},
selectIndex(e){
const { index } = e.target.dataset;
diff --git a/pages/index/index.json b/pages/index/index.json
index 9e26dfe..e273712 100644
--- a/pages/index/index.json
+++ b/pages/index/index.json
@@ -1 +1,5 @@
-{}
\ No newline at end of file
+{
+ "usingComponents": {
+ "audio-overlay": "../../components/audio-overlay/audio-overlay"
+ }
+}
\ No newline at end of file
diff --git a/pages/index/index.wxml b/pages/index/index.wxml
index f005480..3c364f9 100644
--- a/pages/index/index.wxml
+++ b/pages/index/index.wxml
@@ -28,5 +28,13 @@
> {{item.desc}}
+
+
+
+
\ No newline at end of file
diff --git a/pages/result/result.js b/pages/result/result.js
index aabb334..3e298fd 100644
--- a/pages/result/result.js
+++ b/pages/result/result.js
@@ -16,7 +16,9 @@ let formateDate = function (audioList) {
Page({
data: {
- audioList: formateDate(app.globalData.getAudioList())
+ audioList: formateDate(app.globalData.getAudioList()),
+ isAudioPlaying: false,
+ currentAudioText: ''
},
onLoad(options){
this.setData({
@@ -33,8 +35,24 @@ Page({
audio = wx.createInnerAudioContext({useWebAudioImplement: true});
audio.autoplay = true;
audio.src = target.path;
+
+ // 显示播放蒙层
+ this.setData({
+ isAudioPlaying: true,
+ currentAudioText: target.text
+ });
+
+ // 初始化蒙层组件的音频监听
+ setTimeout(() => {
+ const overlayComponent = this.selectComponent('audio-overlay');
+ if (overlayComponent) {
+ overlayComponent.initAudio(audio);
+ }
+ }, 100);
+
// 播放失败要移除缓存内容
audio.onError(err => {
+ this.setData({ isAudioPlaying: false });
wx.showModal({
title: '提示',
content: '该语音缓存失效,点击确定删除',
@@ -80,5 +98,14 @@ Page({
audio.destroy();
audio = null;
}
+ this.setData({
+ isAudioPlaying: false,
+ currentAudioText: ''
+ });
+ },
+
+ // 音频停止播放的回调
+ onAudioStop() {
+ this.resetAudio();
}
});
\ No newline at end of file
diff --git a/pages/result/result.json b/pages/result/result.json
index 9e26dfe..e273712 100644
--- a/pages/result/result.json
+++ b/pages/result/result.json
@@ -1 +1,5 @@
-{}
\ No newline at end of file
+{
+ "usingComponents": {
+ "audio-overlay": "../../components/audio-overlay/audio-overlay"
+ }
+}
\ No newline at end of file
diff --git a/pages/result/result.wxml b/pages/result/result.wxml
index c8dd4d2..bb0803f 100644
--- a/pages/result/result.wxml
+++ b/pages/result/result.wxml
@@ -16,4 +16,11 @@
-
\ No newline at end of file
+
+
+
+
\ No newline at end of file