application.properties

server.port=8908
file.uploadfolder=D:/school/
#分片文件临时目录
file.chunkfolder=D:/school/tempfile/ffmpegpath=D:/tools/ffmpeg-4.2-win64-static/bin/ffmpeg.exe
officehome=C:/Program Files/LibreOffice
logging.file.name=E:/logs/schoolfile.txt#单个文件最大500M(524288000)
spring.servlet.multipart.max-file-size=100MB
#设置总上传数据总大小
spring.servlet.multipart.max-request-size=10000MB#打印日志的两种方式第一种可以指定包名,第二种都可以打印
logging.level.com.xhkjedu.mapper=debugserver.tomcat.uri-encoding=UTF-8
server.tomcat.accesslog.encoding=utf-8

ConfigKey配置文件读取类

package com.xhkjedu.config;import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;/*** @description 配置文件读取类* @date 2020/5/20 14:51**/
@Component
public class ConfigKey {public static String uploadfolder;//文件保存文件夹public static String tempschool;//分片上传临时文件保存目录public static String ffmpegpath;//ffmpeg目录public static String officehome;//office目录@Value("${file.uploadfolder}")public void setUploadfolder(String uploadfolder) {this.uploadfolder = uploadfolder;}@Value("${file.chunkfolder}")public void setTempschool(String tempschool) {this.tempschool = tempschool;}@Value("${ffmpegpath}")public void setFfmpegpath(String ffmpegpath){ this.ffmpegpath = ffmpegpath;}@Value("${officehome}")public static void setOfficehome(String officehome) {ConfigKey.officehome = officehome;}
}

VideoUtil视频工具类

