uview+微信小程序+实现视频压缩(本地压缩)

首先说明PC端的小程序是不可以使用的,这是因为wx.compressVideo在PC端不可用,这是腾讯的问题 可以使用ffmpeg插件可以解决这个问题(自行下载);

效果1

 

 效果2

 页面1

<template>
	<view>
		<view class="top" style="background-color: #66CC99">
			<!-- 2.0.19支持autoBack,默认为false -->
			<u-navbar title="视频压缩" :placeholder="true" :safeAreaInsetTop="true" fixed leftIconSize="0 !important" bgColor="#66CC99" :height="86 + 'rpx'"></u-navbar>
		</view>
		<view class="container" style="padding:30rpx">
			<view style="padding: 30rpx 0rpx;">
				<view style="text-align: center; height:400rpx;background-color: #F8F8F8;">
					<view style="padding: 150rpx;" v-if="videoSrc == ''" @click="chooseAndCompressVideo">
						<view class="icon iconfont icon-jiahao"></view>
						<view style="font-size:30rpx ;color:#BABABA;padding:20rpx 0;font-weight:bold">选择上传视频</view>
					</view>
					<view style="width: 100%;" v-else><video :src="videoSrc" class="videoClass"></video></view>

					<view v-if="videoSrc != ''">
						<view style="font-size: 28rpx; color: #BABABA;padding:20rpx">分辨率:{{ videoWidth }}x{{ videoHeight }},大小:{{ videoSize }}</view>
					</view>
				</view>
			</view>
			<view style="margin: 60rpx 0;padding:30rpx;background-color: #F8F8F8;" @click="show = true">
				<u-row custom-style="font-size:32rpx">
					<u-col span="6">选择压缩质量</u-col>
					<u-col span="6" custom-style="justify-content:flex-end !important">
						<u-row custom-style="justify-content:flex-end !important">
							<u-col span="10" align="right" justify="end" custom-style="text-align:right" v-if="type != ''">
								<text style="text-align: right;" v-if="type != ''">{{ type[0].shape }}</text>
							</u-col>
							<u-col span="2" align="right" justify="end" custom-style="text-align:right"><u-icon name="arrow-right" size="40"></u-icon></u-col>
						</u-row>
					</u-col>
				</u-row>
			</view>
			<view style=" font-size: 28rpx;color:#BABABA">
				<view class="">
					<view style="padding: 6rpx;">PC端暂不支持视频压缩。</view>
					<view style="padding: 6rpx;">压缩质量越好,文件压缩的就越少。</view>
					<view style="padding: 6rpx;color: #66CC99;">标清建议选低质量,高清选中质量,超清选高质量。</view>
					<view style="padding: 6rpx;color:#F44336 ">绝对不保存、不上传用户的所有视频信息!</view>
				</view>
			</view>
			<view style="padding:100rpx 0;">
				<view
					style="margin:60rpx 50rpx; padding:20rpx 0; border-radius: 20rpx;  text-align: center;font-weight:bold;background: linear-gradient(to top, #F2CE53, #FFF9C4);"
					@click="CompressVideo"
				>
					开始压缩
				</view>
				<view
					style="margin:60rpx 50rpx; padding:20rpx 0; border-radius: 20rpx;  text-align: center;font-weight:bold;background: linear-gradient(to top, #F2CE53, #FFF9C4);"
					@click="chooseAndCompressVideo"
				>
					重新上传
				</view>
			</view>
		</view>
		<u-popup :show="show" @close="close" mode="bottom" safeAreaInsetBottom="true" round="20" bgColor="#F8F8F8">
			<view style="text-align: center;font-size: 32rpx;">
				<view class="" style="padding: 30rpx;margin:0 30rpx;">
					<view style="padding: 30rpx;" v-for="(item, index) in types" :key="index" @click="selectType(index)">{{ item.shape }}</view>
				</view>
				<view class="" style="padding:0 30rpx;"><view style="padding: 30rpx;">取消</view></view>
			</view>
		</u-popup>

		<u-toast ref="uToast"></u-toast>
	</view>
</template>

