标签:users tst create edr arraylist gms over stat 相对路径
视音频处理工具
二、ffmpeg与java的结合
首先在com.imooc.utils新建FFMpegTest类
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 /* * java调用cmd命令 */ 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("D:\\ffmpeg\\bin\\ffmpeg.exe"); try { ffmpeg.convertor("C:\\Users\\Administrator\\Pictures\\单挑.mp4", "C:\\Users\\Administrator\\Pictures\\斗牛.avi"); } catch (Exception e) { e.printStackTrace(); } } }
三、java合并视音频
MergeVideoMp3.class
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 苏州大裤衩.mp4 -i bgm.mp3 -t 7 -y 新的视频.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("D:\\ffmpeg\\bin\\ffmpeg.exe"); try { ffmpeg.convertor("C:\\鬼.mp4", "C:\\music.mp3", 7.1, "C:\\这是通过java生产的视频.mp4"); } catch (Exception e) { e.printStackTrace(); } } }
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 -y output.avi List<String> command = new ArrayList<>(); command.add(ffmpegEXE); command.add("-i"); command.add(videoInputPath); 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) { FFMpegTest ffmpeg = new FFMpegTest("D:\\ffmpeg\\bin\\ffmpeg.exe"); try { ffmpeg.convertor("C:\\鬼.mp4", "C:\\北京北京.avi"); } catch (Exception e) { e.printStackTrace(); } } }
四、小程序上传视频后调用视频处理工具联调
五、保存视频信息到数据库
六、截图(视频封面)保存到数据库中
1、后端接口的开发
@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 { //Alt + shirt + R if (StringUtils.isBlank(videoId) || StringUtils.isBlank(userId)) { return IMoocJSONResult.errorMsg("视频主键id和用户id不能为空..."); } //文件保存的空间 String fileSpace = "D:/imooc_videos_dev"; //保存到数据库的相对路径 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 = fileSpace + 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); } } } catch (Exception e) { e.printStackTrace(); }finally { if(fileOutputStream != null) { fileOutputStream.flush(); fileOutputStream.close(); } } videoService.updateVideo(videoId, uploadPathDB); return IMoocJSONResult.ok(); }
2、前端js的开发
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); 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(res) { var data = JSON.parse(res.data); wx.hideLoading(); if (data.status == 200) { wx.showToast({ title: ‘上传成功!~~‘, icon: "success" }); } else { wx.showToast({ title: ‘上传失败!~~‘, icon: "success" }) } } }); wx.navigateBack({ delta: 1, }) } else { wx.showToast({ title: ‘上传失败!~~‘, icon: "success" }) } } }) }
在用手机端进行联调时,上传封面功能并不能实现,这是微信小程序的一个小坑。需要用ffmpeg去截视频某一帧的图才行。
七、使用ffmpeg生成截图
生成截图工具类
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:06"); 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("D:\\ffmpeg\\bin\\ffmpeg.exe"); try { videoInfo.getCover("c:\\北京北京.avi","c:\\北京.jpg"); } catch (Exception e) { e.printStackTrace(); } } }
在controller补充对视频的截图
@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 if (StringUtils.isBlank(userId)) { return IMoocJSONResult.errorMsg("用户id不能为空..."); } //文件保存的空间 String fileSpace = "D:/imooc_videos_dev"; //保存到数据库的相对路径 String uploadPathDB = "/" + userId + "/video" ; String coverPathDB = "/" + userId + "/video"; FileOutputStream fileOutputStream = null; InputStream inputStream = null; String finalVideoPath = ""; try { if(file != null ) { String fileName = file.getOriginalFilename(); String fileNamePrefix = fileName.split("\\.")[0]; if(StringUtils.isNoneBlank(fileName)) { //文件上传的最终路径 finalVideoPath = fileSpace + 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); } } } catch (Exception e) { e.printStackTrace(); }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(); MergeVideoMp3 tool = new MergeVideoMp3(FFMPEG_EXE); String videoInputPath = finalVideoPath; String videoOutputName = UUID.randomUUID().toString() + ".mp4"; uploadPathDB = "/" + userId + "/video" + "/" + videoOutputName; finalVideoPath = FILE_SPACE + uploadPathDB; tool.convertor(videoInputPath, mp3InputPath, videoSeconds, finalVideoPath); } System.out.println("uploadPathDB=" + uploadPathDB); System.out.println("finalVideoPath=" + 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); // System.out.println("desc:"+desc); return IMoocJSONResult.ok(videoId); }
标签:users tst create edr arraylist gms over stat 相对路径
原文地址:https://www.cnblogs.com/bozzzhdz/p/9743739.html