package com.xhkjedu.utils;import com.xhkjedu.config.ConfigKey;
import com.xhkjedu.vo.VideoVo;
import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.EncoderException;
import it.sauronsoftware.jave.MultimediaInfo;
import it.sauronsoftware.jave.VideoInfo;
import lombok.extern.slf4j.Slf4j;import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;/*** @ClassName VideoUtil* Description TODO 视频* Author WN* Date 2020/6/23 11:44**/
@Slf4j
public class VideoUtil {private static String  uploadfolder = ConfigKey.uploadfolder; //文件保存的目录private static String ffmpegpath = ConfigKey.ffmpegpath;//ffpeg目录public static Map<String, Integer> videoMap = new ConcurrentHashMap<>();public static VideoVo getVideo(String filepath){VideoVo videoVo = new VideoVo();videoVo.setVideopath(filepath);Long duration = getVideoDuration(videoVo);int d = Math.round(duration/1000);videoVo.setDuration(d);String coverpath = getVideoCover(uploadfolder + filepath);videoVo.setCoverpath(coverpath);return videoVo;}//获取视频时长private static Long getVideoDuration(VideoVo videoVo) {Long duration = 0l;try {String videopath = uploadfolder + videoVo.getVideopath();File video = new File(videopath);Encoder encoder = new Encoder();MultimediaInfo mi = encoder.getInfo(video);duration = mi.getDuration();} catch (Exception e) {log.error("获取视频时长失败!  viedoPath:{}", videoVo.getVideopath(), e);}return duration;}//获取视频封面图private static String getVideoCover(String videopath){File file = new File(videopath);if (!file.exists()) {System.err.println("路径[" + videopath + "]对应的视频文件不存在!");return "";}String coverpath = videopath.substring(0, videopath.lastIndexOf(".")).replaceFirst("vedio", "file") + ".jpg";List<String> commands = new java.util.ArrayList<String>();commands.add(ffmpegpath);commands.add("-i");commands.add(videopath);commands.add("-y");commands.add("-f");commands.add("image2");commands.add("-ss"); 添加参数"-ss",该参数指定截取的起始时间commands.add("2");// 这个参数是设置截取视频多少秒时的画面commands.add("-t");// 添加参数"-t",该参数指定持续时间commands.add("0.001");// 添加持续时间为1毫秒//commands.add("-s");//commands.add("700x525");commands.add(coverpath);String rtnstr = coverpath.replace(uploadfolder,"");try {ProcessBuilder builder = new ProcessBuilder();builder.command(commands);builder.start();} catch (Exception e) {e.printStackTrace();log.error("获取视频封面图失败:" + e.getMessage());return "";}return rtnstr;}/*** 获取mp4文件编码 mpeg4编码网页端不能播放,需调用transfer方法转为h264编码才能播放* @Param [filePath]* @Author ywx* @Date 2020/8/24 10:26* @return java.lang.String**/public static String getVideoCoder(String filePath){try {File file = new File(filePath);Encoder encoder = new Encoder();MultimediaInfo info = encoder.getInfo(file);VideoInfo video = info.getVideo();String decoder = video.getDecoder();return decoder;} catch (EncoderException e) {return null;}}/*** mp4 mpeg4编码转为h264编码* @Param [infile, outfile]* @Author ywx* @Date 2020/8/24 10:28* @return void**/public static String transferToH264(String infile, Integer resourceid, String type) throws Exception {infile = uploadfolder + infile;File inFile = new File(infile);String outfile = inFile.getParent() + File.separator + "transfer" + File.separator +inFile.getName();File outFile = new File(outfile);if (!inFile.exists() && outFile.exists()){//视频存在直接返回视频地址return outfile.replaceAll("\\\\", "/").replaceAll(uploadfolder,"");}if (!inFile.exists()){throw new Exception("该视频不存在");}String key = type +resourceid;Integer value = videoMap.get(key);if (value == null && outFile.exists()){outFile.delete();//重启服务或程序异常结束视频未转换完成,删除转换后的视频重新转换}if (inFile.exists() && outFile.exists()){//视频转码中return null;}File directory = new File(outFile.getParent());directory.setWritable(true,false);if (!directory.exists()) {directory.mkdirs();}//文件名包含空格转码失败解决方案:给路径加上引号String videoCommend = ffmpegpath+" -threads 5 -i \"" + infile + "\" -vcodec libx264 -preset ultrafast -r 29.97 -b 768k -ar 24000 -ab 64k -s 1280x720 \""+ outfile +"\"";try {videoMap.put(key,resourceid);Runtime rt = Runtime.getRuntime();Process proc = rt.exec(videoCommend);InputStream stderr = proc.getErrorStream();InputStreamReader isr = new InputStreamReader(stderr);BufferedReader br = new BufferedReader(isr);while ( br.readLine() != null) {}int exitVal = proc.waitFor();if (exitVal == 0) {inFile.delete();videoMap.remove(key);} else {throw new Exception("视频转码失败");}} catch (Exception t) {log.error("视频转码失败:"+t.getMessage());throw new Exception("视频转码失败");}return outfile.replaceAll("\\\\", "/").replaceAll(uploadfolder,"");}
}

异常

转换命令1(path下添加ffmpeg的环境变量,通过ffmpeg环境变量转码):
String videoCommend = "ffmpeg -threads 5 -i \"" + infile + "\" -vcodec libx264 -preset ultrafast -r 29.97 -b 768k -ar 24000 -ab 64k -s 1280x720 \""+ outfile +"\"";转换命令2(通过ffmpeg绝对地址转码):
String videoCommend = ffmpegpath+" -threads 5 -i \"" + infile + "\" -vcodec libx264 -preset ultrafast -r 29.97 -b 768k -ar 24000 -ab 64k -s 1280x720 \""+ outfile +"\"";转换命令1在本地(win10环境下正常),在服务器(Windows Server 2012 R2配置一个文件测试服务器正常,启动文件正式服务器时报错)报错信息:Cannot run program "ffmpeg": CreateProcess error=2, 系统找不到指定的文件。转换命令2在本地和服务器上都正常