<script>
import { mapMutations } from 'vuex';
import { mapState } from 'vuex';
export default {
	data() {
		return {
			show: false,
			videoSrc: '', // 压缩后的视频文件路径
			videoHeight: '',
			videoWidth: '',
			videoSize: '',
			type: [{ shape: '高', bit: 'high' }],
			compressVideo: '',
			types: [{ shape: '高', bit: 'high' }, { shape: '中', bit: 'medium' }, { shape: '低', bit: 'low' }]
		};
	},

	onLoad() {},

	methods: {
		...mapMutations(['compressVideoInfos']), // 将 mutations 中的 mapMutations 方法映射到组件中

		close() {
			this.show = false;
		},

		selectType(item) {
			if (item == 0) {
				this.type[0] = this.types[0];
				// console.log(this.type);
			} else if (item == 1) {
				this.type[0] = this.types[1];
			} else {
				this.type[0] = this.types[2];
			}
			this.show = false;
		},

		formatFileSize(fileSize) {
			if (fileSize < 1024) {
				return fileSize + 'B';
			} else if (fileSize < 1024 * 1024) {
				return (fileSize / 1024).toFixed(2) + 'KB';
			} else {
				return (fileSize / (1024 * 1024)).toFixed(2) + 'MB';
			}
		},
		formatFileSizeCompress(fileSize) {
			if (fileSize < 1024) {
				return fileSize + 'KB';
			} else if (fileSize < 1024 * 1024) {
				return (fileSize / 1024).toFixed(2) + 'MB';
			} else {
				return (fileSize / (1024 * 1024)).toFixed(2) + 'G';
			}
		},
		CompressVideo() {
			let that = this;
			if (this.videoSrc != '') {
				wx.showLoading({
					title: '正在压缩...',
					mask: true
				});
				wx.compressVideo({
					src: that.videoSrc, // 需要压缩的视频路径
					quality: 0.8, 
					bitrate: that.type[0].bit, // 比特率,单位为kbps
					fps: 30, // 帧率,默认为30
					resolution: 1, // 分辨率,取值为 0(压缩至 360P)或 1(压缩至 480P),默认为1
					success: res => {
						that.CompressVideoSrc = res.tempFilePath;
						// console.log(that.type[0].bit);
						wx.getVideoInfo({
							src: res.tempFilePath,
							success: function(res) {
								// console.log(res);
								let compressfileSize = res.size;
								let compressformattedFileSize = that.formatFileSizeCompress(compressfileSize);
								let arr1 = res;
								arr1.compressformattedFileSize = compressformattedFileSize;
								arr1.compressVideoSrc = that.CompressVideoSrc;
								console.log(that.CompressVideoSrc)
								that.compressVideoInfos(arr1);
								uni.navigateTo({
									url: '/pages/index/synthesize'
								});
								wx.hideLoading();
								wx.showToast({
									title: '压缩成功',
									icon: 'success',
									duration: 2000
								});
							}
						});
						that.videoSrc = res.tempFilePath;
					},
					fail: ({ errMsg }) => {
						wx.hideLoading();
						wx.showToast({
							title: '压缩失败',
							icon: 'none',
							duration: 2000
						});
						console.log('压缩失败', errMsg);
					}
				});
			} else {
				wx.showToast({
					title: '请先上传视频',
					icon: 'none',
					duration: 2000
				});
			}
		},
		chooseAndCompressVideo() {
			let that=this;
			wx.chooseVideo({
				maxDuration: 60,
				compressed:false,
				camera: 'back',
				success: res => {
					// console.log(res);
					wx.showLoading({
						title: '加载中...',
						mask: true
					});
					console.log(res);
					that.videoHeight = res.height;
					that.videoWidth = res.width;
					const fileSize = res.size;
					const formattedFileSize = that.formatFileSize(fileSize);
					that.videoSize = formattedFileSize;
					that.videoSrc = res.tempFilePath;
					wx.hideLoading();
				}
			});
		}
	}
};
</script>
<style lang="scss" scoped>
.videoClass {
	// margin:30rpx;
	width: 100%;
	height: 400rpx;
	// width:100vw;
	// padding: 30rpx;
}

//自行解决图标问题
@font-face {
	
}

.iconfont {
	font-family: 'iconfont' !important;
	font-size: 60rpx;
	font-style: normal;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}
.icon-jiahao:before {
	content: '\e636';
}
::v-deep .u-icon--right {
	justify-content: flex-end;
}
</style>

页面2

