Commit 906191f76e79e942ac6ebd27dcb32d247588d059

Authored by xwenliang
1 parent fbe86a2d

feat: add entry

README.md
1 1 # 微信小程序 - 语音助手
2 2  
3   -## todo
  3 +### todo
4 4  
5   -1. 历史记录
6 5 \ No newline at end of file
  6 +- [x] 内容安全问题处理
  7 +
  8 +- [x] 下载音频需求
  9 + - 无直接下载接口,可通过 webview 间接实现
  10 + - 个人类小程序不支持 web-view
  11 + - wx.shareFileMessage 可以直接分享文件
... ...
1 1 //app.js
2 2 App({
3   - onLaunch: function() {
  3 + onLaunch () {
4 4  
5 5 },
6   - getUserInfo: function(cb) {
7   - var that = this
8   - if (this.globalData.userInfo) {
9   - typeof cb == "function" && cb(this.globalData.userInfo)
10   - } else {
11   - //调用登录接口
12   - wx.login({
13   - success: function() {
14   - wx.getUserInfo({
15   - success: function(res) {
16   - that.globalData.userInfo = res.userInfo
17   - typeof cb == "function" && cb(that.globalData.userInfo)
18   - }
19   - })
  6 + globalData: {
  7 + getTypeList(){
  8 + return [
  9 + {
  10 + desc: '男声一',
  11 + createUrl(text){
  12 + return `https://fanyi.sogou.com/reventondc/synthesis?text=${text}&speed=1&lang=zh-CHS&from=translateweb&speaker=1`
  13 + }
  14 + },
  15 + {
  16 + desc: '男声二',
  17 + createUrl(text){
  18 + return `https://fanyi.sogou.com/reventondc/synthesis?text=${text}&speed=1&lang=zh-CHS&from=translateweb&speaker=4`
  19 + }
  20 + },
  21 + {
  22 + desc: '女声一',
  23 + createUrl(text){
  24 + return `https://fanyi.sogou.com/reventondc/synthesis?text=${text}&speed=1&lang=zh-CHS&from=translateweb&speaker=2`
  25 + }
  26 + },
  27 + {
  28 + desc: '女声二',
  29 + createUrl(text){
  30 + return `https://fanyi.sogou.com/reventondc/synthesis?text=${text}&speed=1&lang=zh-CHS&from=translateweb&speaker=3`
  31 + }
  32 + },
  33 + {
  34 + desc: '女声三',
  35 + createUrl(text){
  36 + return `https://fanyi.sogou.com/reventondc/synthesis?text=${text}&speed=1&lang=zh-CHS&from=translateweb&speaker=5`
  37 + }
  38 + },
  39 + {
  40 + desc: '女声四',
  41 + createUrl(text){
  42 + return `https://fanyi.sogou.com/reventondc/synthesis?text=${text}&speed=1&lang=zh-CHS&from=translateweb&speaker=6`
  43 + }
  44 + },
  45 + {
  46 + desc: '女声五',
  47 + createUrl(text){
  48 + return `https://tts.youdao.com/fanyivoice?word=${text}&le=zh&keyfrom=speaker-target`
  49 + }
20 50 }
21   - })
  51 + ];
  52 + },
  53 + getSelectedTypeIndex(){
  54 + const storageKey = 'audioTypeselectedIndex';
  55 + return wx.getStorageSync(storageKey);
  56 + },
  57 + setSelectedTypeIndex(index){
  58 + const storageKey = 'audioTypeselectedIndex';
  59 + wx.setStorageSync(storageKey, index);
  60 + return index;
  61 + },
  62 + getAudioList(){
  63 + const storageKey = 'audioList';
  64 + return wx.getStorageSync(storageKey) || [];
  65 + },
  66 + /**
  67 + * @param {(add|delete)} action - 增或删
  68 + * @param {object|number} [param] - 增加时是 audio 描述,删除时是索引
  69 + */
  70 + setAudioList(action, param){
  71 + const storageKey = 'audioList';
  72 + const list = this.getAudioList() || [];
  73 + if(action === 'add' && param.constructor === Object){
  74 + list.push(param);
  75 + wx.setStorageSync(storageKey, list);
  76 + }
  77 + if(action === 'delete' && String(param)){
  78 + list.splice(param, 1);
  79 + wx.setStorageSync(storageKey, list);
  80 + }
  81 + return list;
22 82 }
23   - },
24   - globalData: {
25   - userInfo: null
26 83 }
27 84 });
... ...
pages/index/index.js
1 1 //index.js
2 2 //获取应用实例
3 3 const app = getApp();
4   -const storageKey = 'audioTypeselectedIndex';
5   -const selectedIndex = wx.getStorageSync(storageKey);
6   -const type = [
7   - {
8   - desc: '男声一',
9   - createUrl(text){
10   - return `https://fanyi.sogou.com/reventondc/synthesis?text=${text}&speed=1&lang=zh-CHS&from=translateweb&speaker=1`
11   - }
12   - },
13   - {
14   - desc: '男声二',
15   - createUrl(text){
16   - return `https://fanyi.sogou.com/reventondc/synthesis?text=${text}&speed=1&lang=zh-CHS&from=translateweb&speaker=4`
17   - }
18   - },
19   - {
20   - desc: '女声一',
21   - createUrl(text){
22   - return `https://fanyi.sogou.com/reventondc/synthesis?text=${text}&speed=1&lang=zh-CHS&from=translateweb&speaker=2`
23   - }
24   - },
25   - {
26   - desc: '女声二',
27   - createUrl(text){
28   - return `https://fanyi.sogou.com/reventondc/synthesis?text=${text}&speed=1&lang=zh-CHS&from=translateweb&speaker=3`
29   - }
30   - },
31   - {
32   - desc: '女声三',
33   - createUrl(text){
34   - return `https://fanyi.sogou.com/reventondc/synthesis?text=${text}&speed=1&lang=zh-CHS&from=translateweb&speaker=5`
35   - }
36   - },
37   - {
38   - desc: '女声四',
39   - createUrl(text){
40   - return `https://fanyi.sogou.com/reventondc/synthesis?text=${text}&speed=1&lang=zh-CHS&from=translateweb&speaker=6`
41   - }
42   - },
43   - {
44   - desc: '女声五',
45   - createUrl(text){
46   - return `https://tts.youdao.com/fanyivoice?word=${text}&le=zh&keyfrom=speaker-target`
47   - }
48   - }
49   -];
  4 +const selectedIndex = app.globalData.getSelectedTypeIndex();
  5 +const type = app.globalData.getTypeList();
50 6  
51 7 let audio = null;
52 8  
... ... @@ -65,10 +21,34 @@ Page({
65 21 },
66 22 play(){
67 23 const text = this.data.text || this.data.placeholder;
  24 + const url = this.data.type[this.data.selectedIndex].createUrl(text);
68 25 this.resetAudio();
69 26 audio = wx.createInnerAudioContext({useWebAudioImplement: true});
70 27 audio.autoplay = true;
71   - audio.src = this.data.type[this.data.selectedIndex].createUrl(text);
  28 + // 检查是否播放过
  29 + const audioList = app.globalData.getAudioList();
  30 + const playedIndex = audioList.findIndex(v => v.url === url);
  31 + // 播放过,使用本地文件减少请求
  32 + if(playedIndex > -1){
  33 + return audio.src = audioList[playedIndex].path;
  34 + }
  35 + // 未播放过,先下载再播放
  36 + wx.downloadFile({
  37 + url,
  38 + success (res) {
  39 + audio.src = res.tempFilePath;
  40 + app.globalData.setAudioList('add', {
  41 + // 音频文本
  42 + text,
  43 + // 音频网络地址
  44 + url,
  45 + // 音频本地地址
  46 + path: res.tempFilePath,
  47 + // 音频创建时间
  48 + time: Date.now()
  49 + });
  50 + }
  51 + });
72 52 },
73 53 clear(){
74 54 this.resetAudio();
... ... @@ -89,6 +69,11 @@ Page({
89 69 }, () => {
90 70 this.play();
91 71 });
92   - wx.setStorageSync(storageKey, index);
  72 + app.globalData.setSelectedTypeIndex(index);
  73 + },
  74 + gotoAudioList(){
  75 + wx.navigateTo({
  76 + url: '/pages/result/result'
  77 + });
93 78 }
94 79 });
... ...
pages/index/index.wxml
... ... @@ -13,6 +13,7 @@
13 13 </view>
14 14 <view class="button-view">
15 15 <button bindtap="play" class="button" type="primary" size="mini"> 播放 </button>
  16 + <button bindtap="gotoAudioList" class="goto-audio-list" type="primary" size="mini"> 下载 </button>
16 17 <button bindtap="clear" class="button" type="default" size="mini"> 清空 </button>
17 18 </view>
18 19 <view class="type-view">
... ...
pages/result/result.js
... ... @@ -2,7 +2,6 @@
2 2 import { convertDate } from '../../utils/util.js';
3 3 //获取应用实例
4 4 const app = getApp();
5   -const audioList = app.globalData.getAudioList();
6 5 const type = app.globalData.getTypeList();
7 6  
8 7 let audio = null;
... ... @@ -17,10 +16,12 @@ let formateDate = function (audioList) {
17 16  
18 17 Page({
19 18 data: {
20   - audioList: formateDate(audioList)
  19 + audioList: formateDate(app.globalData.getAudioList())
21 20 },
22 21 onLoad (options) {
23   -
  22 + this.setData({
  23 + audioList: formateDate(app.globalData.getAudioList())
  24 + });
24 25 },
25 26 play(e){
26 27 const { index } = e.target.dataset;
... ...