mp4视频获取时长、封面图、编码、转码(mpeg4转h264)工具类相关推荐

  1. 关于java 上传的音频或视频文件获取时长及视频封面

    1.引入依赖,由于在Github上面的maven依赖,下载不下来,需要手动下载jar,然后安装到本地的maven仓库 <!-- https://mvnrepository.com/artifac ...

  2. python如何下载MP4视频和获取时长

    我们做爬虫工作时,经常会遇到要把爬取的视频下载到本地做存储,那么我们如何使用python去下载视频呢,下载视频不是本文章的重点,在此废话不多说,直接上完整的代码: def download_file( ...

  3. ffmpeg 获取视频的时长

    简单写个程序获取视频的时长,以便做视频播放器的进度条. 很简单,头文件我懒的敲了,直接复制别的,所以有些多余. 代码如下: #include <libavcodec/avcodec.h> ...

  4. Java使用FFmpeg(自定义cmd)系列之获取视频/音频时长(File文件方式)

    ffmpeg系列 Java使用FFmpeg(自定义cmd) Java使用FFmpeg(自定义cmd)系列之获取视频/音频时长 Java使用FFmpeg(自定义cmd)系列之官方API获取视频/音频信息 ...

  5. js获取上传视频的时长

    今天又给大家发福利了,楼主很辛苦的 小伙伴们肯定遇到本地上传视频要获取其时长,话不多说,楼主给大家写了一个demo <!DOCTYPE html> <html> <hea ...

  6. js 获取上传图片和视频的宽高,还有视频的时长

    场景: 当产品经理告诉你说:我们需要限制上传的图片或视频的尺寸,不符合要求不允许上传,这个时候你该怎么做? 不用多想,很明显我们需要想办法拿到图片或视频的宽度,然后和预期的尺寸进行对比过滤,就能轻易实 ...

  7. java 根据URL获取时长,视频大小

    /*** 根据网络路径获取时长* @author ZhangShaobo**/ public class VideoInfoTest {/*** 获取网络文件,暂存为临时文件* @param url* ...

  8. C#随手笔记——获取mp4文件属性(时长)

    客户需求将一段视频重复播放3遍,本来是另一个同事的活,不过说急求找我帮忙,那我肯定也义不容辞呀~第一反应是在播放器中设置重复播放的次数,但想想这种方法不知道有没有,而且也不通用,万一换一款播放器岂不又 ...

  9. Android之通过文件绝对路径获取音视频的时长和视频的缩略图

    1 需求 遍历一个文件夹,需要获取音视频的时长和视频的第一帧图像 2 关键代码实现 获取本地音视频的时长(这里计算出来的是秒为单位),如果文件不是音视频,下面的函数会发生异常,也就是返回0,我们除了通 ...

最新文章

  1. java mysql 文本导入数据语句_Java利用MYSQL LOAD DATA LOCAL INFILE实现大批量导入数据到MySQL...
  2. 开放域知识库问答研究回顾
  3. Ehab and the Expected XOR Problem
  4. 【转】常用的工业测量坐标系
  5. canny算子的理论分析
  6. shell批量修改后缀_bash批量修改文件名称的方法小结(增加,去除,修改后缀)
  7. centos java 乱码_CentOS 7.4 java验证码乱码的问题
  8. c# mysql 中文,c#操作mysql中文乱码的解决方案_c#应用
  9. JAVA:DOM解析XML和修改XML
  10. 智能汽车路径规划学习-Dijkstra、蚁群算法
  11. pb使用http方式上传下载文件
  12. android gc卡顿,由于频繁GC造成的界面卡顿原因分析
  13. 【爬虫】IP代理池的总结、实现与维护,IP代理池小工具(小框架),自建代理ip池
  14. Nlite后期处理技术小结(第三次更新...全文完)(by bluewind)
  15. hadoop 爬虫_这些不用编程的爬虫工具,你一定要知道
  16. 关于vtt 与 srt 字幕 的相互转换
  17. 如何快速搭建一个微服务架构
  18. ping ping ping
  19. 《程序开发心理学》几点核心理解
  20. Posts Tagged 【Catalan】

热门文章

  1. 今晚龙哥露面,赶紧观看直播
  2. php 打开word乱码,如何解决php word 乱码问题
  3. Python(五)文件与IO
  4. 守护长方形问题 C语言
  5. android函数未定义,未捕获的ReferenceError:尝试访问Android时未定义函数webview
  6. 【技术美术】盘点十大可捏脸的单机游戏
  7. 简易好用的pdf编辑器PDFelement 8 Pro Mac
  8. CVE-2022-1609 WordPress Weblizar Backdoor
  9. 基于Springboot+Node.JS+MySQL的日程日志信息管理系统
  10. cpu 缓存 java_Java与CPU缓存是如何亲密接触的!