├── .gitignore ├── pages ├── video │ ├── video.wxss │ ├── video.json │ ├── video.wxml │ └── video.js ├── logs │ ├── logs.json │ ├── logs.wxss │ ├── logs.wxml │ └── logs.js └── index │ ├── index.json │ ├── index.wxss │ ├── index.wxml │ └── index.js ├── qrcode_ms.jpg ├── sitemap.json ├── app.wxss ├── README.md ├── app.json ├── utils └── util.js └── app.js /.gitignore: -------------------------------------------------------------------------------- 1 | project.config.json -------------------------------------------------------------------------------- /pages/video/video.wxss: -------------------------------------------------------------------------------- 1 | 2 | page , .video{ 3 | width: 100%; 4 | height: 100%; 5 | } -------------------------------------------------------------------------------- /qrcode_ms.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ithere/douyin-meinv-miniapp/HEAD/qrcode_ms.jpg -------------------------------------------------------------------------------- /pages/video/video.json: -------------------------------------------------------------------------------- 1 | { 2 | "navigationBarTitleText": "视频播放", 3 | "usingComponents": {} 4 | } -------------------------------------------------------------------------------- /pages/logs/logs.json: -------------------------------------------------------------------------------- 1 | { 2 | "navigationBarTitleText": "查看启动日志", 3 | "usingComponents": {} 4 | } -------------------------------------------------------------------------------- /pages/index/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": {}, 3 | "navigationBarTitleText": "抖音美女视频", 4 | "enablePullDownRefresh": true 5 | } -------------------------------------------------------------------------------- /pages/video/video.wxml: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /pages/logs/logs.wxss: -------------------------------------------------------------------------------- 1 | .log-list { 2 | display: flex; 3 | flex-direction: column; 4 | padding: 40rpx; 5 | } 6 | .log-item { 7 | margin: 10rpx; 8 | } 9 | -------------------------------------------------------------------------------- /sitemap.json: -------------------------------------------------------------------------------- 1 | { 2 | "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html", 3 | "rules": [{ 4 | "action": "allow", 5 | "page": "*" 6 | }] 7 | } -------------------------------------------------------------------------------- /pages/logs/logs.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{index + 1}}. {{log}} 5 | 6 | 7 | -------------------------------------------------------------------------------- /app.wxss: -------------------------------------------------------------------------------- 1 | /**app.wxss**/ 2 | .container { 3 | height: 100%; 4 | display: flex; 5 | flex-direction: column; 6 | align-items: center; 7 | justify-content: space-between; 8 | padding: 200rpx 0; 9 | box-sizing: border-box; 10 | } 11 | -------------------------------------------------------------------------------- /pages/logs/logs.js: -------------------------------------------------------------------------------- 1 | //logs.js 2 | const util = require('../../utils/util.js') 3 | 4 | Page({ 5 | data: { 6 | logs: [] 7 | }, 8 | onLoad: function () { 9 | this.setData({ 10 | logs: (wx.getStorageSync('logs') || []).map(log => { 11 | return util.formatTime(new Date(log)) 12 | }) 13 | }) 14 | } 15 | }) 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 这是一个小程序文件夹 By mosou 2 | #### 视频列表小程序 大家下载后新建小程序 把文件夹内的内容 复制后替换新建的小程序目录内的内容 并勾选不校验合法域名, 否则不能调试获取到数据,小程序扫码的时候请在扫码打开后 点击右上方3个点 在点击开启调试模式,否则一样获取不到数据 3 | #### https://github.com/ithere/douyin-meinv-miniapp.git 克隆地址 4 | #### https://github.com/ithere/douyin-meinv-miniapp 5 | ![mosousuo](https://github.com/ithere/douyindownload-miniapp/blob/master/qrcode_ms.jpg) 6 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages": [ 3 | "pages/index/index", 4 | "pages/logs/logs", 5 | "pages/video/video" 6 | ], 7 | "window": { 8 | "backgroundTextStyle": "light", 9 | "navigationBarBackgroundColor": "#fff", 10 | "navigationBarTitleText": "mosousuo", 11 | "navigationBarTextStyle": "black" 12 | }, 13 | "sitemapLocation": "sitemap.json" 14 | } -------------------------------------------------------------------------------- /utils/util.js: -------------------------------------------------------------------------------- 1 | const formatTime = date => { 2 | const year = date.getFullYear() 3 | const month = date.getMonth() + 1 4 | const day = date.getDate() 5 | const hour = date.getHours() 6 | const minute = date.getMinutes() 7 | const second = date.getSeconds() 8 | 9 | return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':') 10 | } 11 | 12 | const formatNumber = n => { 13 | n = n.toString() 14 | return n[1] ? n : '0' + n 15 | } 16 | 17 | module.exports = { 18 | formatTime: formatTime 19 | } 20 | -------------------------------------------------------------------------------- /pages/index/index.wxss: -------------------------------------------------------------------------------- 1 | /**index.wxss**/ 2 | .userinfo { 3 | display: flex; 4 | flex-direction: column; 5 | align-items: center; 6 | } 7 | 8 | .userinfo-avatar { 9 | width: 128rpx; 10 | height: 128rpx; 11 | margin: 20rpx; 12 | border-radius: 50%; 13 | } 14 | 15 | .userinfo-nickname { 16 | color: #aaa; 17 | } 18 | 19 | .usermotto { 20 | margin-top: 200px; 21 | } 22 | /* pages/douyin/douyinLike/douyinLike.wxss */ 23 | .conetnt { 24 | margin: 0 auto; 25 | float: left; 26 | text-align: center; 27 | } 28 | .conetnt video,image { 29 | height: 380rpx; 30 | width: 250rpx; 31 | } -------------------------------------------------------------------------------- /pages/index/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 52PJ: mosou 喜欢请给个Star 谢谢 24 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | //app.js 2 | App({ 3 | onLaunch: function () { 4 | // 展示本地存储能力 5 | var logs = wx.getStorageSync('logs') || [] 6 | logs.unshift(Date.now()) 7 | wx.setStorageSync('logs', logs) 8 | this.globalData.getUrl = 'https://abc.mosousuo.com/api/douyinApi/getUrl' 9 | this.globalData.url = 'https://ithere.github.io' 10 | // 登录 11 | wx.login({ 12 | success: res => { 13 | // 发送 res.code 到后台换取 openId, sessionKey, unionId 14 | } 15 | }) 16 | // 获取用户信息 17 | wx.getSetting({ 18 | success: res => { 19 | if (res.authSetting['scope.userInfo']) { 20 | // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 21 | wx.getUserInfo({ 22 | success: res => { 23 | // 可以将 res 发送给后台解码出 unionId 24 | this.globalData.userInfo = res.userInfo 25 | 26 | // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 27 | // 所以此处加入 callback 以防止这种情况 28 | if (this.userInfoReadyCallback) { 29 | this.userInfoReadyCallback(res) 30 | } 31 | } 32 | }) 33 | } 34 | } 35 | }) 36 | }, 37 | globalData: { 38 | userInfo: null, 39 | url: '', 40 | getUrl: '' 41 | } 42 | }) -------------------------------------------------------------------------------- /pages/video/video.js: -------------------------------------------------------------------------------- 1 | // pages/video/video.js 2 | Page({ 3 | 4 | /** 5 | * 页面的初始数据 6 | */ 7 | data: { 8 | url: '', 9 | isFirst: true 10 | 11 | }, 12 | 13 | /** 14 | * 生命周期函数--监听页面加载 15 | */ 16 | onLoad: function (options) { 17 | this.setData({ 18 | url: options.url 19 | }) 20 | }, 21 | 22 | onplay: function () { 23 | if (this.data.isFirst) { 24 | let videoContext = wx.createVideoContext('myVideo'); 25 | videoContext.requestFullScreen(); 26 | this.setData({ 27 | isFirst: false 28 | }); 29 | } 30 | }, 31 | /** 32 | * 生命周期函数--监听页面初次渲染完成 33 | */ 34 | onReady: function () { 35 | 36 | }, 37 | 38 | /** 39 | * 生命周期函数--监听页面显示 40 | */ 41 | onShow: function () { 42 | 43 | }, 44 | 45 | /** 46 | * 生命周期函数--监听页面隐藏 47 | */ 48 | onHide: function () { 49 | 50 | }, 51 | 52 | /** 53 | * 生命周期函数--监听页面卸载 54 | */ 55 | onUnload: function () { 56 | 57 | }, 58 | 59 | /** 60 | * 页面相关事件处理函数--监听用户下拉动作 61 | */ 62 | onPullDownRefresh: function () { 63 | 64 | }, 65 | 66 | /** 67 | * 页面上拉触底事件的处理函数 68 | */ 69 | onReachBottom: function () { 70 | 71 | }, 72 | 73 | /** 74 | * 用户点击右上角分享 75 | */ 76 | onShareAppMessage: function () { 77 | 78 | } 79 | }) -------------------------------------------------------------------------------- /pages/index/index.js: -------------------------------------------------------------------------------- 1 | //index.js 2 | //获取应用实例 3 | const app = getApp() 4 | 5 | Page({ 6 | data: { 7 | userInfo: {}, 8 | hasUserInfo: false, 9 | canIUse: wx.canIUse('button.open-type.getUserInfo'), 10 | downloadRes: '', 11 | douyinData: '', 12 | getUrl: app.globalData.getUrl, 13 | url: app.globalData.url, 14 | page: 1, 15 | retData: [] 16 | }, 17 | 18 | onLoad: function (option) { 19 | 20 | const that = this 21 | that.getDouyinData() 22 | return 23 | if (app.globalData.userInfo) { 24 | this.setData({ 25 | userInfo: app.globalData.userInfo, 26 | hasUserInfo: true 27 | }) 28 | } else if (this.data.canIUse) { 29 | // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 30 | // 所以此处加入 callback 以防止这种情况 31 | app.userInfoReadyCallback = res => { 32 | this.setData({ 33 | userInfo: res.userInfo, 34 | hasUserInfo: true 35 | }) 36 | } 37 | } else { 38 | // 在没有 open-type=getUserInfo 版本的兼容处理 39 | wx.getUserInfo({ 40 | success: res => { 41 | app.globalData.userInfo = res.userInfo 42 | this.setData({ 43 | userInfo: res.userInfo, 44 | hasUserInfo: true 45 | }) 46 | } 47 | }) 48 | } 49 | }, 50 | getUserInfo: function (e) { 51 | console.log(e) 52 | app.globalData.userInfo = e.detail.userInfo 53 | this.setData({ 54 | userInfo: e.detail.userInfo, 55 | hasUserInfo: true 56 | }) 57 | }, 58 | wxOnDownFile: function (url) { 59 | const that = this 60 | const downloadTask = wx.downloadFile({ 61 | url: url, 62 | filePath: '', 63 | success: (res) => { 64 | that.setData({ 65 | downloadRes: res 66 | }) 67 | that.downSuccess() 68 | } 69 | }) 70 | }, 71 | downSuccess: function () { 72 | const that = this 73 | wx.hideLoading() 74 | wx.saveVideoToPhotosAlbum({ 75 | filePath: that.data.downloadRes.tempFilePath, 76 | success: function (res) { 77 | wx.showToast({ 78 | title: '保存成功', 79 | }) 80 | } 81 | }) 82 | return 83 | }, 84 | getRand: function () { 85 | const that = this 86 | const num = Math.ceil(Math.random() * 10) 87 | if (!num) { 88 | that.getRand() 89 | } 90 | return num 91 | }, 92 | getDouyinData: function (url = '') { 93 | wx.showLoading({ 94 | title: '正在加载,请稍后...', 95 | }); 96 | wx.showNavigationBarLoading(); 97 | const that = this 98 | // var num = that.getRand() - 0 99 | // console.log("num:" + num); 100 | url = that.data.url 101 | wx.request({ 102 | url: url + '/open/douyin/likeData/' + (201900000000000 + this.data.page), 103 | success: function (data) { 104 | wx.hideLoading(); 105 | wx.hideNavigationBarLoading(); 106 | if (that.data.page == 1) { 107 | wx.stopPullDownRefresh(); 108 | } 109 | const retData = data.data 110 | if (retData.aweme_list.length) { 111 | let douyinData = []; 112 | if (that.data.page == 1) { 113 | douyinData = retData.aweme_list; 114 | } else { 115 | douyinData = that.data.douyinData.concat(retData.aweme_list); 116 | } 117 | that.setData({ 118 | douyinData: douyinData, 119 | retData: retData.aweme_list 120 | }) 121 | } else { 122 | that.setData({ 123 | retData: [] 124 | }) 125 | setTimeout(() => { 126 | that.getDouyinData(url) 127 | }, 300) 128 | return 129 | } 130 | }, 131 | fail: function (err) { 132 | wx.hideLoading(); 133 | wx.hideNavigationBarLoading(); 134 | } 135 | }) 136 | }, 137 | itemClick: function (e = '') { 138 | const that = this 139 | var shortUrl = e.currentTarget.dataset.url 140 | if (!shortUrl) { 141 | return 142 | } 143 | wx.request({ 144 | url: that.data.getUrl, 145 | method: 'POST', 146 | header: { 147 | 'Content-Type': 'application/x-www-form-urlencoded' 148 | }, 149 | data: { 150 | url: encodeURIComponent(shortUrl) 151 | }, 152 | success: function (data) { 153 | if (data.data) { 154 | wx.showLoading({ 155 | title: '正在下载', 156 | mask: true 157 | }) 158 | wx.navigateTo({ 159 | url: '/pages/video/video?url=' + data.data, 160 | }) 161 | } 162 | } 163 | }) 164 | }, 165 | douyinApi: function (e = '') { 166 | const that = this 167 | var shortUrl = e.currentTarget.dataset.url 168 | if (!shortUrl) { 169 | return 170 | } 171 | wx.request({ 172 | url: that.data.getUrl, 173 | method: 'POST', 174 | header: { 175 | 'Content-Type': 'application/x-www-form-urlencoded' 176 | }, 177 | data: { 178 | url: encodeURIComponent(shortUrl) 179 | }, 180 | success: function (data) { 181 | if (data.data) { 182 | wx.showLoading({ 183 | title: '正在下载', 184 | mask: true 185 | }) 186 | that.wxOnDownFile(data.data) 187 | } 188 | } 189 | }) 190 | 191 | }, 192 | /** 193 | * 生命周期函数--监听页面隐藏 194 | */ 195 | onHide: function () { 196 | wx.hideLoading() 197 | this.setData({ 198 | isClose: true 199 | }) 200 | }, 201 | 202 | /** 203 | * 生命周期函数--监听页面卸载 204 | */ 205 | onUnload: function () { 206 | wx.hideLoading() 207 | this.setData({ 208 | isClose: true 209 | }) 210 | }, 211 | onPullDownRefresh: function () { 212 | this.data.page = 1; 213 | this.getDouyinData(); 214 | }, 215 | onReachBottom: function () { 216 | if (this.data.retData.length) { 217 | this.data.page++; 218 | this.getDouyinData(); 219 | } else { 220 | wx.showToast({ 221 | title: '没有更多数据了', 222 | icon: "none" 223 | }) 224 | } 225 | 226 | } 227 | }) --------------------------------------------------------------------------------