目录

简述

Maven依赖

代码

总结


简述

将MP4视频内的音频提取出来,该工具类的解决思路如下:

1、提取视频音频pcm数据

2、将pcm数据封装音频头保存。

Maven依赖

        <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.5.2</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.bytedeco</groupId><artifactId>javacv-platform</artifactId><version>1.5.5</version></dependency>

说明一下,这里用到了hutools工具包,因为可以大幅简化代码。如果有自己的读取文件流的工具类,可以不使用。

代码

上代码

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.UUID;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.javacpp.Loader;import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Optional;/** @Author huyi @Date 2021/10/20 12:11 @Description: mp4提取音频工具类 */
@Slf4j
public class Mp4ExtractAudioUtils {/*** 获取视频的文件pcm文件地址** @param url MP4* @return* @throws Exception*/public static String getMp4Pcm(String url, String tmpDir) throws Exception {Optional<String> pcmPath = Optional.empty();try {pcmPath = convertMP4toPCM(Paths.get(url), Paths.get(tmpDir));} catch (Exception exception) {exception.printStackTrace();throw new Exception("转换pcm异常:" + exception.getMessage());}if (pcmPath.isPresent()) {return pcmPath.get();} else {throw new Exception("视频转换音频失败");}}/*** 将单个PM4文件进行片头和片尾歌曲删除后,转换为PCM文件** @param mp4Path* @param pcmDir* @return 转换完成后的pcm文件路径*/public static Optional<String> convertMP4toPCM(Path mp4Path, Path pcmDir) {String ffmpeg = Loader.load(org.bytedeco.ffmpeg.ffmpeg.class);// 基于ffmpeg进行pcm转换// 基于输入路径的md5值来命名,也可以基于系统时间戳来命名String pcmFile = pcmDir.resolve(UUID.randomUUID() + ".pcm").toString();ProcessBuilder pcmBuilder =new ProcessBuilder(ffmpeg,"-y","-i",mp4Path.toAbsolutePath().toString(),"-vn","-acodec","pcm_s16le","-f","s16le","-ac","1","-ar","16000",pcmFile);try {// inheritIO是指将 子流程的IO与当前java流程的IO设置为相同pcmBuilder.inheritIO().start().waitFor();} catch (InterruptedException | IOException e) {log.error("ffmpeg将mp4转换为pcm时出错", e);return Optional.empty();}// 返回pcm文件路径return Optional.of(pcmFile);}/*** 根据PCM文件构建wav的header字段** @param srate Sample rate - 8000, 16000, etc.* @param channel Number of channels - Mono = 1, Stereo = 2, etc..* @param format Number of bits per sample (16 here)* @throws IOException*/public static byte[] buildWavHeader(int dataLength, int srate, int channel, int format)throws IOException {byte[] header = new byte[44];long totalDataLen = dataLength + 36;long bitrate = srate * channel * format;header[0] = 'R';header[1] = 'I';header[2] = 'F';header[3] = 'F';header[4] = (byte) (totalDataLen & 0xff);header[5] = (byte) ((totalDataLen >> 8) & 0xff);header[6] = (byte) ((totalDataLen >> 16) & 0xff);header[7] = (byte) ((totalDataLen >> 24) & 0xff);header[8] = 'W';header[9] = 'A';header[10] = 'V';header[11] = 'E';header[12] = 'f';header[13] = 'm';header[14] = 't';header[15] = ' ';header[16] = (byte) format;header[17] = 0;header[18] = 0;header[19] = 0;header[20] = 1;header[21] = 0;header[22] = (byte) channel;header[23] = 0;header[24] = (byte) (srate & 0xff);header[25] = (byte) ((srate >> 8) & 0xff);header[26] = (byte) ((srate >> 16) & 0xff);header[27] = (byte) ((srate >> 24) & 0xff);header[28] = (byte) ((bitrate / 8) & 0xff);header[29] = (byte) (((bitrate / 8) >> 8) & 0xff);header[30] = (byte) (((bitrate / 8) >> 16) & 0xff);header[31] = (byte) (((bitrate / 8) >> 24) & 0xff);header[32] = (byte) ((channel * format) / 8);header[33] = 0;header[34] = 16;header[35] = 0;header[36] = 'd';header[37] = 'a';header[38] = 't';header[39] = 'a';header[40] = (byte) (dataLength & 0xff);header[41] = (byte) ((dataLength >> 8) & 0xff);header[42] = (byte) ((dataLength >> 16) & 0xff);header[43] = (byte) ((dataLength >> 24) & 0xff);return header;}/*** 默认写入的pcm数据是16000采样率,16bit,可以按照需要修改** @param filePath* @param pcmData*/public static String writeToFile(String filePath, byte[] pcmData) {BufferedOutputStream bos = null;try {bos = new BufferedOutputStream(new FileOutputStream(filePath));byte[] header = buildWavHeader(pcmData.length, 16000, 1, 16);bos.write(header, 0, 44);bos.write(pcmData);bos.close();return filePath;} catch (Exception e) {e.printStackTrace();return filePath;} finally {if (bos != null) {try {bos.close();} catch (IOException e) {e.printStackTrace();}}}}/*** 提取音频* @param mp4Path MP4地址* @param tmpDir 临时文件夹* @param resultPath 最终结果音频地址* @return 音频地址* @throws Exception 异常*/public static String extractAudio(String mp4Path, String tmpDir, String resultPath)throws Exception {String pcmPath = getMp4Pcm(mp4Path, tmpDir);return writeToFile(resultPath, FileUtil.readBytes(pcmPath));}public static void main(String[] args) throws Exception {System.out.println(extractAudio("C:\\Users\\huyi\\Desktop\\测试.mp4","C:\\Users\\huyi\\Desktop","C:\\Users\\huyi\\Desktop\\测试.wav"));}
}

执行结果:

可以看到生成一个临时的pcm文件,可以自己调整工具类将临时文件删除。

生成音频成功。

总结

这里有几点需要说明。

1、hutools工具主要是为了使用一些方便的组件,可以用自定义的,不一定要引入。

2、关于音频头文件的参数,在另一篇文章我有详细描述,可以参考:生成自定义时长的静音音频 | Java工具类_阿良的博客-CSDN博客

3、里面用到了ffmpeg进行pcm转换,需要本地环境有ffmpeg环境,具体说明在我另一篇有描述,可以参考:java 音频转为wav格式标准音频 | Java工具类_阿良的博客-CSDN博客

4、该工具类部分参数可以调整为入参模式,如果有疑问的话,可以私信我。

如果本文对你有帮助,请点个赞支持一下吧。

java 视频提取音频 | Java工具类相关推荐

