分享一个uniapp开发的微信小程序免费《短视频去水印》小程序
html
<template>
<view class="content">
<view class="area-wrap">
<textarea name="" v-model="state.content" maxlength="800" id="" cols="30" rows="10" placeholder-class="plc"
placeholder="请输入分享链接/分享内容"></textarea>
<view class="count">
{{state.content.length}}/800
</view>
</view>
<uv-row customStyle="margin-bottom: 10px" justify="end">
<uv-col span="3">
<uv-button :text="state.content?'清空':'粘贴'" @click="clearOrpaste"></uv-button>
</uv-col>
<uv-col span="3" offset="1">
<uv-button :disabled="state.resolved" :text="state.content?'开始解析':'粘贴并解析'" type="primary"
@click="startAnalyzing"></uv-button>
</uv-col>
</uv-row>
<view class="wrap">
<view v-if="state.result.video_url">
<view class="title">无水印视频</view>
<video :src="state.result.video_url"></video>
<uv-button style="margin-top: 20rpx;" type="primary" text="" @click="saveVideo(state.result.video_url)">
<text class="iconfont icon-download"></text>
<text>保存视频</text>
</uv-button>
</view>
<view v-if="state.result.title">
<view class="title">标题</view>
<view class="title-content">{{state.result.title}}</view>
<uv-button style="margin-top: 20rpx;" type="primary" text="" @click="copy(state.result.title)">
<text class="iconfont icon-copy"></text>
<text>复制标题</text>
</uv-button>
</view>
<view v-if="state.result.cover_url">
<view class="title">封面</view>
<image @click="preview(state.result.cover_url)" class="cover_url" :src="state.result.cover_url"
mode="aspectFill"></image>
<uv-button icon-color="#fff" style="margin-top: 20rpx;" type="primary" text=""
@click="saveImg(state.result.cover_url)">
<text class="iconfont icon-download"></text>
<text>保存封面</text>
</uv-button>
</view>
</view>
</view>
</template>
javascript
<script setup>
import {
getCurrentInstance,
reactive,
watch
} from "vue"
import {
onLoad,
onShareAppMessage,
onShareTimeline
} from "@dcloudio/uni-app"
const {
proxy,
appContext
} = getCurrentInstance()
const {
req
} = appContext.config.globalProperties;
const {
toast,
containsURL
} = appContext.config.globalProperties._;
const state = reactive({
content: "",
result: {
cover_url: "",
title: "",
video_url: "",
resolved: false
}
})
watch(() => state.content, val => {
if (val == "") {
state.resolved = false
}
})
onShareAppMessage(() => {
return {
title: "轻便短视频去水印",
path: "/pages/index/index"
}
})
onShareTimeline(() => {
return {
title: "轻便短视频去水印",
path: "/pages/index/index"
}
})
async function startAnalyzing() {
if (state.resolved) return
if (!state.content) {
let data = await getClipboardData()
if (data) {
state.content = data
}
}
if (!state.content) return toast("分享内容不能为空")
const isUrl = containsURL(state.content)
if (!isUrl) return toast("分享地址格式错误")
uni.showLoading({
title: "解析中...",
mask: true
})
req.get("/video/share/url/parse", {
params: {
url: state.content
}
})
.then(res => {
uni.hideLoading()
state.resolved = true
const {
cover_url,
title,
video_url
} = res
state.result.cover_url = cover_url
state.result.title = title
state.result.video_url = video_url
})
}
function getClipboardData() {
return new Promise((resolve, reject) => {
uni.getClipboardData({
success: function(res) {
resolve(res.data)
},
fail() {
reject(data)
}
});
})
}
function clearOrpaste() {
if (state.content) {
// 清除操作
state.content = ""
state.resolved = false
} else {
// 粘贴操作
uni.getClipboardData({
success: function(res) {
state.content = res.data
}
});
}
}
function copy(content) {
uni.setClipboardData({
data: content,
success() {
toast("已复制")
}
})
}
function saveVideo(val) {
uni.showLoading({
title: "保存中..."
})
const downloadTask = uni.downloadFile({
url: val,
success(res) {
uni.saveVideoToPhotosAlbum({
filePath: res.tempFilePath,
success(e) {
toast("保存成功", "success")
},
fail(err) {
if (err.errMsg == "saveVideoToPhotosAlbum:fail auth deny") {
uni.showModal({
title: "提示",
content: "需要您授权保存相册",
confirmText: "点击授权",
success(res) {
if (res.confirm) {
uni.openSetting({
success: setting => {
if (setting.authSetting['scope.writePhotosAlbum']) {
uni.showModal({
title: '提示',
content: '获取权限成功,再次点击下载即可保存',
showCancel: false,
})
} else {
uni.showModal({
title: '提示',
content: '获取权限失败,将无法保存到相册哦',
showCancel: false,
})
}
}
})
}
},
})
} else {
toast("保存失败")
}
req.post("/bugReport", {
method: "saveVideoToPhotosAlbum",
data: res.tempFilePath,
error: JSON.stringify(err),
})
}
})
},
fail(err) {
req.post("/bugReport", {
method: "downloadFile",
data: val,
error: JSON.stringify(err)
})
toast("保存失败")
}
})
downloadTask.onProgressUpdate((res) => {
// console.log('下载进度' + res.progress);
if (res.progress >= 100) {
uni.hideLoading()
}
});
}
function saveImg(val) {
uni.downloadFile({
url: val,
success(res) {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success() {
toast("保存成功", "success")
},
fail(err) {
if (err.errMsg == "saveImageToPhotosAlbum:fail auth deny") {
uni.showModal({
title: "提示",
content: "需要您授权保存相册",
confirmText: "点击授权",
success(res) {
if (res.confirm) {
uni.openSetting({
success: setting => {
if (setting.authSetting['scope.writePhotosAlbum']) {
uni.showModal({
title: '提示',
content: '获取权限成功,再次点击下载即可保存',
showCancel: false,
})
} else {
uni.showModal({
title: '提示',
content: '获取权限失败,将无法保存到相册哦',
showCancel: false,
})
}
}
})
}
},
})
} else {
toast("保存失败")
}
req.post("/bugReport", {
method: "saveImageToPhotosAlbum",
data: res.tempFilePath,
error: JSON.stringify(err)
})
}
})
},
fail(err) {
req.post("/bugReport", {
method: "downloadFile",
data: val,
error: JSON.stringify(err)
})
toast("保存失败")
}
})
}
function preview(url) {
uni.previewImage({
urls: [url]
})
}
</script>
css
<style lang="scss">
.iconfont {
margin-right: 20rpx;
font-size: 40rpx;
}
.title-content {
border-radius: 5rpx;
padding: 10rpx;
width: 100%;
box-sizing: border-box;
border: 1rpx dashed #999;
margin-bottom: 20rpx;
}
.cover_url {
width: 100%;
height: 600rpx;
}
video {
width: 100%;
}
.title {
font-size: 36rpx;
font-weight: bold;
margin: 40rpx 0;
padding-left: 30rpx;
position: relative;
&::before {
content: "";
position: absolute;
width: 14rpx;
height: 40rpx;
background-color: $theme-color;
left: 0;
top: 50%;
border-radius: 10rpx;
transform: translateY(-50%);
}
}
.plc {
font-size: 28rpx;
}
.area-wrap {
background-color: #fff;
width: 100%;
padding: 20rpx;
padding-bottom: 10rpx;
border-radius: 5rpx;
box-sizing: border-box;
margin-bottom: 20rpx;
textarea {![请添加图片描述](https://i-blog.csdnimg.cn/direct/714d26ef190e4715a33978b157197fd3.png)
font-size: 28rpx;
width: 100%;
}
.count {
margin-top: 10rpx;
font-size: 24rpx;
color: #999;
text-align: right;
}
}
page {
padding: 24rpx;
box-sizing: border-box;
}
</style>