<template>
	<view>
		<view class="top" style="background-color: #66CC99">
			<!-- 2.0.19支持autoBack,默认为false -->
			<u-navbar :autoBack="true" title="视频压缩" :placeholder="true" :safeAreaInsetTop="true" fixed leftIconSize="50rpx !important" bgColor="#66CC99" :height="86 + 'rpx'"></u-navbar>
		</view>

		<view class="container" style="padding:30rpx">
			<view style="padding: 30rpx 0rpx;">
				<view style="text-align: center; height:400rpx;background-color: #F8F8F8;">
					<view style="width: 100%;"><video :src="video_info.compressVideoSrc" class="videoClass"></video></view>
				</view>
			</view>

			<view style="padding: 30rpx;text-align: center;font-size:32rpx;color:#66CC99;font-weight:bold">压缩已完成,点击视频可预览</view>

			<view style="padding: 30rpx;font-size: 30rpx;background-color: #F8F8F8;border-radius: 20rpx;">
				<view>
					<view style="padding: 10rpx 0;">
						<u-row custom-style="padding:10rpx 0rpx">
							<u-col span="6">文件大小</u-col>
							<u-col span="6" custom-style="color: #bababa;"><view style="text-align: right;">{{video_info.compressformattedFileSize}}</view></u-col>
						</u-row>
						<u-row custom-style="padding:10rpx 0rpx">
							<u-col span="6">分辨率</u-col>
							<u-col span="6" custom-style="color: #bababa;"><view style="text-align: right;">{{video_info.width}}*{{video_info.height}}</view></u-col>
						</u-row>
						<u-row custom-style="padding:10rpx 0rpx">
							<u-col span="6">码率</u-col>
							<u-col span="6" custom-style="color: #bababa;"><view style="text-align: right;">{{video_info.bitrate}}kbps</view></u-col>
						</u-row>
						<u-row custom-style="padding:10rpx 0rpx">
							<u-col span="6">帧率</u-col>
							<u-col span="6" custom-style="color: #bababa;"><view style="text-align: right;">{{video_info.fps}}</view></u-col>
						</u-row>
					</view>

				<view style="padding:0rpx 0;">
					<view
						style="margin:60rpx 50rpx; padding:20rpx 0; border-radius: 20rpx;  text-align: center;font-weight:bold;background: linear-gradient(to top, #F2CE53, #FFF9C4);"
						@click="downloadCompressedVideo"
					>
						保存视频
					</view>
					<view
						style="margin:60rpx 50rpx; padding:20rpx 0; border-radius: 20rpx;  text-align: center;font-weight:bold;background: linear-gradient(to top, #F2CE53, #FFF9C4);"
						@click="chooseAndCompressVideo"
					>
						重新上传
					</view>
				</view>
					
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	import { mapMutations } from 'vuex';
	import { mapState } from 'vuex';
export default {
	data() {
		return {
			videoSrc: ''
		};
	},
		computed: {
			...mapState({ video_info: state => state.compressVideoInfo }) // 将 state 中的 buildingInformation 对象映射到组件中
		},
		onLoad(){
		
		},
	methods:{
		downloadCompressedVideo() {
			const compressedVideoSrc = this.video_info.compressVideoSrc;
			
			
			
			wx.getSetting({
			  success: res => {
			    if (!res.authSetting['scope.writePhotosAlbum']) {
			      // 如果用户未授权,则打开授权界面
			      wx.authorize({
			        scope: 'scope.writePhotosAlbum',
			        success: () => {
			          // 用户已授权,保存视频文件
			        wx.saveVideoToPhotosAlbum({
			        	filePath: compressedVideoSrc,
			        	success: () => {
			        		wx.showToast({
			        			title: '保存成功',
			        			icon: 'success',
			        			duration: 2000
			        		});
			        	},
			        	fail: ({ errMsg }) => {
			        		wx.showToast({
			        			title: '保存失败',
			        			icon: 'none',
			        			duration: 2000
			        		});
			        		// console.log('保存失败', errMsg);
			        	}
			        });
			        },
			        fail: () => {
			          // 用户拒绝授权,提示用户打开授权界面
			          wx.showModal({
			            title: '保存失败',
			            content: '请在小程序设置中打开保存到相册的权限',
			            showCancel: false,
			            confirmText: '确定',
			            success: res => {
			              if (res.confirm) {
			                wx.openSetting({
			                  success: res => {
			                    // console.log(res);
			                  }
			                });
			              }
			            }
			          });
			        }
			      });
			    } else {
			      // 用户已授权,保存视频文件
			   wx.saveVideoToPhotosAlbum({
			   	filePath: compressedVideoSrc,
			   	success: () => {
			   		wx.showToast({
			   			title: '保存成功',
			   			icon: 'success',
			   			duration: 2000
			   		});
			   	},
			   	fail: ({ errMsg }) => {
			   		wx.showToast({
			   			title: '保存失败',
			   			icon: 'none',
			   			duration: 2000
			   		});
			   		console.log('保存失败', errMsg);
			   	}
			   });
			    }
			  }
			});

		},
		chooseAndCompressVideo(){
			uni.navigateBack({
				delta:1,
			})
		}
	}
};
</script>

<style scoped lang="scss">
.videoClass {
	// margin:30rpx;
	width: 100%;
	height: 400rpx;
	// width:100vw;
	// padding: 30rpx;
}
</style>

下方是小程序demo可以看看效果 

 

创作不易,点个赞吧~~~

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值