最近很火的 倒放挑战 - ReverseVoice (微信小程序版 前后端源码)
项目地址:?https://github.com/smackgg/reversevoice 整个项目其实很简单,从本人在抖音和 B 站看到火起来到最终小程序上线也就几天的下班时间就搞定了,11月16日上线至今用户量还是蛮多的(主要当时做的快此类 app 比较少),现在已经出现了大量的更简约更好的倒放挑战 app,本项目开源仅供大家学习~ 拥抱 TypeScript ~ 顺便小声吐槽一下 Taro 对 Ts 的支持还是不够啊,希望大家多去给 Taro 提 dts 的 PR ~ 体验小程序二维码挑战分享海报 (这个海报暂时有问题,修复代码因为资质问题还没有提交审核)
功能介绍/实现原理
使用 ffmpeg 进行音频倒放,核心代码:
小程序录音使用官方 api,详细逻辑见?./wechatapp/pages/index/index.tsx 录音
利用 canvas 动态合成分享海报?/wechatapp/pages/sharePoster ,mask: true,})
// 获取图片信息
const [productImgInfo,qrcodeImgInfo] = await Promise.all([
this.getImageInfo(sharePoster),// 获取主图
this.getQrImgInfo(),136); font-style: italic;">// 获取二维码图片
])
// product image 宽高
const pW = CANVAS_WIDTH
const pH = (pW / productImgInfo.width) * productImgInfo.height
// canvas 高度
let canvasHeight = pH
const ctx = Taro.createCanvasContext('canvas',null)
ctx.fillStyle = '#fff'
ctx.fillRect(0,0,CANVAS_WIDTH,canvasHeight)
// 绘制背景图片
ctx.drawImage(sharePoster,pW,pH)
// 绘制二维码 (因为有角度,需要旋转画布,再旋转回来)
ctx.rotate(-Math.PI / 32)
ctx.translate(-25 * ratio,10 * ratio)
ctx.drawImage(qrcodeImgInfo.path,QR_LEFT,QR_TOP,QR_WIDTH,QR_WIDTH)
ctx.rotate(Math.PI / 32)
this.setState({
canvasStyle: {
...this.state.canvasStyle,height: canvasHeight,},})
ctx.stroke()
setTimeout(() => {
Taro.hideLoading()
ctx.draw()
},500)
}
import Taro from '@tarojs/taro'
import { connect } from '@tarojs/redux';
import defaultShareImg from '@/assets/images/share.png'
type Options = {
title?: string
imageUrl?: string
path?: string
}
const defalutOptions: Options = {
title: '你能听懂我说啥么?最近很火的反转录音来啦~',imageUrl: defaultShareImg,path: 'pages/index/index',}
function withShare() {
return function demoComponent(Component: ComponentClass) {
@connect(({ user }) => ({
userInfo: user.userInfo
}))
class WithShare extends Component {
$shareOptions?: Options
async componentWillMount() {
Taro.showShareMenu({
withShareTicket: true,})
if (super.componentWillMount) {
super.componentWillMount()
}
}
// 点击分享的那一刻会进行调用
onShareAppMessage() {
// const sharePath = `${path}&shareFromUser=${userInfo.shareId}`
let options = defalutOptions
if (this.$shareOptions) {
options = {
...defalutOptions,...this.$shareOptions,}
}
return options
}
render() {
return super.render()
}
}
return WithShare
}
}
export default withShare
使用 @withShare()
class Room extends Component {
/**
* 指定config的类型声明为: Taro.Config
*
* 由于 typescript 对于 object 类型推导只能推出 Key 的基本类型
* 对于像 navigationBarTextStyle: 'black' 这样的推导出的类型是 string
* 提示和声明 navigationBarTextStyle: 'black' | 'white' 类型冲突,需要显示声明类型
*/
config: Config = {
navigationBarTitleText: '首页',}
$shareOptions = {
title: '倒放挑战!你能听懂我倒立洗头~',imageUrl: '',}
/**
....
*/
}
微信官方文档登录流程 项目运行 - 后端准备需要提前安装:
开始
npm?install
npm run build
npm start
项目运行 - 小程序端cd?wechatapp
在 wechatapp/src/utils 目录下克隆 env.example.ts 文件至同目录命名为 .env.ts 文件
此文件两个参数分别代表本地开发和线上部署的请求地址
npm run dev:weapp // development mode
或者 npm run build:weapp // production mode
选择导入项目,并选择 wechatapp/dist 目录
若本地开发,需要在开发者工具中设置开启“不校验合法域名“
LicenseMIT (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |