〇、前情提要

完成了视频上传,接下来是给上传的视频保存一张同名的jpg文件在同样文件夹中,并且获取到视频的分辨率。
macOS Catalina 10.15.1
ffmpeg version 4.3.1
Eclipse

参考:

  1. 【FFmpeg】mac系统安装FFmpeg并对视频进行转码、对视频截图、对视频压缩
    https://blog.csdn.net/weixin_43210113/article/details/109802138
  2. ✨java+ffmpeg使用记录
    https://blog.csdn.net/u011424614/article/details/108006131
  3. Download FFmpeg
    http://ffmpeg.org/download.html
  4. 【王仔编程】22期.FFmpeg截取视频帧
    https://www.bilibili.com/video/BV16t411T7YX?from=search&seid=6597950623021114962
  5. 简单粗暴:Java 使用 FFmpeg 获取视频的分辨率 Java获取视频的时长 Java获取视频的编码格式
    https://blog.csdn.net/q2450751976/article/details/103993096
  6. Java - split()函数和trim()函数的用法
    https://blog.csdn.net/caroline_wendy/article/details/24465141
  7. 我的文章:【FFmpeg】java实现利用ffmpeg视频上传转码同时截取一帧保存为同名图片,并获取视频分辨率(补充部分)
    https://blog.csdn.net/weixin_43210113/article/details/110425390

一、基础知识

参考:
Java使用FFmpeg处理视频文件指南
https://blog.csdn.net/mickle_zhang/article/details/105481917

安装

参考我以前的文章,对FFmpeg基础操作:
【FFmpeg】mac系统安装FFmpeg并对视频进行转码、对视频截图
https://blog.csdn.net/weixin_43210113/article/details/109802138

安装完毕后可以不在项目中导包了


二、✨java+ffmpeg使用记录

再次感谢该文作者,解决了我入门关。

参考:
java+ffmpeg使用记录
https://blog.csdn.net/u011424614/article/details/108006131

创建一个ffmpeg文件夹

  • 执行命令的任务工具类 CommandTask.java
    用来编写执行command任务的工具
  • 测试类 FFmpegTest.java
    用来编写用ffmpeg执行的语句

