微信小程序_(校园视)开发上传视频业务
微信小程序_(校园视) 开发用户注册登陆 传送门
微信小程序_(校园视) 开发上传视频业务 传送门
微信小程序_(校园视) 开发视频的展示页-上 传送门
微信小程序_(校园视) 开发视频的展示页-下 传送门
用户上传视频
用户选择视频->打开选择bgm->选择/不选择bgm输入视频的描述->Controller上传视频->保存视频的截图->用户是否选择bgm
用户没有选择bgm可以直接保存视频,用户选择bgm将合并原视频和bgm新的视频并且保存
用户点击上传视频触发uploadVideo方法
<button size='mini' class='primary' bindtap='uploadVideo'> 上传作品</button>
uploadVideo:function(){ var me =this; wx.chooseVideo({ sourceType: ['album'], success(res) { console.log(res); } }) }
<view> <view class='container'> <image src="{{faceUrl}}" class="face" bindtap='changeFace'></image> <label class='nickname'>{{nickname}}</label> <button size='mini' class='primary' bindtap='uploadVideo'> 上传作品</button> <button size='mini' type='' class='logout' bindtap='logout'>注销</button> <view class='container-row'> <label class='info-items'>{{fansCounts}} 粉丝</label> <label class='info-items'>{{followCounts}} 关注</label> <label class='info-items'>{{receiveLikeCounts}} 获赞</label> </view> </view> </view> <view class="line"></view>
var videoUtil = require('../../utils/videoUtil.js') const app = getApp() Page({ data: { faceUrl: "../resource/images/noneface.png", }, onLoad: function (params) { var me = this; var user = app.userInfo; wx.showLoading({ title: '请等待...', }); // 调用后端 var serverUrl = app.serverUrl; wx.request({ url: serverUrl + '/user/query?userId='+user.id, method: "POST", header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { console.log(res.data); wx.hideLoading(); if (res.data.status == 200) { var userInfo= res.data.data; var faceUrl = "../resource/images/noneface.png"; if (userInfo.faceImage != null && userInfo.faceImage != '' && userInfo.faceImage!=undefined){ faceUrl = serverUrl + userInfo.faceImage; } me.setData({ faceUrl: faceUrl, fansCounts: userInfo.fansCounts, followCounts: userInfo.followCounts, receiveLikeCounts: userInfo.receiveLikeCounts, nickname: userInfo.nickname }); } } }) }, logout:function(params){ var user = app.userInfo; var serverUrl = app.serverUrl; wx.showLoading({ title: '请等待...', }); // 调用后端 wx.request({ url: serverUrl + '/logout?userId='+user.id, method: "POST", header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { console.log(res.data); wx.hideLoading(); if (res.data.status == 200) { // 注销成功 wx.showToast({ title: '注销成功', icon: 'success', duration: 2000 }); //清除全局用户对象 app.userInfo = null; //页面跳转 wx.navigateTo({ url: '../userLogin/login', }) } } }) }, changeFace:function(){ var me = this; wx.chooseImage({ count: 1, sizeType: ['compressed'], sourceType: ['album'], success:function(res) { var tempFilePaths = res.tempFilePaths; console.log(tempFilePaths); wx.showLoading({ title: '上传中...', }) var serverUrl = app.serverUrl; wx.uploadFile({ url: serverUrl+'/user/uploadFace?userId='+app.userInfo.id, filePath: tempFilePaths[0], name: 'file', header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { var data = JSON.parse(res.data); console.log(data); wx.hideLoading(); if(data.status == 200){ wx.showToast({ title: '上传成功', icon: "success" }); var imageUrl = data.data; me.setData({ faceUrl: serverUrl+imageUrl }); } else if (data.status == 500){ wx.showToast({ title: data.msg }); } } }) } }) }, uploadVideo:function(){ var me =this; wx.chooseVideo({ sourceType: ['album'], success(res) { console.log(res); } }) } })
背景BGM音乐
选择背景音乐页面
<view> <form bindsubmit='upload'> <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>
const app = getApp()
Page({
data: {
},
onLoad: function (params) {
},
})
添加音乐模块样式
<radio-group name="bgm"> <view class='container'> <audio poster="{{poster}}" name="{{name}}" author="{{author}}" src="{{src}}" id="myAudio" controls loop></audio> <radio style='margin-top:20px;' value=''></radio> </view> </radio-group>
<view> <form bindsubmit='upload'> <radio-group name="bgm"> <view class='container'> <audio poster="{{poster}}" name="{{name}}" author="{{author}}" src="{{src}}" id="myAudio" controls loop></audio> <radio style='margin-top:20px;' value=''></radio> </view> </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>
const app = getApp() Page({ data: { 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) { }, })
数据库中单独添加一条数据
音乐文件放在虚拟路径F:\imooc-video-gary\bgm下
添加查询Bgm的Controller层
@RestController @Api(value="背景音乐业务的接口",tags= {"背景音乐业务的controller"}) @RequestMapping("/bgm") public class BgmController { @Autowired private BgmService bgmService; @ApiOperation(value="获取背景音乐列表",notes="获取背景音乐列表的接口") @PostMapping("/list") public IMoocJSONResult list() { return IMoocJSONResult.ok(bgmService.queryBgmList()); } }
添加查询Bgm的Service
@Transactional(propagation = Propagation.SUPPORTS) @Override public List<Bgm> queryBgmList() { return bgmMapper.selectAll(); }
package com.imooc.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.imooc.service.BgmService; import com.imooc.utils.IMoocJSONResult; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @RestController @Api(value="背景音乐业务的接口",tags= {"背景音乐业务的controller"}) @RequestMapping("/bgm") public class BgmController { @Autowired private BgmService bgmService; @ApiOperation(value="获取背景音乐列表",notes="获取背景音乐列表的接口") @PostMapping("/list") public IMoocJSONResult list() { return IMoocJSONResult.ok(bgmService.queryBgmList()); } }
package com.imooc.service; import java.util.List; import com.imooc.pojo.Bgm; import com.imooc.pojo.Users; public interface BgmService { //查询背景音乐列表 public List<Bgm> queryBgmList(); }
package com.imooc.server.impl; import java.util.List; import org.n3r.idworker.Sid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.imooc.mapper.BgmMapper; import com.imooc.mapper.UsersMapper; import com.imooc.pojo.Bgm; import com.imooc.pojo.Users; import com.imooc.service.BgmService; import com.imooc.service.UserService; import tk.mybatis.mapper.entity.Example; import tk.mybatis.mapper.entity.Example.Criteria; @Service public class BgmServiceImpl implements BgmService { @Autowired private BgmMapper bgmMapper; @Autowired private Sid sid; @Transactional(propagation = Propagation.SUPPORTS) @Override public List<Bgm> queryBgmList() { return bgmMapper.selectAll(); } }
微信小程序bgm页面联调获取背景音乐列表
chooseBgm.wxml中通过使用block循环获得数据库中的bgm
<block wx:for="{{bgmList}}"> <view class='container'> <audio name="{{item.name}}" author="{{item.author}}" src="{{serverUrl}}{{item.path}}" id="myAudio" controls loop></audio> <radio style='margin-top:20px;' value='{{item.id}}'></radio> </view> </block>
为防止用户歌曲名字输入时过长,可以在<audio>组件中通过style='width:300px'去进行歌曲名长度控制
<audio name="{{item.name}}" author="{{item.author}}" src="{{serverUrl}}{{item.path}}" style='width:300px' id="myAudio" controls loop></audio>
chooseBgm.js中通过编写onLoad函数去对后台发起bgm/list请求
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 }); } } }) },
<view> <form bindsubmit='upload'> <radio-group name="bgm"> <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>
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 }); } } }) }, })
开发上传短视频接口
短视频上传接口类似上传头像
@PostMapping(value="/upload",headers="content-type=multipart/form-data") public IMoocJSONResult uploadFace(String userId, String bgmId,double videoSeconds,int videoWidth,int videoHeight,String desc, @ApiParam(value="短视频",required=true) MultipartFile file) throws Exception { if(StringUtils.isBlank(userId)) { return IMoocJSONResult.errorMsg("用户id不能为空..."); } //文件保存命名空间 String fileSpace = "F:/imooc-video-gary"; //保存到数据库中的相对路径 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); } }else { return IMoocJSONResult.errorMsg("上传出错..."); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return IMoocJSONResult.errorMsg("上传出错..."); }finally { if(fileOutputStream != null) { fileOutputStream.flush(); fileOutputStream.close(); } } return IMoocJSONResult.ok(); }
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="query"), @ApiImplicitParam(name="bgmId",value="背景音乐id",required=false, dataType="String" ,paramType="query"), @ApiImplicitParam(name="videoSeconds",value="背景音乐播放长度",required=true, dataType="String" ,paramType="query"), @ApiImplicitParam(name="videoWidth",value="视频的宽度",required=true, dataType="String" ,paramType="query"), @ApiImplicitParam(name="videoHeight",value="视频的高度",required=true, dataType="String" ,paramType="query"), @ApiImplicitParam(name="desc",value="视频的描述",required=false, dataType="String" ,paramType="query") }) @PostMapping(value="/upload",headers="content-type=multipart/form-data") public IMoocJSONResult uploadFace(String userId, String bgmId,double videoSeconds,int videoWidth,int videoHeight,String desc, @ApiParam(value="短视频",required=true) MultipartFile file) throws Exception { if(StringUtils.isBlank(userId)) { return IMoocJSONResult.errorMsg("用户id不能为空..."); } //文件保存命名空间 String fileSpace = "F:/imooc-video-gary"; //保存到数据库中的相对路径 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); } }else { return IMoocJSONResult.errorMsg("上传出错..."); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return IMoocJSONResult.errorMsg("上传出错..."); }finally { if(fileOutputStream != null) { fileOutputStream.flush(); fileOutputStream.close(); } } return IMoocJSONResult.ok(); } }
小程序上传视频
视频从mine页面传参到chooseBgm页面
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>300){ wx.showToast({ title: '视频长度不能超过5分钟...', icon:"none", duration:2500 }) } else if(duration<3){ wx.showToast({ title: '视频长度太短,请上传超过3秒的视频...', icon: "none", duration: 2500 }) }else{ //打开选择bgm页面 wx.navigateTo({ url: '../chooseBgm/chooseBgm?duration=' + duration + "&tmpheight=" + tmpheight + "&tmpwidth=" + tmpwidth + "&tmpVideoUrl=" + tmpVideoUrl + "&tmpCoverUrl=" + tmpCoverUrl , }) } } }) }
chooseBgm页面通过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: '上传中...', }) var serverUrl = app.serverUrl; wx.uploadFile({ url: serverUrl + '/video/upload', formData:{ userId: app.userInfo.id, bgmId:bgmId, desc: desc, videoSeconds: duration, videoWidth: tmpheight, videoHeight: tmpwidth, }, filePath: tmpVideoUrl, name: 'file', header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { var data = JSON.parse(res.data); console.log(res); wx.hideLoading(); if (data.status == 200) { wx.showToast({ title: '上传成功', icon: "success" }); } } }) }
<view> <form bindsubmit='upload'> <radio-group name="bgmId"> <block wx:for="{{bgmList}}" wx:key=""> <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>
const app = getApp() Page({ data: { bgmList:[], serverUrl:"", videoParams:{} }, onLoad: function (params) { var me = this; console.log(params); me.setData({ videoParams: params }); 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 }); } } }) }, 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: '上传中...', }) var serverUrl = app.serverUrl; wx.uploadFile({ url: serverUrl + '/video/upload', formData:{ userId: app.userInfo.id, bgmId:bgmId, desc: desc, videoSeconds: duration, videoWidth: tmpheight, videoHeight: tmpwidth, }, filePath: tmpVideoUrl, name: 'file', header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { var data = JSON.parse(res.data); console.log(res); wx.hideLoading(); if (data.status == 200) { wx.showToast({ title: '上传成功', icon: "success" }); } } }) } })
var videoUtil = require('../../utils/videoUtil.js') const app = getApp() Page({ data: { faceUrl: "../resource/images/noneface.png", }, onLoad: function (params) { var me = this; var user = app.userInfo; wx.showLoading({ title: '请等待...', }); // 调用后端 var serverUrl = app.serverUrl; wx.request({ url: serverUrl + '/user/query?userId='+user.id, method: "POST", header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { console.log(res.data); wx.hideLoading(); if (res.data.status == 200) { var userInfo= res.data.data; var faceUrl = "../resource/images/noneface.png"; if (userInfo.faceImage != null && userInfo.faceImage != '' && userInfo.faceImage!=undefined){ faceUrl = serverUrl + userInfo.faceImage; } me.setData({ faceUrl: faceUrl, fansCounts: userInfo.fansCounts, followCounts: userInfo.followCounts, receiveLikeCounts: userInfo.receiveLikeCounts, nickname: userInfo.nickname }); } } }) }, logout:function(params){ var user = app.userInfo; var serverUrl = app.serverUrl; wx.showLoading({ title: '请等待...', }); // 调用后端 wx.request({ url: serverUrl + '/logout?userId='+user.id, method: "POST", header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { console.log(res.data); wx.hideLoading(); if (res.data.status == 200) { // 注销成功 wx.showToast({ title: '注销成功', icon: 'success', duration: 2000 }); //清除全局用户对象 app.userInfo = null; //页面跳转 wx.navigateTo({ url: '../userLogin/login', }) } } }) }, changeFace:function(){ var me = this; wx.chooseImage({ count: 1, sizeType: ['compressed'], sourceType: ['album'], success:function(res) { var tempFilePaths = res.tempFilePaths; console.log(tempFilePaths); wx.showLoading({ title: '上传中...', }) var serverUrl = app.serverUrl; wx.uploadFile({ url: serverUrl+'/user/uploadFace?userId='+app.userInfo.id, filePath: tempFilePaths[0], name: 'file', header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { var data = JSON.parse(res.data); console.log(data); wx.hideLoading(); if(data.status == 200){ wx.showToast({ title: '上传成功', icon: "success" }); var imageUrl = data.data; me.setData({ faceUrl: serverUrl+imageUrl }); } else if (data.status == 500){ wx.showToast({ title: data.msg }); } } }) } }) }, 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>300){ wx.showToast({ title: '视频长度不能超过5分钟...', icon:"none", duration:2500 }) } else if(duration<3){ wx.showToast({ title: '视频长度太短,请上传超过3秒的视频...', icon: "none", duration: 2500 }) }else{ //打开选择bgm页面 wx.navigateTo({ url: '../chooseBgm/chooseBgm?duration=' + duration + "&tmpheight=" + tmpheight + "&tmpwidth=" + tmpwidth + "&tmpVideoUrl=" + tmpVideoUrl + "&tmpCoverUrl=" + tmpCoverUrl , }) } } }) } })
ffmpeg
ffmpeg:视音频处理工具,跨平台的视音频处理解决方案
视频转换命令
$ ffmpeg -i input.mp4 output.avi
Java于ffmpeg的结合
在common层中创建FFMpegTest.java类,实现java于ffmpeg的结合
package com.imooc.utils; import java.util.ArrayList; import java.util.List; public class FFMpegTest { private String ffmpegEXE; public FFMpegTest(String ffmpegEXE) { super(); this.ffmpegEXE = ffmpegEXE; } public void convertor(String videoInputPath,String videoOutputPath) throws Exception{ //$ ffmpeg -i input.mp4 output.avi List<String> command = new ArrayList<>(); command.add(ffmpegEXE); command.add("-i"); command.add(videoInputPath); command.add(videoOutputPath); for(String c:command) { System.out.print(c); } ProcessBuilder process = new ProcessBuilder(command); process.start(); } public static void main(String[] args) { FFMpegTest ffmpeg = new FFMpegTest("F:\\Garyffmpeg\\ffmpeg\\bin\\ffmpeg.exe"); try { ffmpeg.convertor("E:\\19222\\毕业生.mp4","E:\\19222\\毕.avi"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
可以看到转码格式的输出
为了提高资源的利用率,可以在convertor()方法中提高流资源利用率
public void convertor(String videoInputPath,String videoOutputPath) throws Exception{ //$ ffmpeg -i input.mp4 output.avi List<String> command = new ArrayList<>(); command.add(ffmpegEXE); command.add("-i"); command.add(videoInputPath); command.add(videoOutputPath); for(String c:command) { System.out.print(c); } ProcessBuilder builder = new ProcessBuilder(command); Process process = builder.start(); InputStream errorStream = process.getErrorStream(); InputStreamReader inputStreamReader = new InputStreamReader(errorStream); BufferedReader br = new BufferedReader(inputStreamReader); String line = ""; //一直读取到最后一行 while((line=br.readLine()) !=null ) { } if(br!=null) { br.close(); } if(inputStreamReader!=null) { inputStreamReader.close(); } if(errorStream!=null) { errorStream.close(); } }
package com.imooc.utils; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; public class FFMpegTest { private String ffmpegEXE; public FFMpegTest(String ffmpegEXE) { super(); this.ffmpegEXE = ffmpegEXE; } public void convertor(String videoInputPath,String videoOutputPath) throws Exception{ //$ ffmpeg -i input.mp4 output.avi List<String> command = new ArrayList<>(); command.add(ffmpegEXE); command.add("-i"); command.add(videoInputPath); command.add(videoOutputPath); for(String c:command) { System.out.print(c); } ProcessBuilder builder = new ProcessBuilder(command); Process process = builder.start(); InputStream errorStream = process.getErrorStream(); InputStreamReader inputStreamReader = new InputStreamReader(errorStream); BufferedReader br = new BufferedReader(inputStreamReader); String line = ""; //一直读取到最后一行 while((line=br.readLine()) !=null ) { } if(br!=null) { br.close(); } if(inputStreamReader!=null) { inputStreamReader.close(); } if(errorStream!=null) { errorStream.close(); } } public static void main(String[] args) { FFMpegTest ffmpeg = new FFMpegTest("F:\\Garyffmpeg\\ffmpeg\\bin\\ffmpeg.exe"); try { ffmpeg.convertor("E:\\19222\\毕业生.mp4","E:\\19222\\毕2.avi"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
ffmpeg操作视频与bgm结合
视频与bgm结合,最终长度以视频的为主
Gary.mp4视频与GaryMusic.mp3音频合成,合成新的new.mp4文件
同理使用java代码生成mp4视频
public void convertor(String videoInputPath,String mp3InputPath, double seconds,String videoOutputPath) throws Exception{ //ffmpeg.exe -i Gary.mp4 -i GaryMusic.mp3 -t 7 -y new.mp4 List<String> command = new ArrayList<>(); command.add(ffmpegEXE); command.add("-i"); command.add(videoInputPath); command.add("-i"); command.add(mp3InputPath); command.add("-t"); command.add(String.valueOf(seconds)); command.add("-y"); command.add(videoOutputPath); for(String c:command) { System.out.print(c); } ProcessBuilder builder = new ProcessBuilder(command); Process process = builder.start(); InputStream errorStream = process.getErrorStream(); InputStreamReader inputStreamReader = new InputStreamReader(errorStream); BufferedReader br = new BufferedReader(inputStreamReader); String line = ""; //一直读取到最后一行 while((line=br.readLine()) !=null ) { } if(br!=null) { br.close(); } if(inputStreamReader!=null) { inputStreamReader.close(); } if(errorStream!=null) { errorStream.close(); } }
package com.imooc.utils; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; public class MergeVideoMp3 { private String ffmpegEXE; public MergeVideoMp3(String ffmpegEXE) { super(); this.ffmpegEXE = ffmpegEXE; } public void convertor(String videoInputPath,String mp3InputPath, double seconds,String videoOutputPath) throws Exception{ //ffmpeg.exe -i Gary.mp4 -i GaryMusic.mp3 -t 7 -y new.mp4 List<String> command = new ArrayList<>(); command.add(ffmpegEXE); command.add("-i"); command.add(videoInputPath); command.add("-i"); command.add(mp3InputPath); command.add("-t"); command.add(String.valueOf(seconds)); command.add("-y"); command.add(videoOutputPath); for(String c:command) { System.out.print(c); } ProcessBuilder builder = new ProcessBuilder(command); Process process = builder.start(); InputStream errorStream = process.getErrorStream(); InputStreamReader inputStreamReader = new InputStreamReader(errorStream); BufferedReader br = new BufferedReader(inputStreamReader); String line = ""; //一直读取到最后一行 while((line=br.readLine()) !=null ) { } if(br!=null) { br.close(); } if(inputStreamReader!=null) { inputStreamReader.close(); } if(errorStream!=null) { errorStream.close(); } } public static void main(String[] args) { MergeVideoMp3 ffmpeg = new MergeVideoMp3("F:\\Garyffmpeg\\ffmpeg\\bin\\ffmpeg.exe"); try { ffmpeg.convertor("E:\\19222\\毕业生.mp4","E:\\19222\\GaryMusic.mp3",7.1,"E:\\19222\\通过java生成的视频.mp4"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
小程序上传视频后调用视频处理工具类联调
可以在小程序端添加判断用户是否选择了BGM,如果不用户选择合成BGM,那就查询bgm的信息,并且合并视频生成新的视频
if(StringUtils.isNotBlank(bgmId)) { Bgm bgm = bgmService.queryBgmById(bgmId); String mp3InputPath = FILE_SPACE + bgm.getPath(); //System.out.println("1:mp3InputPath + "+mp3InputPath); MergeVideoMp3 tool = new MergeVideoMp3(FFMPEG_EXE); String videoInputPath = finalVideoPath; String videdoOutputName = UUID.randomUUID().toString() + ".mp4"; uploadPathDB = "/" + userId + "/video" + "/" +videdoOutputName; finalVideoPath = FILE_SPACE + uploadPathDB; tool.convertor(videoInputPath, mp3InputPath, videoSeconds, finalVideoPath); }
FFMpegTest.java作为FFMpeg合并短视频的BGM
public void convertor(String videoInputPath,String videoOutputPath) throws Exception{ //$ ffmpeg -i input.mp4 output.avi List<String> command = new ArrayList<>(); command.add(ffmpegEXE); command.add("-i"); command.add(videoInputPath); command.add(videoOutputPath); for(String c:command) { System.out.print(c); } ProcessBuilder builder = new ProcessBuilder(command); Process process = builder.start(); InputStream errorStream = process.getErrorStream(); InputStreamReader inputStreamReader = new InputStreamReader(errorStream); BufferedReader br = new BufferedReader(inputStreamReader); String line = ""; //一直读取到最后一行 while((line=br.readLine()) !=null ) { } if(br!=null) { br.close(); } if(inputStreamReader!=null) { inputStreamReader.close(); } if(errorStream!=null) { errorStream.close(); } }
package com.imooc.utils; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; public class FFMpegTest { private String ffmpegEXE; public FFMpegTest(String ffmpegEXE) { super(); this.ffmpegEXE = ffmpegEXE; } public void convertor(String videoInputPath,String videoOutputPath) throws Exception{ //$ ffmpeg -i input.mp4 output.avi List<String> command = new ArrayList<>(); command.add(ffmpegEXE); command.add("-i"); command.add(videoInputPath); command.add(videoOutputPath); for(String c:command) { System.out.print(c); } ProcessBuilder builder = new ProcessBuilder(command); Process process = builder.start(); InputStream errorStream = process.getErrorStream(); InputStreamReader inputStreamReader = new InputStreamReader(errorStream); BufferedReader br = new BufferedReader(inputStreamReader); String line = ""; //一直读取到最后一行 while((line=br.readLine()) !=null ) { } if(br!=null) { br.close(); } if(inputStreamReader!=null) { inputStreamReader.close(); } if(errorStream!=null) { errorStream.close(); } } public static void main(String[] args) { FFMpegTest ffmpeg = new FFMpegTest("F:\\Garyffmpeg\\ffmpeg\\bin\\ffmpeg.exe"); try { ffmpeg.convertor("E:\\19222\\毕业生.mp4","E:\\19222\\毕2.avi"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
package com.imooc.controller; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.util.UUID; import org.apache.commons.lang3.StringUtils; import org.apache.tomcat.util.http.fileupload.IOUtils; import org.springframework.beans.factory.annotation.Autowired; 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.Bgm; import com.imooc.pojo.Users; import com.imooc.service.BgmService; import com.imooc.utils.IMoocJSONResult; import com.imooc.utils.MergeVideoMp3; 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 extends BasicController{ @Autowired private BgmService bgmService; @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 uploadFace(String userId, String bgmId,double videoSeconds,int videoWidth,int videoHeight,String desc, @ApiParam(value="短视频",required=true) MultipartFile file) throws Exception { if(StringUtils.isBlank(userId)) { return IMoocJSONResult.errorMsg("用户id不能为空..."); } //文件保存命名空间 //String fileSpace = "F:/imooc-video-gary"; //保存到数据库中的相对路径 String uploadPathDB = "/" + userId + "/video"; FileOutputStream fileOutputStream = null; InputStream inputStream = null; String finalVideoPath = ""; try { if( file != null ) { String fileName = file.getOriginalFilename(); if(StringUtils.isNoneBlank(fileName)) { //文件上传的最终保存路径 finalVideoPath = FILE_SPACE + 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); } }else { return IMoocJSONResult.errorMsg("上传出错..."); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return IMoocJSONResult.errorMsg("上传出错..."); }finally { if(fileOutputStream != null) { fileOutputStream.flush(); fileOutputStream.close(); } } //判断bgmId是否为空, //如果不为空,那就查询bgm的信息,并且合并视频生成新的视频 if(StringUtils.isNotBlank(bgmId)) { Bgm bgm = bgmService.queryBgmById(bgmId); String mp3InputPath = FILE_SPACE + bgm.getPath(); //System.out.println("1:mp3InputPath + "+mp3InputPath); MergeVideoMp3 tool = new MergeVideoMp3(FFMPEG_EXE); String videoInputPath = finalVideoPath; String videdoOutputName = UUID.randomUUID().toString() + ".mp4"; uploadPathDB = "/" + userId + "/video" + "/" +videdoOutputName; finalVideoPath = FILE_SPACE + uploadPathDB; tool.convertor(videoInputPath, mp3InputPath, videoSeconds, finalVideoPath); } System.out.println("uploadPathDB="+uploadPathDB); System.out.println("finalVideoPath="+finalVideoPath); return IMoocJSONResult.ok(); } }
const app = getApp() Page({ data: { bgmList:[], serverUrl:"", videoParams:{} }, onLoad: function (params) { var me = this; console.log(params); me.setData({ videoParams: params }); 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 }); } } }) }, 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: '上传中...', }) var serverUrl = app.serverUrl; wx.uploadFile({ url: serverUrl + '/video/upload', formData: { userId: app.userInfo.id, bgmId: bgmId, desc: desc, videoSeconds: duration, videoWidth: tmpheight, videoHeight: tmpwidth, }, filePath: tmpVideoUrl, name: 'file', header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { var data = JSON.parse(res.data); console.log(res); wx.hideLoading(); if (data.status == 200) { wx.showToast({ title: '上传成功', icon: "success" }); } } }) } })
保存视频到数据库中
在VideoController中将数视频信息存储到数据库中
//保存视频信息到数据库 Videos video = new Videos(); video.setAudioId(bgmId); video.setUserId(userId); video.setVideoSeconds((float)videoSeconds); video.setVideoHeight(videoHeight); video.setVideoWidth(videoWidth); video.setVideoDesc(desc); video.setVideoPath(uploadPathDB); video.setStatus(VideoStatusEnum.SUCCESS.value); video.setCreateTime(new Date()); videoService.saveVideo(video);
保存数据库方法
@Transactional(propagation = Propagation.REQUIRED) @Override public void saveVideo(Videos video) { String id = sid.nextShort(); video.setId(id); videosMapper.insertSelective(video); }
package com.imooc.service; import java.util.List; import com.imooc.pojo.Bgm; import com.imooc.pojo.Users; import com.imooc.pojo.Videos; public interface VideoService { //保存视频 public void saveVideo(Videos video); }
package com.imooc.server.impl; import java.util.List; import org.n3r.idworker.Sid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.imooc.mapper.BgmMapper; import com.imooc.mapper.UsersMapper; import com.imooc.mapper.VideosMapper; import com.imooc.pojo.Bgm; import com.imooc.pojo.Users; import com.imooc.pojo.Videos; import com.imooc.service.BgmService; import com.imooc.service.UserService; import com.imooc.service.VideoService; import tk.mybatis.mapper.entity.Example; import tk.mybatis.mapper.entity.Example.Criteria; @Service public class VideoServiceImpl implements VideoService { @Autowired private VideosMapper videosMapper; @Autowired private Sid sid; @Transactional(propagation = Propagation.REQUIRED) @Override public void saveVideo(Videos video) { String id = sid.nextShort(); video.setId(id); videosMapper.insertSelective(video); } }
package com.imooc.controller; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.util.Date; import java.util.UUID; import org.apache.commons.lang3.StringUtils; import org.apache.tomcat.util.http.fileupload.IOUtils; import org.springframework.beans.factory.annotation.Autowired; 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.enums.VideoStatusEnum; import com.imooc.pojo.Bgm; import com.imooc.pojo.Users; import com.imooc.pojo.Videos; import com.imooc.service.BgmService; import com.imooc.service.VideoService; import com.imooc.utils.IMoocJSONResult; import com.imooc.utils.MergeVideoMp3; 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 extends BasicController{ @Autowired private BgmService bgmService; @Autowired private VideoService videoService; @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 uploadFace(String userId, String bgmId,double videoSeconds,int videoWidth,int videoHeight,String desc, @ApiParam(value="短视频",required=true) MultipartFile file) throws Exception { if(StringUtils.isBlank(userId)) { return IMoocJSONResult.errorMsg("用户id不能为空..."); } //文件保存命名空间 //String fileSpace = "F:/imooc-video-gary"; //保存到数据库中的相对路径 String uploadPathDB = "/" + userId + "/video"; FileOutputStream fileOutputStream = null; InputStream inputStream = null; String finalVideoPath = ""; try { if( file != null ) { String fileName = file.getOriginalFilename(); if(StringUtils.isNoneBlank(fileName)) { //文件上传的最终保存路径 finalVideoPath = FILE_SPACE + 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); } }else { return IMoocJSONResult.errorMsg("上传出错..."); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return IMoocJSONResult.errorMsg("上传出错..."); }finally { if(fileOutputStream != null) { fileOutputStream.flush(); fileOutputStream.close(); } } //判断bgmId是否为空, //如果不为空,那就查询bgm的信息,并且合并视频生成新的视频 if(StringUtils.isNotBlank(bgmId)) { Bgm bgm = bgmService.queryBgmById(bgmId); String mp3InputPath = FILE_SPACE + bgm.getPath(); //System.out.println("1:mp3InputPath + "+mp3InputPath); MergeVideoMp3 tool = new MergeVideoMp3(FFMPEG_EXE); String videoInputPath = finalVideoPath; String videdoOutputName = UUID.randomUUID().toString() + ".mp4"; uploadPathDB = "/" + userId + "/video" + "/" +videdoOutputName; finalVideoPath = FILE_SPACE + uploadPathDB; tool.convertor(videoInputPath, mp3InputPath, videoSeconds, finalVideoPath); } //保存视频信息到数据库 Videos video = new Videos(); video.setAudioId(bgmId); video.setUserId(userId); video.setVideoSeconds((float)videoSeconds); video.setVideoHeight(videoHeight); video.setVideoWidth(videoWidth); video.setVideoDesc(desc); video.setVideoPath(uploadPathDB); video.setStatus(VideoStatusEnum.SUCCESS.value); video.setCreateTime(new Date()); videoService.saveVideo(video); return IMoocJSONResult.ok(); } }
上传封面图保存到数据库中
因为wx.uploadFile()方法上传是单文件,所以视频和封面必须要分开上传
保存视频uploadCover(Sring userId,String videoId)方法
@ApiOperation(value="上传封面", notes="上传封面的接口") @ApiImplicitParams({ @ApiImplicitParam(name="userId",value="用户id",required=true, dataType="String" ,paramType="form"), @ApiImplicitParam(name="videoId",value="视频主键id",required=true, dataType="String" ,paramType="form") }) @PostMapping(value="/uploadCover",headers="content-type=multipart/form-data") public IMoocJSONResult uploadCover(String userId,String videoId, @ApiParam(value="视频封面",required=true) MultipartFile file) throws Exception { if(StringUtils.isBlank(userId) ||StringUtils.isBlank(videoId) ) { return IMoocJSONResult.errorMsg("视频主键id和用户id不能为空..."); } //文件保存命名空间 //String fileSpace = "F:/imooc-video-gary"; //保存到数据库中的相对路径 String uploadPathDB = "/" + userId + "/video"; FileOutputStream fileOutputStream = null; InputStream inputStream = null; String finalCoverPath = ""; try { if( file != null ) { String fileName = file.getOriginalFilename(); if(StringUtils.isNoneBlank(fileName)) { //文件上传的最终保存路径 finalCoverPath = FILE_SPACE + uploadPathDB + "/" + fileName; //设置数据库保存的路径 uploadPathDB += ("/" + fileName); File outFile = new File(finalCoverPath); if(outFile.getParentFile()!=null || !outFile.getParentFile().isDirectory()) { //创建父文件夹 outFile.getParentFile().mkdirs(); } fileOutputStream = new FileOutputStream(outFile); inputStream = file.getInputStream(); IOUtils.copy(inputStream, fileOutputStream); } }else { return IMoocJSONResult.errorMsg("上传出错..."); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return IMoocJSONResult.errorMsg("上传出错..."); }finally { if(fileOutputStream != null) { fileOutputStream.flush(); fileOutputStream.close(); } } videoService.updateVideo(videoId, uploadPathDB); return IMoocJSONResult.ok(); }
将视频封面保存进数据库方法
@Transactional(propagation = Propagation.REQUIRED) @Override public void updateVideo(String videoId, String coverPath) { Videos video = new Videos(); video.setId(videoId); video.setCoverPath(coverPath); videosMapper.updateByPrimaryKeySelective(video); }
package com.imooc.server.impl; import java.util.List; import org.n3r.idworker.Sid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.imooc.mapper.BgmMapper; import com.imooc.mapper.UsersMapper; import com.imooc.mapper.VideosMapper; import com.imooc.pojo.Bgm; import com.imooc.pojo.Users; import com.imooc.pojo.Videos; import com.imooc.service.BgmService; import com.imooc.service.UserService; import com.imooc.service.VideoService; import tk.mybatis.mapper.entity.Example; import tk.mybatis.mapper.entity.Example.Criteria; @Service public class VideoServiceImpl implements VideoService { @Autowired private VideosMapper videosMapper; @Autowired private Sid sid; @Transactional(propagation = Propagation.REQUIRED) @Override public String saveVideo(Videos video) { String id = sid.nextShort(); video.setId(id); videosMapper.insertSelective(video); return id; } @Transactional(propagation = Propagation.REQUIRED) @Override public void updateVideo(String videoId, String coverPath) { Videos video = new Videos(); video.setId(videoId); video.setCoverPath(coverPath); videosMapper.updateByPrimaryKeySelective(video); } }
package com.imooc.controller; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.util.Date; import java.util.UUID; import org.apache.commons.lang3.StringUtils; import org.apache.tomcat.util.http.fileupload.IOUtils; import org.springframework.beans.factory.annotation.Autowired; 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.enums.VideoStatusEnum; import com.imooc.pojo.Bgm; import com.imooc.pojo.Users; import com.imooc.pojo.Videos; import com.imooc.service.BgmService; import com.imooc.service.VideoService; import com.imooc.utils.IMoocJSONResult; import com.imooc.utils.MergeVideoMp3; 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 extends BasicController{ @Autowired private BgmService bgmService; @Autowired private VideoService videoService; @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 uploadFace(String userId, String bgmId,double videoSeconds,int videoWidth,int videoHeight,String desc, @ApiParam(value="短视频",required=true) MultipartFile file) throws Exception { if(StringUtils.isBlank(userId)) { return IMoocJSONResult.errorMsg("用户id不能为空..."); } //文件保存命名空间 //String fileSpace = "F:/imooc-video-gary"; //保存到数据库中的相对路径 String uploadPathDB = "/" + userId + "/video"; FileOutputStream fileOutputStream = null; InputStream inputStream = null; String finalVideoPath = ""; try { if( file != null ) { String fileName = file.getOriginalFilename(); if(StringUtils.isNoneBlank(fileName)) { //文件上传的最终保存路径 finalVideoPath = FILE_SPACE + 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); } }else { return IMoocJSONResult.errorMsg("上传出错..."); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return IMoocJSONResult.errorMsg("上传出错..."); }finally { if(fileOutputStream != null) { fileOutputStream.flush(); fileOutputStream.close(); } } //判断bgmId是否为空, //如果不为空,那就查询bgm的信息,并且合并视频生成新的视频 if(StringUtils.isNotBlank(bgmId)) { Bgm bgm = bgmService.queryBgmById(bgmId); String mp3InputPath = FILE_SPACE + bgm.getPath(); //System.out.println("1:mp3InputPath + "+mp3InputPath); MergeVideoMp3 tool = new MergeVideoMp3(FFMPEG_EXE); String videoInputPath = finalVideoPath; String videdoOutputName = UUID.randomUUID().toString() + ".mp4"; uploadPathDB = "/" + userId + "/video" + "/" +videdoOutputName; finalVideoPath = FILE_SPACE + uploadPathDB; tool.convertor(videoInputPath, mp3InputPath, videoSeconds, finalVideoPath); } //保存视频信息到数据库 Videos video = new Videos(); video.setAudioId(bgmId); video.setUserId(userId); video.setVideoSeconds((float)videoSeconds); video.setVideoHeight(videoHeight); video.setVideoWidth(videoWidth); video.setVideoDesc(desc); video.setVideoPath(uploadPathDB); video.setStatus(VideoStatusEnum.SUCCESS.value); video.setCreateTime(new Date()); String videoId = videoService.saveVideo(video); return IMoocJSONResult.ok(videoId); } @ApiOperation(value="上传封面", notes="上传封面的接口") @ApiImplicitParams({ @ApiImplicitParam(name="userId",value="用户id",required=true, dataType="String" ,paramType="form"), @ApiImplicitParam(name="videoId",value="视频主键id",required=true, dataType="String" ,paramType="form") }) @PostMapping(value="/uploadCover",headers="content-type=multipart/form-data") public IMoocJSONResult uploadCover(String userId,String videoId, @ApiParam(value="视频封面",required=true) MultipartFile file) throws Exception { if(StringUtils.isBlank(userId) ||StringUtils.isBlank(videoId) ) { return IMoocJSONResult.errorMsg("视频主键id和用户id不能为空..."); } //文件保存命名空间 //String fileSpace = "F:/imooc-video-gary"; //保存到数据库中的相对路径 String uploadPathDB = "/" + userId + "/video"; FileOutputStream fileOutputStream = null; InputStream inputStream = null; String finalCoverPath = ""; try { if( file != null ) { String fileName = file.getOriginalFilename(); if(StringUtils.isNoneBlank(fileName)) { //文件上传的最终保存路径 finalCoverPath = FILE_SPACE + uploadPathDB + "/" + fileName; //设置数据库保存的路径 uploadPathDB += ("/" + fileName); File outFile = new File(finalCoverPath); if(outFile.getParentFile()!=null || !outFile.getParentFile().isDirectory()) { //创建父文件夹 outFile.getParentFile().mkdirs(); } fileOutputStream = new FileOutputStream(outFile); inputStream = file.getInputStream(); IOUtils.copy(inputStream, fileOutputStream); } }else { return IMoocJSONResult.errorMsg("上传出错..."); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return IMoocJSONResult.errorMsg("上传出错..."); }finally { if(fileOutputStream != null) { fileOutputStream.flush(); fileOutputStream.close(); } } videoService.updateVideo(videoId, uploadPathDB); return IMoocJSONResult.ok(); } }
小程序端上传视频业务流程实现
当小程序端成功上传视频回调函数返回200时,上传视频封面
if (data.status == 200) { var videoId = data.data; //上传短视频封面 wx.showLoading({ title: '上传中...', }) wx.uploadFile({ url: serverUrl + '/video/uploadCover', formData: { userId: app.userInfo.id, videoId: videoId }, filePath: tmpCoverUrl, name: 'file', header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { var data = JSON.parse(res.data); wx.hideLoading(); if (data.status == 200) { wx.showToast({ title: '上传成功', icon: "success" }); wx.navigateBack({ delta:1, }) } else { wx.showToast({ title: '上传失败!', icon: "success" }); } } }) }else{ wx.showToast({ title: '上传失败!', icon:"success" }); }
const app = getApp() Page({ data: { bgmList:[], serverUrl:"", videoParams:{} }, onLoad: function (params) { var me = this; console.log(params); me.setData({ videoParams: params }); 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 }); } } }) }, 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: '上传中...', }) var serverUrl = app.serverUrl; wx.uploadFile({ url: serverUrl + '/video/upload', formData: { userId: app.userInfo.id, bgmId: bgmId, desc: desc, videoSeconds: duration, videoWidth: tmpheight, videoHeight: tmpwidth, }, filePath: tmpVideoUrl, name: 'file', header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { var data = JSON.parse(res.data); wx.hideLoading(); if (data.status == 200) { var videoId = data.data; //上传短视频封面 wx.showLoading({ title: '上传中...', }) wx.uploadFile({ url: serverUrl + '/video/uploadCover', formData: { userId: app.userInfo.id, videoId: videoId }, filePath: tmpCoverUrl, name: 'file', header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { var data = JSON.parse(res.data); wx.hideLoading(); if (data.status == 200) { wx.showToast({ title: '上传成功', icon: "success" }); wx.navigateBack({ delta:1, }) } else { wx.showToast({ title: '上传失败!', icon: "success" }); } } }) }else{ wx.showToast({ title: '上传失败!', icon:"success" }); } } }) } })
为避免在微信小程序端截不到视频封面的图片,即使用ffmpeg技术去实现
截图思路:截视频的第1s
bin>ffmpeg.exe -ss 00:00:01 -y -i new.mp4 -vframes 1 new2.jpg
package com.imooc.utils; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.List; /** * * @Description: 获取视频的信息 */ public class FetchVideoCover { // 视频路径 private String ffmpegEXE; public void getCover(String videoInputPath, String coverOutputPath) throws IOException, InterruptedException { // ffmpeg.exe -ss 00:00:01 -i spring.mp4 -vframes 1 bb.jpg List<String> command = new java.util.ArrayList<String>(); command.add(ffmpegEXE); // 指定截取第1秒 command.add("-ss"); command.add("00:00:01"); command.add("-y"); command.add("-i"); command.add(videoInputPath); command.add("-vframes"); command.add("1"); command.add(coverOutputPath); for (String c : command) { System.out.print(c + " "); } ProcessBuilder builder = new ProcessBuilder(command); Process process = builder.start(); InputStream errorStream = process.getErrorStream(); InputStreamReader inputStreamReader = new InputStreamReader(errorStream); BufferedReader br = new BufferedReader(inputStreamReader); String line = ""; while ( (line = br.readLine()) != null ) { } if (br != null) { br.close(); } if (inputStreamReader != null) { inputStreamReader.close(); } if (errorStream != null) { errorStream.close(); } } public String getFfmpegEXE() { return ffmpegEXE; } public void setFfmpegEXE(String ffmpegEXE) { this.ffmpegEXE = ffmpegEXE; } public FetchVideoCover() { super(); } public FetchVideoCover(String ffmpegEXE) { this.ffmpegEXE = ffmpegEXE; } public static void main(String[] args) { // 获取视频信息。 FetchVideoCover videoInfo = new FetchVideoCover("F:\\Garyffmpeg\\ffmpeg\\bin\\ffmpeg.exe"); try { videoInfo.getCover("e:\\19222\\Gary12.mp4","e:\\19222\\Gary1212.jpg"); } catch (Exception e) { e.printStackTrace(); } } }
上传视频流程整合视频截图功能
在VideoController.java中实现视频截图功能并保存到数据库中
//对视频封面进行截图 FetchVideoCover videoInfo = new FetchVideoCover(FFMPEG_EXE); videoInfo.getCover(finalVideoPath,FILE_SPACE + coverPathDB); //保存视频信息到数据库 Videos video = new Videos(); video.setAudioId(bgmId); video.setUserId(userId); video.setVideoSeconds((float)videoSeconds); video.setVideoHeight(videoHeight); video.setVideoWidth(videoWidth); video.setVideoDesc(desc); video.setVideoPath(uploadPathDB); video.setCoverPath(coverPathDB); video.setStatus(VideoStatusEnum.SUCCESS.value); video.setCreateTime(new Date());
package com.imooc.utils; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.List; /** * * @Description: 获取视频的信息 */ public class FetchVideoCover { // 视频路径 private String ffmpegEXE; public void getCover(String videoInputPath, String coverOutputPath) throws IOException, InterruptedException { // ffmpeg.exe -ss 00:00:01 -i spring.mp4 -vframes 1 bb.jpg List<String> command = new java.util.ArrayList<String>(); command.add(ffmpegEXE); // 指定截取第1秒 command.add("-ss"); command.add("00:00:01"); command.add("-y"); command.add("-i"); command.add(videoInputPath); command.add("-vframes"); command.add("1"); command.add(coverOutputPath); for (String c : command) { System.out.print(c + " "); } ProcessBuilder builder = new ProcessBuilder(command); Process process = builder.start(); InputStream errorStream = process.getErrorStream(); InputStreamReader inputStreamReader = new InputStreamReader(errorStream); BufferedReader br = new BufferedReader(inputStreamReader); String line = ""; while ( (line = br.readLine()) != null ) { } if (br != null) { br.close(); } if (inputStreamReader != null) { inputStreamReader.close(); } if (errorStream != null) { errorStream.close(); } } public String getFfmpegEXE() { return ffmpegEXE; } public void setFfmpegEXE(String ffmpegEXE) { this.ffmpegEXE = ffmpegEXE; } public FetchVideoCover() { super(); } public FetchVideoCover(String ffmpegEXE) { this.ffmpegEXE = ffmpegEXE; } public static void main(String[] args) { // 获取视频信息。 FetchVideoCover videoInfo = new FetchVideoCover("F:\\Garyffmpeg\\ffmpeg\\bin\\ffmpeg.exe"); try { videoInfo.getCover("e:\\19222\\Gary12.mp4","e:\\19222\\Gary1212.jpg"); } catch (Exception e) { e.printStackTrace(); } } }
package com.imooc.controller; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.util.Date; import java.util.UUID; import org.apache.commons.lang3.StringUtils; import org.apache.tomcat.util.http.fileupload.IOUtils; import org.springframework.beans.factory.annotation.Autowired; 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.enums.VideoStatusEnum; import com.imooc.pojo.Bgm; import com.imooc.pojo.Users; import com.imooc.pojo.Videos; import com.imooc.service.BgmService; import com.imooc.service.VideoService; import com.imooc.utils.FetchVideoCover; import com.imooc.utils.IMoocJSONResult; import com.imooc.utils.MergeVideoMp3; 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 extends BasicController{ @Autowired private BgmService bgmService; @Autowired private VideoService videoService; @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 uploadFace(String userId, String bgmId,double videoSeconds,int videoWidth,int videoHeight,String desc, @ApiParam(value="短视频",required=true) MultipartFile file) throws Exception { if(StringUtils.isBlank(userId)) { return IMoocJSONResult.errorMsg("用户id不能为空..."); } //文件保存命名空间 //String fileSpace = "F:/imooc-video-gary"; //保存到数据库中的相对路径 String uploadPathDB = "/" + userId + "/video"; String coverPathDB = "/" + userId + "/video"; FileOutputStream fileOutputStream = null; InputStream inputStream = null; String finalVideoPath = ""; try { if( file != null ) { String fileName = file.getOriginalFilename(); //Gary.mp4 使用spilt进行分割 String fileNamePrefix = fileName.split("\\.")[0]; if(StringUtils.isNoneBlank(fileName)) { //文件上传的最终保存路径 finalVideoPath = FILE_SPACE + uploadPathDB + "/" + fileName; //设置数据库保存的路径 uploadPathDB += ("/" + fileName); coverPathDB = coverPathDB + "/" + fileNamePrefix + ".jpg"; 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); } }else { return IMoocJSONResult.errorMsg("上传出错..."); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return IMoocJSONResult.errorMsg("上传出错..."); }finally { if(fileOutputStream != null) { fileOutputStream.flush(); fileOutputStream.close(); } } //判断bgmId是否为空, //如果不为空,那就查询bgm的信息,并且合并视频生成新的视频 if(StringUtils.isNotBlank(bgmId)) { Bgm bgm = bgmService.queryBgmById(bgmId); String mp3InputPath = FILE_SPACE + bgm.getPath(); //System.out.println("1:mp3InputPath + "+mp3InputPath); MergeVideoMp3 tool = new MergeVideoMp3(FFMPEG_EXE); String videoInputPath = finalVideoPath; String videdoOutputName = UUID.randomUUID().toString() + ".mp4"; uploadPathDB = "/" + userId + "/video" + "/" +videdoOutputName; finalVideoPath = FILE_SPACE + uploadPathDB; tool.convertor(videoInputPath, mp3InputPath, videoSeconds, finalVideoPath); } //对视频封面进行截图 FetchVideoCover videoInfo = new FetchVideoCover(FFMPEG_EXE); videoInfo.getCover(finalVideoPath,FILE_SPACE + coverPathDB); //保存视频信息到数据库 Videos video = new Videos(); video.setAudioId(bgmId); video.setUserId(userId); video.setVideoSeconds((float)videoSeconds); video.setVideoHeight(videoHeight); video.setVideoWidth(videoWidth); video.setVideoDesc(desc); video.setVideoPath(uploadPathDB); video.setCoverPath(coverPathDB); video.setStatus(VideoStatusEnum.SUCCESS.value); video.setCreateTime(new Date()); String videoId = videoService.saveVideo(video); return IMoocJSONResult.ok(videoId); } @ApiOperation(value="上传封面", notes="上传封面的接口") @ApiImplicitParams({ @ApiImplicitParam(name="userId",value="用户id",required=true, dataType="String" ,paramType="form"), @ApiImplicitParam(name="videoId",value="视频主键id",required=true, dataType="String" ,paramType="form") }) @PostMapping(value="/uploadCover",headers="content-type=multipart/form-data") public IMoocJSONResult uploadCover(String userId,String videoId, @ApiParam(value="视频封面",required=true) MultipartFile file) throws Exception { if(StringUtils.isBlank(userId) ||StringUtils.isBlank(videoId) ) { return IMoocJSONResult.errorMsg("视频主键id和用户id不能为空..."); } //文件保存命名空间 //String fileSpace = "F:/imooc-video-gary"; //保存到数据库中的相对路径 String uploadPathDB = "/" + userId + "/video"; FileOutputStream fileOutputStream = null; InputStream inputStream = null; String finalCoverPath = ""; try { if( file != null ) { String fileName = file.getOriginalFilename(); if(StringUtils.isNoneBlank(fileName)) { //文件上传的最终保存路径 finalCoverPath = FILE_SPACE + uploadPathDB + "/" + fileName; //设置数据库保存的路径 uploadPathDB += ("/" + fileName); File outFile = new File(finalCoverPath); if(outFile.getParentFile()!=null || !outFile.getParentFile().isDirectory()) { //创建父文件夹 outFile.getParentFile().mkdirs(); } fileOutputStream = new FileOutputStream(outFile); inputStream = file.getInputStream(); IOUtils.copy(inputStream, fileOutputStream); } }else { return IMoocJSONResult.errorMsg("上传出错..."); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return IMoocJSONResult.errorMsg("上传出错..."); }finally { if(fileOutputStream != null) { fileOutputStream.flush(); fileOutputStream.close(); } } videoService.updateVideo(videoId, uploadPathDB); return IMoocJSONResult.ok(); } }
const app = getApp() Page({ data: { bgmList:[], serverUrl:"", videoParams:{} }, onLoad: function (params) { var me = this; console.log(params); me.setData({ videoParams: params }); 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 }); } } }) }, 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: '上传中...', }) var serverUrl = app.serverUrl; wx.uploadFile({ url: serverUrl + '/video/upload', formData: { userId: app.userInfo.id, bgmId: bgmId, desc: desc, videoSeconds: duration, videoWidth: tmpheight, videoHeight: tmpwidth, }, filePath: tmpVideoUrl, name: 'file', header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { var data = JSON.parse(res.data); wx.hideLoading(); if (data.status == 200) { wx.showToast({ title: '上传成功!', icon: "success" }); // 上传成功后跳回之前的页面 wx.navigateBack({ delta: 1 }) /* var videoId = data.data; //上传短视频封面 wx.showLoading({ title: '上传中...', }) wx.uploadFile({ url: serverUrl + '/video/uploadCover', formData: { userId: app.userInfo.id, videoId: videoId }, filePath: tmpCoverUrl, name: 'file', header: { 'content-type': 'application/json' // 默认值 }, success: function (res) { var data = JSON.parse(res.data); wx.hideLoading(); if (data.status == 200) { wx.showToast({ title: '上传成功', icon: "success" }); wx.navigateBack({ delta:1, }) } else { wx.showToast({ title: '上传失败!', icon: "success" }); } } }) */ }else{ wx.showToast({ title: '上传失败!', icon:"success" }); } } }) } })