「小程序JAVA实战」小程序视频封面处理(48)
转自:https://idig8.com/2018/09/16/xiaochengxujavashizhanxiaochengxushipinfengmianchuli47/
截图这块,在微信小程序工具上,上传视频是有返回截图的,但是万万没想到在手机端是不能用的。所以还得借助ffmpge工具来完成,方式很简单。源码:https://github.com/limingios/wxProgram.git 中wx-springboot 和 No.15
例子
注意建议使用jpg的格式,png的格式比较大
ffmpeg -y -i a.mp4 -ss 00:00:01 -vframes 1 new.jpg
java代码工具类编写
spring boot common中加入FetchVideoCover
package com.idig8.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("c:\\ffmpeg\\bin\\ffmpeg.exe");
try {
videoInfo.getCover("c:\\北京北京.avi","c:\\北京.jpg");
} catch (Exception e) {
e.printStackTrace();
}
}
}
功能实现
视频转化完毕后,完成视频截图的转化,并保存在数据库中
package com.idig8.controller;
import java.io.File;
import java.util.Date;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.idig8.pojo.Bgm;
import com.idig8.pojo.Videos;
import com.idig8.service.BgmService;
import com.idig8.service.VideoService;
import com.idig8.utils.FetchVideoCover;
import com.idig8.utils.JSONResult;
import com.idig8.utils.MergeVideoMp3;
import com.idig8.utils.enums.VideoStatusEnum;
import com.idig8.utils.file.FileUtil;
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 videosService;
@Value("${server.file.path}")
private String fileSpace;
@Value("${server.ffmpeg.path}")
private String ffmpegexe;
@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 JSONResult upload(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 JSONResult.errorMsg("用户id不能为空...");
}
// 文件保存的命名空间
String fileName = file.getOriginalFilename();
// 保存到数据库中的相对路径
String path = "";
String videOutPath = "";
String ImagePath = "";
try {
path = FileUtil.uploadFile(file.getBytes(), fileSpace, fileName);
} catch (Exception e) {
e.getStackTrace();
return JSONResult.errorMsg(e.getMessage());
}
if(StringUtils.isNotBlank(bgmId)){
Bgm bgm = bgmService.queryBgmById(bgmId);
String mp3BgmPath = fileSpace + bgm.getPath();
MergeVideoMp3 mergeVideoMp3 = new MergeVideoMp3(ffmpegexe);
String videOutPathName = UUID.randomUUID().toString()+".mp4";
File targetFile = new File(fileSpace + userId);
if (!targetFile.exists()) {
targetFile.mkdirs();
}
videOutPath = "/"+userId+"/"+videOutPathName;
String videoInput = fileSpace +path;
mergeVideoMp3.convertor(videoInput, mp3BgmPath, videoSeconds, fileSpace +videOutPath);
}else{
videOutPath = path;
}
ImagePath = "/"+userId+"/"+UUID.randomUUID().toString()+".jpg";;
FetchVideoCover fetchVideoCover = new FetchVideoCover(ffmpegexe);
fetchVideoCover.getCover(fileSpace +videOutPath, fileSpace +ImagePath);
Videos videos = new Videos();
videos.setAudioId(bgmId);
videos.setCreateTime(new Date());
videos.setVideoDesc(desc);
videos.setId(UUID.randomUUID().toString());
videos.setUserId(userId);
videos.setVideoHeight(videoHeight);
videos.setVideoWidth(videoWidth);
videos.setVideoPath(videOutPath);
videos.setCoverPath(ImagePath);
videos.setStatus(VideoStatusEnum.SUCCESS.value);
videosService.saveVideo(videos);
return JSONResult.ok(path);
}
}
小程序中的chooseBgm.js 增加友好提示
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',
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
});
} else if (res.data.status == 502) {
wx.showToast({
title: res.data.msg,
duration: 2000,
icon: "none",
success: function () {
wx.redirectTo({
url: '../userLogin/login',
})
}
});
}
}
})
},
upload:function(e){
var me = this;
var datasParams = me.data.videoParams;
var bgmId = e.detail.value.bgmId;
var desc = e.detail.value.desc;
console.log("bgmId:"+bgmId);
console.log("desc:" + desc);
var tempDuration = datasParams.tempDuration;
var tempHeight = datasParams.tempHeight;
var tempWidth = datasParams.tempWidth;
var tempSize = datasParams.tempSize;
var tempFilePath = datasParams.tempFilePath;
var thumbTempFilePath = datasParams.thumbTempFilePath;
var userId = app.userInfo.id;
wx.showLoading({
title: '请等待...',
});
var serverUrl = app.serverUrl;
// 调用后端
wx.uploadFile({
url: serverUrl + '/video/upload',
filePath: tempFilePath,
formData:{
userId: userId,
bgmId: bgmId,
videoSeconds: tempDuration,
videoWidth: tempWidth,
videoHeight: tempHeight,
desc: desc,
},
name: 'file',
success:function(res){
console.log(res);
var status = JSON.parse(res.data).status;
debugger;
wx.hideLoading();
if (status == 200) {
wx.showToast({
title: "上传成功~!",
icon: 'none',
duration: 3000
})
} else if (status == 500) {
wx.showToast({
title: res.data.msg,
icon: 'none',
duration: 3000
})
}
}
})
}
})
PS:截图也是通过ffmpge的方式,小程序工具的坑很多,官网都没介绍返回截图,但是小程序工具就返回截图了,这就是个坑。
「小程序JAVA实战」小程序视频封面处理(48)的更多相关文章
- 「小程序JAVA实战」小程序首页视频(49)
转自:https://idig8.com/2018/09/21/xiaochengxujavashizhanxiaochengxushouyeshipin48/ 视频显示的内容是视频的截图,用户的头像 ...
- 「小程序JAVA实战」小程序的flex布局(22)
转自:https://idig8.com/2018/08/09/xiaochengxu-chuji-22/ 之前已经把小程序的框架说完了,接下来说说小程序的组件,在说组件之前,先说说布局吧.源码:ht ...
- 「小程序JAVA实战」小程序的留言和评价功能(70)
转自:https://idig8.com/2018/10/28/xiaochengxujavashizhanxiaochengxudeliuyanhepingjiagongneng69/ 目前小程序这 ...
- 「小程序JAVA实战」小程序的举报功能开发(68)
转自:https://idig8.com/2018/09/25/xiaochengxujavashizhanxiaochengxudeweixinapicaidancaozuo66-2/ 通过点击举报 ...
- 「小程序JAVA实战」小程序的个人信息作品,收藏,关注(66)
转自:https://idig8.com/2018/09/24/xiaochengxujavashizhanxiaochengxudegerenxinxizuopinshoucangguanzhu65 ...
- 「小程序JAVA实战」小程序的关注功能(65)
转自:https://idig8.com/2018/09/24/xiaochengxujavashizhanxiaochengxudeguanzhugongneng64/ 在个人页面,根据发布者个人和 ...
- 「小程序JAVA实战」小程序的视频点赞功能开发(62)
转自:https://idig8.com/2018/09/24/xiaochengxujavashizhanxiaochengxudeshipindianzangongnengkaifa61/ 视频点 ...
- 「小程序JAVA实战」小程序的springboot后台拦截器(61)
转自:https://idig8.com/2018/09/24/xiaochengxujavashizhanxiaochengxudespringboothoutailanjieqi60/ 之前咱们把 ...
- 「小程序JAVA实战」小程序上传短视频(46)
转自:https://idig8.com/2018/09/14/xiaochengxujavashizhanxiaochengxushangchuanduanshipin45/ 个人信息:用户上传短视 ...
随机推荐
- 【Demo】Tree.js实例
Three.js是通过对WebGL接口的封装与简化而形成的一个易用的图形库. 简单点的说法:WebGL可以看成是浏览器给我们提供的接口,在javascript中可以直接用这些API进行3D图形的绘制: ...
- Oracle 9i & 10g编程艺术-深入数据库体系结构-学习笔记(持续更新中)
--20170322 --1.0 --更新表的统计信息begin dbms_stats.set_table_stats(user,'EMP',numrows => 10000);end; beg ...
- offsetParent.scrollTop IE下一直报错,说“缺少对象”
<div style="position:fiexd; top:135px;_position: absolute; right: 0pt; _top:expression_r(off ...
- 045——VUE中组件之父组件使用scope定义子组件模板结构
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 201621123006 《Java程序设计》第13周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 为你的系统增加网络功能(购物车.图书馆管理.斗地主等)-分组完成 为了让你的系统可以被多个用户通过网 ...
- 解析xml(当节点中有多个子节点)
概要:解析一个xml,当一个节点中又包含多个子节点如何解析,对比一个节点中不包括其他节点的情况. 一,xml样例 <cisReports batNo="查询批次号" unit ...
- IIS经典模式与集成模式
在IIS7.0中Web应用程序有两种配置形式:经典和集成 经典模式 经典模式是为了与之前的版本兼容,使用ISAPI扩展来调用ASP.NET运行库,原先运行于IIS6.0下的Web应用程序迁移到IIS7 ...
- github打开慢,页面打不开,请求老是失败问题修复总结
感谢老铁 QQ(1218624820) 提供的方法建议 原因来自于DNS污染, 到下面的目录进行修改文件 C:\Windows\System32\drivers\etc 在后面粘贴下面的信息 192. ...
- lambda,reduce,filter用法
1.lambda的用法 sum = lambda arg1,arg2:arg1+arg2 sum(10,20) --->30 | | 实际上是def sum(arg1,arg2) return ...
- LOJ10131. 「一本通 4.4 例 2」暗的连锁【树上差分】
LINK solution 很简单的题 你就考虑实际上是对每一个边求出两端节点分别在两个子树里面的附加边的数量 然后这个值是0第二次随便切有m种方案,如果这个值是1第二次只有一种方案 如果这个值是2或 ...