目录

  • 目标
  • 依赖
  • VideoFormat.java
  • Video.java
  • 怎么使用

目标

将所有格式的视频转码为H5能播放的mp4格式

依赖

<!-- 依赖很多,不需要的自行排除 -->
<!-- 转码功能只需要以ffmpeg、javacpp、javacv、openblas、opencv开头的jar包依赖 -->
<dependency><groupId>org.bytedeco</groupId><artifactId>javacv-platform</artifactId><version>1.5.3</version>
</dependency>

VideoFormat.java

package com.videotest;public class VideoFormat {private boolean exists;private boolean isFile;private String absolutePath;private String parent = "";private String name = "";private String simpleName = "";private String extName = "";//扩展名/*** @See {org.bytedeco.ffmpeg.global.avcodec}*/private int videoCodec;//视频编码格式/*** @See {org.bytedeco.ffmpeg.global.avcodec}*/private int audioCodec;//音频编码格式private String format = "";//封装格式public boolean isExists() {return exists;}public void setExists(boolean exists) {this.exists = exists;}public boolean isFile() {return isFile;}public void setFile(boolean isFile) {this.isFile = isFile;}public String getAbsolutePath() {return absolutePath;}public void setAbsolutePath(String absolutePath) {this.absolutePath = absolutePath;}public String getParent() {return parent;}public void setParent(String parent) {this.parent = parent;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSimpleName() {return simpleName;}public void setSimpleName(String simpleName) {this.simpleName = simpleName;}public String getExtName() {return extName;}public void setExtName(String extName) {this.extName = extName;}public int getVideoCodec() {return videoCodec;}public void setVideoCodec(int videoCodec) {this.videoCodec = videoCodec;}public int getAudioCodec() {return audioCodec;}public void setAudioCodec(int audioCodec) {this.audioCodec = audioCodec;}public String getFormat() {return format;}public void setFormat(String format) {this.format = format;}@Overridepublic String toString() {return "VideoFormat [exists=" + exists + ", isFile=" + isFile + ", parent=" + parent + ", name=" + name+ ", simpleName=" + simpleName + ", extName=" + extName + ", videoCodec=" + videoCodec + ", audioCodec="+ audioCodec + ", format=" + format + "]";}}

Video.java

package com.videotest;import java.io.File;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class Video {private static final Logger logger = LoggerFactory.getLogger(Video.class);private static final String DEFAULT_EXTNAME = "mp4";private static final String DEFAULT_FORMAT = "mov,mp4,m4a,3gp,3g2,mj2";private VideoFormat videoFormat;public Video (String absolutePath) {this(new File(absolutePath));}public Video (String parent, String fileName) {this(new File(parent, fileName));}public Video (File file) {VideoFormat videoFormat = new VideoFormat();FFmpegFrameGrabber frameGrabber = null;try {videoFormat.setExists(file.exists());videoFormat.setFile(file.isFile());videoFormat.setAbsolutePath(file.getAbsolutePath());videoFormat.setParent(file.getParent());videoFormat.setName(file.getName());if (!file.isFile()) {return;}int dotLastIndex = videoFormat.getName().lastIndexOf(".");if (dotLastIndex > 0 && dotLastIndex < videoFormat.getName().length() - 1) {videoFormat.setSimpleName(videoFormat.getName().substring(0, dotLastIndex));videoFormat.setExtName(videoFormat.getName().substring(dotLastIndex + 1));} else {videoFormat.setSimpleName(videoFormat.getName());}frameGrabber = FFmpegFrameGrabber.createDefault(file);frameGrabber.start();videoFormat.setVideoCodec(frameGrabber.getVideoCodec());videoFormat.setAudioCodec(frameGrabber.getAudioCodec());videoFormat.setFormat(frameGrabber.getFormat());} catch (Exception e) {logger.warn(file.getAbsolutePath() + " -> error", e);} finally {if (frameGrabber != null) {try {frameGrabber.close();} catch (org.bytedeco.javacv.FrameGrabber.Exception e) {logger.warn("frameGrabber.close异常", e);}}}this.videoFormat = videoFormat;}protected VideoFormat getVideoFormat() {return videoFormat;}public boolean isVideo () {return this.getVideoFormat().getVideoCodec() != avcodec.AV_CODEC_ID_NONE;}protected boolean hasAudio () {return this.getVideoFormat().getAudioCodec() != avcodec.AV_CODEC_ID_NONE;}protected boolean isMp4 () {return DEFAULT_EXTNAME.equalsIgnoreCase(this.getVideoFormat().getExtName());}protected boolean canPlayInH5IgnoreExtName () {if (!this.isVideo()) {return false;}VideoFormat videoFormat = this.videoFormat;if (this.hasAudio() && videoFormat.getAudioCodec() != avcodec.AV_CODEC_ID_AAC) {return false;}if (videoFormat.getVideoCodec() != avcodec.AV_CODEC_ID_H264) {return false;}if (!DEFAULT_FORMAT.equals(videoFormat.getFormat())) {return false;}return true;}public boolean canPlayInH5 () {if (!this.isMp4()) {return false;}return this.canPlayInH5IgnoreExtName();}public String convert2Mp4 () throws Exception {return this.convert2Mp4(this.videoFormat.getParent());}/*** * @param outputParent 输出目录* @return 输出文件的绝对路径* @throws Exception*/public String convert2Mp4 (String outputParent) throws Exception {VideoFormat videoFormat = this.videoFormat;if (!this.isVideo()) {throw new org.bytedeco.javacv.FrameGrabber.Exception("[" + videoFormat.getAbsolutePath() + "] 不是视频文件");}File outfile = new File(outputParent);if (outfile.isFile()) {throw new FileAlreadyExistsException("[" + outputParent + "] 是文件并且已存在");}if (!outfile.exists()) {outfile.mkdirs();}String outFilePath = new File(outputParent, videoFormat.getSimpleName() + "_recode." + DEFAULT_EXTNAME).getAbsolutePath();outFilePath = outFilePath.replace("\\", "/");//如果视频本来就能在浏览器中播放,则只进行复制if (this.canPlayInH5IgnoreExtName()) {Files.copy(new File(videoFormat.getParent(), videoFormat.getName()).toPath(), new File(outFilePath).toPath(), StandardCopyOption.REPLACE_EXISTING);return outFilePath;}FFmpegFrameGrabber frameGrabber = FFmpegFrameGrabber.createDefault(new File(videoFormat.getParent(), videoFormat.getName()));Frame captured_frame = null;FFmpegFrameRecorder recorder = null;try {frameGrabber.start();recorder = new FFmpegFrameRecorder(outFilePath, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);recorder.setFormat(DEFAULT_EXTNAME);recorder.setFrameRate(frameGrabber.getFrameRate());recorder.setVideoBitrate(frameGrabber.getVideoBitrate());recorder.setAspectRatio(frameGrabber.getAspectRatio());recorder.setAudioOptions(frameGrabber.getAudioOptions());recorder.setSampleRate(frameGrabber.getSampleRate());recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);recorder.start();while (true) {captured_frame = frameGrabber.grabFrame();if (captured_frame == null) {logger.info(outFilePath + "转码完成");break;}recorder.record(captured_frame);}} finally {if (recorder != null) {try {recorder.close();} catch (Exception e) {logger.warn("recorder.close异常", e);}}try {frameGrabber.close();} catch (org.bytedeco.javacv.FrameGrabber.Exception e) {logger.warn("frameGrabber.close异常", e);}}return outFilePath;}}

怎么使用

public static void main(String[] args) throws Exception {Video video = new Video("D:", "1607589556364324.mkv");if (video.isVideo()) {String convert2Mp4 = video.convert2Mp4();System.out.println(convert2Mp4);}//      Video video = new Video("D:", "1607589556364324.mkv");
//      if (video.isVideo() && !video.canPlayInH5()) {//          String convert2Mp4 = video.convert2Mp4();
//          System.out.println(convert2Mp4);
//      }
}

基于javacv的视频截图和转码(升级版)

基于javacv的视频转码(升级版)相关推荐

  1. Qt基于FFmpeg实现视频转码

    一.简述转码 转码的作用:封装格式的实现.(h264->mov.mp4.flv.avi(封装格式)等) 之前博客中提到如何把像素数据编码得到 H264 的压缩码流数据,但是一般的播放工具是没法直 ...

  2. 基于javacv的视频编码格式判断及转码

    目录 目标 依赖 从网上找的代码 遇到问题 眼前的希望 ~~最终代码~~ 升级代码 目标 将所有格式的视频 转码为mp4格式 升级版 依赖 <!-- 依赖很多,不需要的自行排除 --> & ...

  3. 基于javacv的视频截图、转码、提取音频

    目录 目标 全量依赖 最小依赖 截图配置类 转码配置类 提取音频配置类 源视频处理结果类 核心类 怎么使用 目标 将所有格式的视频转码为H5能播放的mp4格式,也可以截取任意一帧图片 全量依赖 < ...

  4. 最简单的基于FFmpeg的移动端样例:IOS 视频转码器

    ===================================================== 最简单的基于FFmpeg的移动端样例系列文章列表: 最简单的基于FFmpeg的移动端样例:A ...

  5. 最简单的基于FFmpeg的移动端例子:IOS 视频转码器

    ===================================================== 最简单的基于FFmpeg的移动端例子系列文章列表: 最简单的基于FFmpeg的移动端例子:A ...

  6. 最简单的基于FFmpeg的移动端例子:Android 视频转码器

    ===================================================== 最简单的基于FFmpeg的移动端例子系列文章列表: 最简单的基于FFmpeg的移动端例子:A ...

  7. 基于 Amazon Lambda 的无服务器视频转码方案

    在 re:Invent 2020 上,Amazon Lambda推出了大函数支持.Amazon Lambda客户可以设置Amazon Lambda函数的最大内存为 10,240 MB(10GB),与之 ...

  8. GPU在视频转码中的应用研究进展

    转载地址:http://blog.csdn.net/jubincn/article/details/6669156 GPU在视频转码中的应用研究进展 已有的视频转码软件 目前,市场上已经出现了几款优秀 ...

  9. 腾讯视频云勇夺云端视频转码大赛多项第一

    2021年2月21日,莫斯科国立大学(Moscow State University)举办的MSU云端视频转码大赛(Cloud Video Transcoding Services Compariso ...

  10. JavaCV音视频开发宝典:基于JavaCV实现wav音频直播服务,wav在线FM电台直播服务,无需流媒体服务,浏览器原生audio标签直接播放wav直播音频

    <JavaCV音视频开发宝典>专栏目录导航 <JavaCV音视频开发宝典>专栏介绍和目录 ​ 前言 之前写过了mp3实现FM电台直播服务:<JavaCV音视频开发宝典:J ...

最新文章

  1. 关于锁机制:数据库锁
  2. 实验6_MPEG音频编码实验
  3. python 局域网 主机名_使用python获取连接到本地网络(基于主机名)的所有设备的ip...
  4. C语言进制转换相关函数
  5. 实对称矩阵对角化为什么要做正交化单位化操作呢?
  6. 逆水寒 各个服务器位置,逆水寒合服公告_哪些服务器要合并_3DM网游
  7. 电路基础-交流电-正弦量和相量
  8. A Game of Thrones(15)
  9. 程序员最该买的十本书
  10. 浅谈巫师2的战斗难度策略
  11. 全国高速公路一览表_拔剑-浆糊的传说_新浪博客
  12. java tcp dtu_使用有人DTU设备接入OneNet(基于TCP透传)
  13. 免费不限量查询手机归属地的api
  14. 恒成立、能成立和恰成立三类命题赏析【初级和中级辅导】
  15. CAD怎么在线转换图纸呢?
  16. 商城限时秒杀功能系统
  17. c语言模板类,C++类模板(Class Template)
  18. 目录 -- Vue.js 3.0 企业级管理后台开发实战 基于Element Plus
  19. 五子棋AI算法-Alpha Beta剪枝
  20. 最接近神的人 reverse

热门文章

  1. Java实现静态代理
  2. js如何连接mysql数据库_js怎样连接和调用mysql数据库?
  3. django + mysql8修改数据库密码
  4. 偏最小二乘法_实例讲解:简明扼要最小二乘法计算过程
  5. SSM框架整合思想及步骤
  6. 软件开发生命周期的四个阶段
  7. 迈达斯GTS-NX网格模型(FPN)导入Flac3D 6.0
  8. 汇川机器人视觉标定_汇川机器人应用技术课件(1).ppt
  9. netperf-2.7.0 交叉编译
  10. 分布式集群中网络分区问题