小程序短视频项目———上传短视频业务
Posted bozzzhdz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小程序短视频项目———上传短视频业务相关的知识,希望对你有一定的参考价值。
一、用户选择视频
1、微信选中视频接口
wx.chooseVideo(Object object)
拍摄视频或从手机相册中选视频。
参数
Object object
属性 | 类型 | 默认值 | 是否必填 | 说明 | 支持版本 |
---|---|---|---|---|---|
sourceType | Array.<string> | [‘album‘, ‘camera‘] | 否 | 视频选择的来源 | |
compressed | boolean | true | 否 | 是否压缩所选择的视频文件 | >= 1.6.0 |
maxDuration | number | 60 | 否 | 拍摄视频最长拍摄时间,单位秒 | |
camera | string | ‘back‘ | 否 | 默认拉起的是前置或者后置摄像头。部分 android 手机下由于系统 ROM 不支持无法生效 | |
success | function | 否 | 接口调用成功的回调函数 | ||
fail | function | 否 | 接口调用失败的回调函数 | ||
complete | function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
object.sourceType 的合法值
值 | 说明 |
---|---|
album | 从相册选择视频 |
camera | 使用相机拍摄视频 |
object.camera 的合法值
值 | 说明 |
---|---|
back | 默认拉起后置摄像头 |
front | 默认拉起前置摄像头 |
object.success 回调函数
参数
Object res
属性 | 类型 | 说明 | 支持版本 |
---|---|---|---|
tempFilePath | string | 选定视频的临时文件路径 | |
duration | number | 选定视频的时间长度 | |
size | number | 选定视频的数据量大小 | |
height | number | 返回选定视频的高度 | |
width | number | 返回选定视频的宽度 |
示例代码
wx.chooseVideo({ sourceType: [‘album‘,‘camera‘], maxDuration: 60, camera: ‘back‘, success(res) { console.log(res.tempFilePath) } })
2、mine.js文件上传视频事件绑定uploadVideo事件编写(注:此步骤暂时只包含选中视频并上传到临时路径)
uploadVideo: function(){ var me = this; wx.chooseVideo({ sourceType: [‘album‘], success(res) { console.log(res); var duration = res.duration; var tmpheight = res.height; var tmpwidth = res.width; var tmpVideoUrl = res.tempFilePath; var tmpCoverUrl = res.thumbTempFilePath; if(duration > 11){ wx.showToast({ title: ‘视频长度不能超过10秒...‘, icon: "none", duration: 2500 }) } else if (duration < 1){ wx.showToast({ title: ‘视频长度不能小于1秒...‘, icon: "none", duration: 2500 }) }else{ //TODO 打开选择bgm的页面 } } }) }
二、选择背景音乐页面
1、
chooseBgm.wxml
<view> <form bindsubmit=‘upload‘> <radio-group name="bgmId"> <block wx:for="{{bgmList}}"> <view class=‘container‘> <audio name="{{item.name}}" author="{{item.author}}" src="{{serverUrl}}{{item.path}}" style=‘width:300px‘ id="myAudio" controls loop></audio> <radio style=‘margin-top:20px;‘ value=‘{{item.id}}‘></radio> </view> </block> </radio-group> <view class="inputView"> <label class="loginLabel">视频描述:</label> <input name="desc" class="inputText" placeholder="说点什么吧" /> </view> <!-- 提交 --> <button class="submitBtn" type="primary" form-type=‘submit‘>上传视频</button> <button class="gobackBtn" type="warn" form-type=‘reset‘>重置</button> </form> </view>
chooseBgm.wxss
page { height: 100%; } .container { display: flex; margin-top: 20rpx; justify-content: space-around; } .submitBtn { width: 80%; margin-top: 15px; } .gobackBtn { width: 80%; margin-top: 15px; } .loginLabel { color: gray; font-size: 15px; } .inputText { float: right; text-align: right; margin-right: 22px; margin-top: 11px; font-size: 15px; } .inputView { padding: 5px; background-color: white; line-height: 45px; border: solid 1px whitesmoke; }
2、微信音频接口
audio
注意:1.6.0 版本开始,该组件不再维护。建议使用能力更强的 wx.createInnerAudioContext 接口
音频。
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
id | String | audio 组件的唯一标识符 | |
src | String | 要播放音频的资源地址 | |
loop | Boolean | false | 是否循环播放 |
controls | Boolean | false | 是否显示默认控件 |
poster | String | 默认控件上的音频封面的图片资源地址,如果 controls 属性值为 false 则设置 poster 无效 | |
name | String | 未知音频 | 默认控件上的音频名字,如果 controls 属性值为 false 则设置 name 无效 |
author | String | 未知作者 | 默认控件上的作者名字,如果 controls 属性值为 false 则设置 author 无效 |
binderror | EventHandle | 当发生错误时触发 error 事件,detail = {errMsg: MediaError.code} | |
bindplay | EventHandle | 当开始/继续播放时触发play事件 | |
bindpause | EventHandle | 当暂停播放时触发 pause 事件 | |
bindtimeupdate | EventHandle | 当播放进度改变时触发 timeupdate 事件,detail = {currentTime, duration} | |
bindended | EventHandle | 当播放到末尾时触发 ended 事件 |
MediaError.code
返回错误码 | 描述 |
---|---|
1 | 获取资源被用户禁止 |
2 | 网络错误 |
3 | 解码错误 |
4 | 不合适资源 |
三、开发后台bgm列表接口
四、bgm页面联调获取背景音乐列表
chooseBgm.wxml
<view> <form bindsubmit=‘upload‘> <radio-group name="bgmId"> <block wx:for="{{bgmList}}"> <view class=‘container‘> <audio name="{{item.name}}" author="{{item.author}}" src="{{serverUrl}}{{item.path}}" style=‘width:300px‘ id="myAudio" controls loop></audio> <radio style=‘margin-top:20px;‘ value=‘{{item.id}}‘></radio> </view> </block> </radio-group> <view class="inputView"> <label class="loginLabel">视频描述:</label> <input name="desc" class="inputText" placeholder="说点什么吧" /> </view> <!-- 提交 --> <button class="submitBtn" type="primary" form-type=‘submit‘>上传视频</button> <button class="gobackBtn" type="warn" form-type=‘reset‘>重置</button> </form> </view>
chooseBgm.js
const app = getApp() Page({ data: { bgmList: [], serverUrl: "", poster: ‘http://y.gtimg.cn/music/photo_new/T002R300x300M000003rsKF44GyaSk.jpg?max_age=2592000‘, name: ‘此时此刻‘, author: ‘许巍‘, src: ‘http://ws.stream.qqmusic.qq.com/M500001VfvsJ21xFqb.mp3?guid=ffffffff82def4af4b12b3cd9337d5e7&uin=346897220&vkey=6292F51E1E384E06DCBDC9AB7C49FD713D632D313AC4858BACB8DDD29067D3C601481D36E62053BF8DFEAF74C0A5CCFADD6471160CAF3E6A&fromtag=46‘, }, onLoad: function (params) { var me = this; wx.showLoading({ title: ‘请等待...‘, }); var serverUrl = app.serverUrl; // 调用后端 wx.request({ url: serverUrl + ‘/bgm/list‘, method: "POST", header: { ‘content-type‘: ‘application/json‘ // 默认值 }, success: function (res) { console.log(res.data); wx.hideLoading(); if (res.data.status == 200) { var bgmList = res.data.data; me.setData({ bgmList: bgmList, serverUrl: serverUrl }); } } }) } })
五、开发上传短视频接口
package com.imooc.controller; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import org.apache.commons.lang3.StringUtils; import org.apache.tomcat.util.http.fileupload.IOUtils; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import com.imooc.pojo.Users; import com.imooc.utils.IMoocJSONResult; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @RestController @Api(value="视频相关业务的接口", tags= {"视频相关业务的controller"}) @RequestMapping("/video") public class VideoController { @ApiOperation(value="用户上传视频", notes="用户上传视频的接口") @ApiImplicitParams({ @ApiImplicitParam(name="userId", value="用户id", required=true, dataType="String", paramType="form"), @ApiImplicitParam(name="bgmId", value="背景音乐id", required=false, dataType="String", paramType="form"), @ApiImplicitParam(name="videoSeconds", value="背景音乐播放长度", required=true, dataType="String", paramType="form"), @ApiImplicitParam(name="videoWidth", value="视频宽度", required=true, dataType="String", paramType="form"), @ApiImplicitParam(name="videoHeight", value="视频高度", required=true, dataType="String", paramType="form"), @ApiImplicitParam(name="desc", value="视频描述", required=false, dataType="String", paramType="form") }) @PostMapping(value="/upload", headers="content-type=multipart/form-data") public IMoocJSONResult upload(String userId, String bgmId, double videoSeconds, int videoWidth, int videoHeight, String desc, @ApiParam(value="短视频", required=true) MultipartFile file) throws Exception { //Alt + shirt + R //文件保存的空间 String fileSpace = "D:/imooc_videos_dev"; //保存到数据库的相对路径 String uploadPathDB = "/" + userId + "/video" ; FileOutputStream fileOutputStream = null; InputStream inputStream = null; try { if(file != null ) { String fileName = file.getOriginalFilename(); if(StringUtils.isNoneBlank(fileName)) { //文件上传的最终路径 String finalVideoPath = fileSpace + uploadPathDB + "/" + fileName; //设置数据库保存的路径 uploadPathDB += ("/" + fileName); File outFile = new File(finalVideoPath); if(outFile.getParentFile() != null || !outFile.getParentFile().isDirectory()) { //创建父文件夹 outFile.getParentFile().mkdirs(); } fileOutputStream = new FileOutputStream(outFile); inputStream = file.getInputStream(); IOUtils.copy(inputStream, fileOutputStream); } } } catch (Exception e) { e.printStackTrace(); }finally { if(fileOutputStream != null) { fileOutputStream.flush(); fileOutputStream.close(); } } return IMoocJSONResult.ok(); } }
六、视频临时参数传入到下一个页面
首先在mine.js文件上的uploadVideo事件上补充页面跳转到chooseBgm.wxml
//打开选择bgm的页面 wx.navigateTo({ url: ‘../chooseBgm/chooseBgm?duration=‘ + duration + "&tmpHeight=" + tmpHeight + "&tmpWidth=" + tmpWidth + "&tmpVideoUrl=" + tmpVideoUrl + "&tmpCoverUrl=" + tmpCoverUrl , })
然后在chooseBgm.js文件上的初加载事件onLoad事件上通过参数param接受,VideoParams是在一开始就设置的。
var me = this; console.log(params); me.setData({ videoParams: params });
整个上传视频事件upLoad事件
upload: function(e) { var me = this; var bgmId = e.detail.value.bgmId; var desc = e.detail.value.desc; console.log("bgmId:" + bgmId); console.log("desc:" + desc); var duration = me.data.videoParams.duration; var tmpheight = me.data.videoParams.tmpHeight; var tmpwidth = me.data.videoParams.tmpWidth; var tmpVideoUrl = me.data.videoParams.tmpVideoUrl; var tmpCoverUrl = me.data.videoParams.tmpCoverUrl; //上传短视频 wx.showLoading({ title: ‘Loading...‘, }) var serverUrl = app.serverUrl; wx.uploadFile({ url: serverUrl + ‘/video/upload‘, formData: { userId: app.userInfo.id, bgmId: bgmId, desc: desc, videoSeconds: duration, videoHeight: tmpheight, videoWidth: tmpwidth }, filePath: tmpVideoUrl, name: ‘file‘, header: { ‘content-type‘: ‘application/json‘ // 默认值 }, success(res) { // var data = JSON.parse(res.data); console.log(res); wx.hideLoading(); if (data.status == 200) { wx.showToast({ title: ‘上传成功!~~‘, icon: "success" }); } } }) }
以上是关于小程序短视频项目———上传短视频业务的主要内容,如果未能解决你的问题,请参考以下文章