  1. java 项目中常用的工具类总结

    1.文件 1.根据图片的链接,下载图片 package com.lingxu.module.BigDataJoinMessage.util;import java.io.FileOutputStrea ...

  2. java企业微信消息发送工具类

    java企业微信消息发送工具类 用途 基于java实现调用企业微信发送消息,文件,图片. 实现效果 文件列表 文件名 用途 WechatUtil.java 企业微信工具类 WechatTest.jav ...

  3. java inputtools_Java后台开发常用工具类

    本文涉及的工具类部分是自己编写,另一部分是在项目里收集的.工具类涉及数据库连接.格式转换.文件操作.发送邮件等等.提高开发效率,欢迎收藏与转载. 数据库连接工具类 数据库连接工具类--仅仅获得连接对象 ...

  4. java 兼容excel_Java解析Excel工具类(兼容xls和xlsx)

    依赖jar org.apache.poi poi-ooxml 4.0.1 ExcelUtils.java package javax.utils; import java.io.File; impor ...

  5. java中定义一个CloneUtil 工具类

    其实所有的java对象都可以具备克隆能力,只是因为在基础类Object中被设定成了一个保留方法(protected),要想真正拥有克隆的能力, 就需要实现Cloneable接口,重写clone方法.通 ...

  6. 【java笔记】Collections集合工具类

    java.utils.Collections是集合工具类,用来对集合进行操作 常用方法: public static<T>boolean addAll(Collection<T> ...

  7. (转)JAVA 十六个常用工具类

    (转)JAVA 十六个常用工具类 一. org.apache.commons.io.IOUtils closeQuietly 关闭一个IO流.socket.或者selector且不抛出异常.通常放在f ...

  8. JAVA实现 PDF转换 常用工具类(html转PDF、PDF添加页码、PDF文件下载、PDF添加印章或者水印)

    JAVA实现 PDF转换 常用工具类(html转PDF.PDF添加页码.PDF文件下载.PDF添加印章或者水印)可直接使用 package com.bestvike.util; import com. ...

  9. Java(35):Java Base64编码和解码工具类

    Java Base64编码和解码工具类 Base64Util工具类: package com.ciphergateway.utils; import java.io.UnsupportedEncodi ...

  10. JAVA 文件上传下载工具类

    JAVA 文件上传下载工具类 import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; import org. ...

最新文章

  1. prefetch下载SRA 数据
  2. 对比MySQL表数据内容方式汇总
  3. python精要(73)-函数传递任意参数
  4. problem about can't trigger exit-command in CR
  5. 苹果电脑java如何降级,如何在Mac OSX上降级JRE / JDK?
  6. CSS-伪类选择器(未完待续。。。)
  7. minSdkVersion、maxSdkVersion、targetSdkVersion、target释义
  8. java案例代码13--斗地主部分代码--静态ArrayList的使用
  9. Dialogue and Conversational Agents
  10. Hive从身份证号中提取相关信息_性别_年龄_出生日期_详细地址
  11. MYQQ复活版 20220801
  12. 快速原型VS敏捷、迭代
  13. 《Revisiting Pre-trained Models for Chinese Natural Language Processing》(MacBERT)阅读记录
  14. 国内自主首创·融合数据采集与运动控制技术--运动数据采集卡
  15. BS4爬取物价局房产备案价以及dataframe的操作来获取房价的信息分析
  16. http://gm100861.blog.51cto.com/1930562/954333
  17. Linux 下 ls -l 命令执行显示结果的每一列含义
  18. 数显之家快讯:【SHIO世硕心语】智慧城市时代下的智慧标识设计初探
  19. win7系统msi文件无法安装历程
  20. Docker容器-----Consul部署

热门文章

  1. matlab通信系统4g,matlab_通信原理.ppt
  2. DNS之BIND使用小结(Forward转发)
  3. 辽宁大学计算机专科专业,2020辽宁大学计算机考研专业课调整
  4. Cortex m0+笔记
  5. 情人节神奇的传情之物,“懂爱”的你都会爱上它丨情人节系列
  6. gitlab无法推送
  7. Flutter Dio 报错is not a subtype of type ‘DioError‘
  8. 数据分析师的工作职责是什么?
  9. 在linux平台上如何修改hostid
  10. arp-scan使用