创建执行命令的任务工具类 CommandTask.java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;/*** 执行命令的任务工具* */
public class CommandTask {/*** 执行命令* @param command 命令* */public static void exeute(List<String> command) throws IOException {// 执行命令ProcessBuilder processBuilder = new ProcessBuilder(command);Process process = processBuilder.start(); // 开始执行InputStream errorStream = process.getErrorStream(); // 字节流InputStreamReader inputStreamReader = new InputStreamReader(errorStream); // 字节流和字符流的中介BufferedReader bufferedReader = new BufferedReader(inputStreamReader); // 字符流String line = "";while ((line = bufferedReader.readLine()) != null){System.out.println(line); // 输出转换过程}// 关闭流if(bufferedReader != null){ bufferedReader.close(); }if(inputStreamReader != null){ inputStreamReader.close(); }if(errorStream != null){ errorStream.close(); }}
}

创建测试类 FFmpegTest.java

package com.demo.ffmpeg;import java.io.IOException;
import java.util.LinkedList;
import java.util.List;public class FFmpegTest {public static void main(String[] args) {String ffmpegPath = "C:\\ffmpeg20200809\\bin\\ffmpeg.exe";String inputVideoPath = "C:\\ffmpeg20200809\\bin\\input.mp4";String outputVideoPath = "C:\\ffmpeg20200809\\bin\\output.avi";// 组装 格式转换 命令List<String> command = new LinkedList<>();command.add(ffmpegPath);command.add("-i");command.add(inputVideoPath);command.add(outputVideoPath);try {// 执行命令CommandTask.exeute(command);} catch (IOException e) {e.printStackTrace();}}
}

其中

String ffmpegPath = "FFmpeg程序的执行路径";
String inputVideoPath = "输入文件的存放路径";
String outputVideoPath = "输出文件的存放路径";

ffmpegPath在MacOS安装好FFmpeg后,可以在控制台中通过which ffmpeg命令获取FFmpeg程序的执行路径

于是我获得的FFmpeg程序的执行路径为/usr/local/bin/ffmpeg
根据我的电脑所写的为

String ffmpegPath = "/usr/local/bin/ffmpeg";
String inputVideoPath = "/Users/junla/Downloads/test.mp4";
String outputVideoPath = "/Users/junla/Downloads/bbb.mov";

完整代码为

package ffmpeg;import java.io.IOException;
import java.util.LinkedList;
import java.util.List;public class FFmpegTest {public static void main(String[] args) {Video_Transcoding();}// 视频转码public static void Video_Transcoding() {String ffmpegPath = "/usr/local/bin/ffmpeg";String inputVideoPath = "/Users/junla/Downloads/test.mp4";String outputVideoPath = "/Users/junla/Downloads/bbb.mov";// 组装 格式转换 命令List<String> command = new LinkedList<>();command.add(ffmpegPath);command.add("-i");command.add(inputVideoPath);command.add(outputVideoPath);try {// 执行命令CommandTask.exeute(command);} catch (IOException e) {e.printStackTrace();}}}

运行后

控制台输出与直接在终端内测试结果相同

成功在下载里将其转换了格式,为此


三、FFmpeg截取视频帧

截图的ffmpeg代码

ffmpeg路径 -i 视频路径 -y -f image2 -ss 1 要保存的图片路径

参考:
【王仔编程】22期.FFmpeg截取视频帧
https://www.bilibili.com/video/BV16t411T7YX?from=search&seid=6597950623021114962

用例

截图成功

FFmpegUtil.java

public class FFmpegUtil{@Value("ffmpeg所在路径")private String FFMPEG_PATH;@Value("图片保存路径")private String COVER_PATH;public String videoCatchImg(String videoPath){List<String> commands = new java.util.ArrayList<String>();commands.add(FFMPEG_PATH);// 输入文件commands.add("-i");commands.add(videoPath);// 输出文件若存在可以覆盖commands.add("-y");// 指定图片编码格式commands.add("-f");commands.add("image2");// 设置截取视频第一秒时的画面commands.add("-ss");commands.add("1");// 截取的图片路径String[] paths = videoPath.split("/");commands.add(COVER_PATH + paths[paths.length-1] + "_cover.jpg");try{ProcessBuilder builder = new ProcessBuilder();builder.command(commands);Process start = builder.start();//等命令执行完,因为后面要上传图片start.waitFor();}catch(Exception e){e.printStackTrace();}return COVER_PATH + paths[paths.length-1] + "_cover.jpg";}
}

VideoController.java

public ApiResponse videoUpload(@RequestParam("file")MultipartFile file)throws IOException{//上传封面String coverPath = fFmpegUtil.videoCathImg(videoUrl);Response coverResponse = qiniuService.uploadFile(new File(coverPath));QiNiuPutRet coverPutRet = gson.fromJson(coverResponse.bodyString(),QiNiuPutRet.class);String videoCoverUrl = qiniuPrefix + coverPutRet.key;
}

总结

视频中的VideoController.javaCommandTask.java用法相同。
FFmpegUtil.javaFFmpegTest.java用法相同。
于是仿照FFmpegUtil.java的代码有了以下的视频截图代码:

 // 视频截图public static void videoCatchImg(String test){/*** ffmpeg路径 -i 视频路径 -y -f image2 -ss 1 要保存的图片路径*/String ffmpegPath = "/usr/local/bin/ffmpeg";String inputVideoPath = "/Users/junla/Downloads/" + test + ".mp4";String outputPicPath = "/Users/junla/Downloads/" + test + ".jpg";List<String> commands = new java.util.ArrayList<String>();commands.add(ffmpegPath);// 输入文件commands.add("-i");commands.add(inputVideoPath);// 输出文件若存在可以覆盖commands.add("-y");// 指定图片编码格式commands.add("-f");commands.add("image2");// 设置截取视频第一秒时的画面commands.add("-ss");commands.add("1");// 截取的图片路径commands.add(outputPicPath);try{// 执行命令CommandTask.exeute(commands);}catch(Exception e){e.printStackTrace();}}

最终实现了上传视频的同时,也生成了视频的略缩图。当然是在上传文件的同时传入同名参数,利用ffmpeg保存。


四、获取视频分辨率

参考

参考:
简单粗暴:Java 使用 FFmpeg 获取视频的分辨率 Java获取视频的时长 Java获取视频的编码格式
https://blog.csdn.net/q2450751976/article/details/103993096


import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;/*** @description: ffmepg获取视频时长* @create: 2020/01/15 17:28*/
public class FFmpeg获取视频时长 {public static void main(String[] args) {//ffmepg工具地址String ffmpegPath = "F:\\ffmepg\\ffmpeg.exe";//视频文件地址String videoPath = "F:\\ffmepg\\video.mp4";
//        拼接cmd命令语句StringBuffer buffer = new StringBuffer();buffer.append(ffmpegPath);//注意要保留单词之间有空格buffer.append(" -i ");buffer.append(videoPath);
//        执行命令语句并返回执行结果try {Process process = Runtime.getRuntime().exec(buffer.toString());InputStream in = process.getErrorStream();BufferedReader br = new BufferedReader(new InputStreamReader(in));String line ;while((line=br.readLine())!=null) {if(line.trim().startsWith("Duration:")){//根据字符匹配进行切割System.out.println("视频时间 = " + line.trim().substring(0,line.trim().indexOf(",")));}//一般包含fps的行就包含分辨率if(line.contains("fps")){//根据String definition = line.split(",")[2];definition = definition.trim().split(" ")[0];System.out.println("分辨率 = " + definition);}}}catch (Exception e){e.printStackTrace();}}
}

分析代码中重要部分

if(line.contains("fps")){definition = line.split(",")[2];definition = definition.trim().split(" ")[0];System.out.println(definition);
}

参考:
Java - split()函数和trim()函数的用法
https://blog.csdn.net/caroline_wendy/article/details/24465141
具体参考Java API:
http://docs.oracle.com/javase/6/docs/api/java/lang/String.html

  • split("")[]
    split()函数是根据参数如",", “-”, " "等, 分割String字符串, 返回一个String的数组(String[]), 可以通过索引指定元素.
    如果未找到, 则返回整个String字符串, 作为String数组(String[])的第0个元素.

  • trim().split("")[]
    trim()函数是去掉String字符串的首尾空格;

分析-i 输出的input内容

definition = line.split(",")[2];

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'C:\apache-tomcat-9.0.22\webapps\TAYPro\upload\pb4lwcIES1GHNUg.mp4':Metadata:major_brand     : mp42minor_version   : 0compatible_brands: mp42isomavc1creation_time   : 2020-11-10T10:44:51.000000Zencoder         : HandBrake 0.9.9 2013051800Duration: 00:00:16.73, start: 0.000000, bitrate: 3782 kb/sStream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 3779 kb/s, 30 fps, 30 tbr, 90k tbn, 180k tbc (default)Metadata:creation_time   : 2020-11-10T10:44:51.000000Zencoder         : JVT/AVC Coding
Stream mapping:Stream #0:0 -> #0:0 (h264 (native) -> mjpeg (native))
Press [q] to stop, [?] for help

其中找到fps所在的Stream开头的行,通过,可拆分为

Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661),yuv420p(tv,bt709),1920x1080 [SAR 1:1 DAR 16:9],3779 kb/s,30 fps,30 tbr,90k tbn,180k tbc (default)

其中[3]为想要的1920x1080 [SAR 1:1 DAR 16:9],

definition = definition.trim().split(" ")[0];
通过trim()删除首尾的空格,再通过空格拆分.split(" ")[]得到

 1920x1080 [SAR 1:1DAR16:9],

取[0]

✨注意:每个视频输出的信息并不相同,需要换一个获取的方式
由于此部分太长…另写一篇文章请见:

我的文章:
【FFmpeg】java实现利用ffmpeg视频上传转码同时截取一帧保存为同名图片,并获取视频分辨率(补充部分)
https://blog.csdn.net/weixin_43210113/article/details/110425390

放进我的FFmpegTest.java

// 视频分辨率public static String videoInfo(String media_rand_name){String path = "视频路径前缀";String ffmpegPath = "ffmpeg路径";String inputVideoPath = path + media_rand_name + ".mp4";StringBuffer buffer = new StringBuffer();buffer.append(ffmpegPath);//注意要保留单词之间有空格buffer.append(" -i ");buffer.append(inputVideoPath);String definition = null;String definition1,definition2,pix = null;//执行命令语句并返回执行结果try {Process process = Runtime.getRuntime().exec(buffer.toString());InputStream in = process.getErrorStream();BufferedReader br = new BufferedReader(new InputStreamReader(in));String line ;while((line=br.readLine())!=null) {//一般包含fps的行就包含分辨率if(line.contains("fps")){//根据x分割 trim删去首尾空格definition1 = line.split("x")[1];definition2 = line.split("x")[2];String[] find1 = definition1.trim().split(" ");String find2 = definition2.trim().split(" ")[0];pix = find1[find1.length-1]+"x"+findNum(find2);}}}catch (Exception e){e.printStackTrace();}return pix;}

测试

数据库中成功存入(配合需要修改servlet里的内容)


【FFmpeg】java实现利用ffmpeg视频上传转码同时截取一帧保存为同名图片,并获取视频分辨率相关推荐

  1. 无广告的免费视频存储空间并提供视频上传转码的功能,很不错的哦

    我们把做好的视频,存放在第三方视频网站平台,再调用时,视频一般都有50秒,甚至70秒的广告,这就看观看者,带来非常难受的体验. 示例1: 示例2: 示例3: 示例4: 广告过长,会影响观看者的耐心,有 ...

  2. 封装一个完整版的uniapp图片和视频上传组件,拿来即用,可进行图片视频切换,可自定义上传按钮样式,删除按钮样式,可单独上传图片或者视频,可限制上传数量

    第一步 components里面新建一个manyImgUpload.vue组件,将以下代码放入 以下代码中需要你改的地方 uni.uploadFile中的参数,url为你公司的上传接口.files为你 ...

  3. 阿里云视频上传视频获取进度条问题(使用session方案,获取进度一直为0的解决方案)补充:前后端分离项目中获取进度解决方案

    1.场景描述: 之前用阿里云上传视频,前端反应上传视频经常出现获取视频url失败问题.但是接口我测过很多遍都是没有问题的.后台这边提供了一个视频上传的接口返回一个videoId,还提供了一个根据vid ...

  4. 网站实现视频上传、转码、截图及在线播放功能

    网站实现视频上传.转码.截图及在线播放功能 时间 2014-10-15 22:46:05 IT社区推荐资讯 原文   http://itindex.net/detail/51396-网站-视频-上传 ...

  5. 阿里云VOD 视频点播(二)、VUE视频上传,视频播放

    一,VUE视频上传 (1),视频上传引入的js文件,在index.html文件里面引入js,如下图 js文件在官网可以下载然后放在自己的项目里面,下载下面的js文件引入项目 JavaScript上传S ...

  6. 2亿日活,日均千万级视频上传,快手推荐系统如何应对技术挑战?

    据移动应用数据分析平台 App Annie 在 7 月 10 日发布的 2019 年第二季度最新移动应用市场报告显示,快手在 2019 年第二季度消费额排名中位于第四,成为中国最赚钱的短视频平台之一. ...

  7. java实现视频上传和播放SpringMVC + Mybatis + ckplayer+ffmpeg+mencoder

    参考了很多大牛的文章,终于成功了,先感谢以下大牛,然后从前辈身上获利很多,我也应该把自己成功的经验奉献出来 ffmpeg参考:http://www.cnblogs.com/findingsea/arc ...

  8. java 上传视频并播放_java实现视频上传和播放..doc

    java实现视频上传和播放. Java实现视频网站的视频上传.视频转码.视频关键帧抽图, 及视频播放功能 视频网站中提供的在线视频播放功能,播放的都是FLV格式的文件,它是Flash动画文件,可通过F ...

  9. java上传视频代码下载_java 实现视频上传

    [实例简介] java上传视频转码播放的一个demo,实现java上传视频.转码.截图和播放功能 [实例截图] [核心代码] java视频上传,转码,播放实现 └── java视频上传,转码,播放实现 ...

最新文章

  1. CBM——IT与业务融合的重要途径
  2. JAVA线程池ScheduledExecutorService周期性地执行任务 与单个Thread周期性执行任务的异常处理...
  3. HttpWatch是强大的网页数据分析工具
  4. hdu1007最近点对问题(分冶java)
  5. 每次新增页面复制粘贴?100多行源码的 element-ui 的新增组件功能教你解愁
  6. drools的可升级读写锁探究
  7. Exchange 2007的自动发现
  8. 数据:以太坊2.0合约余额新增1.28万ETH
  9. Java基础(二)——面向对象
  10. mysql中的事物处理
  11. 悄悄地我走了 著名的非自然死亡
  12. 出租车计费器的Verilog语言简单完成
  13. 深度卷积神经网络最新进展综述
  14. flyway命名规范
  15. Python数据分析学习系列 九 绘图和可视化
  16. 1227: 苹果和虫子
  17. CSDN小伙伴们苦苦寻找的最全的微软msdn原版windows系统镜像和office下载地址集锦
  18. 微信小程序前后端交互案例
  19. 硕士毕业论文写不出来导致严重焦虑,怎么办?
  20. 实现一个导航栏,鼠标滑入滑出效果展示。点击每个导航栏菜单,分别弹出对应内容

热门文章

  1. 中科院考研经历①--一轮复习总结及二轮复习规划
  2. BZOJ2560 串珠子
  3. 基于STM32单片机的大气压强检测仪(Proteus仿真+程序)
  4. 小程序的代理加盟创业机会在哪里?
  5. js用滚动条模拟横向时间轴
  6. 穿刺线夹定额套什么子目合适?
  7. python win32转pdf 横版_Python 小技巧之 Office 文件转 PDF
  8. php会员模版,会员中心模板
  9. 22岁转行新手学了34天Python还没入门的原因:学习路线不对!
  10. 计算机专业过硬的大学,高质量文书+过硬背景,迎来美国东北大学计算机专业硕士offer...