Java离线视频提取音频+音频提取文案

devtools/2024/11/9 16:34:05/
aidu_pl">

需引入依赖javacv、vosk相关依赖,

至于javacv依赖,网上有很多缩减方案,注释部分是可行的缩减方案,至于视频提取视频这里无需安装ffmpeg,只需引入依赖。而vosk需要下载模型方可使用,并且下载比较慢,可先用小模型跑通。

    <properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><javacv.version>1.5.6</javacv.version><system.windowsx64>windows-x86_64</system.windowsx64></properties><!--  javacv+javacpp -->
<!--    <dependency>-->
<!--      <groupId>org.bytedeco</groupId>-->
<!--      <artifactId>javacv</artifactId>-->
<!--      <version>${javacv.version}</version>-->
<!--    </dependency>-->
<!--    <dependency>-->
<!--      <groupId>org.bytedeco</groupId>-->
<!--      <artifactId>javacpp-platform</artifactId>-->
<!--      <version>${javacv.version}</version>-->
<!--    </dependency>-->
<!--    &lt;!&ndash; ffmpeg最小依赖包,必须包含上面的javacv+javacpp核心库 &ndash;&gt;-->
<!--    <dependency>-->
<!--      <groupId>org.bytedeco</groupId>-->
<!--      <artifactId>ffmpeg</artifactId>-->
<!--      <version>4.4-${javacv.version}</version>-->
<!--      <classifier>${system.windowsx64}</classifier>-->
<!--    </dependency>-->
<!--&lt;!&ndash;     最小opencv依赖包 ,必须包含上面的javacv+javacpp&ndash;&gt;-->
<!--        <dependency>-->
<!--          <groupId>org.bytedeco</groupId>-->
<!--          <artifactId>opencv</artifactId>-->
<!--          <version>4.5.1-${javacv.version}</version>-->
<!--          <classifier>${system.windowsx64}</classifier>-->
<!--        </dependency>-->
<!--        <dependency>-->
<!--          <groupId>org.bytedeco</groupId>-->
<!--          <artifactId>openblas</artifactId>-->
<!--          <version>0.3.13-${javacv.version}</version>-->
<!--          <classifier>${system.windowsx64}</classifier>-->
<!--        </dependency>-->
<!--    <dependency>-->
<!--      <groupId>org.bytedeco</groupId>-->
<!--      <artifactId>flycapture</artifactId>-->
<!--      <version>2.13.3.31-${javacv.version}</version>-->
<!--      <classifier>${system.windowsx64}</classifier>-->
<!--    </dependency>--><dependencies><!-- 视频提取音频信息 --><dependency><groupId>org.bytedeco</groupId><artifactId>javacv-platform</artifactId><version>1.5.10</version></dependency><!-- 获取音频信息 --><dependency><groupId>org</groupId><artifactId>jaudiotagger</artifactId><version>2.0.3</version></dependency><dependency><groupId>net.java.dev.jna</groupId><artifactId>jna</artifactId><version>5.13.0</version></dependency><dependency><groupId>com.alphacephei</groupId><artifactId>vosk</artifactId><version>0.3.45</version></dependency><!-- JAVE2(Java音频视频编码器)库是ffmpeg项目上的Java包装器。 --><dependency><groupId>ws.schild</groupId><artifactId>jave-core</artifactId><version>3.1.1</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.83</version></dependency></dependencies>

视频提取音频

java">package org.example;import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;public class Test {public static void extractVoice(String sourceFileName, String audioUrl) throws FFmpegFrameGrabber.Exception, FFmpegFrameRecorder.Exception {//抓取资源FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(sourceFileName);Frame frame = null;FFmpegFrameRecorder recorder = null;frameGrabber.start();//转录为单轨, 16K采样率, wav格式recorder = new FFmpegFrameRecorder(audioUrl, frameGrabber.getAudioChannels());recorder.setFormat(frameGrabber.getFormat());recorder.setSampleRate(frameGrabber.getSampleRate());//frameGrabber.getSampleRate()//recorder.setAudioBitrate(128000);// 音频比特率recorder.setTimestamp(frameGrabber.getTimestamp());recorder.setVideoCodec(avcodec.AV_CODEC_ID_NONE); // 不录制视频recorder.start();int index = 0;while (true) {frame = frameGrabber.grabSamples();if (frame == null) break;if (frame.samples != null) {recorder.recordSamples(frame.sampleRate, frame.audioChannels, frame.samples);recorder.setTimestamp(frameGrabber.getTimestamp());}index++;}recorder.stop();recorder.release();frameGrabber.stop();frameGrabber.release();}public static void main(String[] args) throws FFmpegFrameGrabber.Exception, FFmpegFrameRecorder.Exception {String videoFilePath = "I:\\workspace\\test.mp4"; // 视频文件路径String audioOutputPath = "I:\\workspace\\test_audio.wav"; // 输出的音频文件路径long s = System.currentTimeMillis();extractVoice(videoFilePath, audioOutputPath);System.out.println(System.currentTimeMillis() - s);}}

音频提取文字

至于model可去此网站下载,解压使用。大模型下载较慢

VOSK Models

java">package org.example;import com.alibaba.fastjson.JSON;
import org.vosk.LibVosk;
import org.vosk.LogLevel;
import org.vosk.Model;
import org.vosk.Recognizer;import javax.sound.sampled.*;
import java.io.*;
import java.util.Optional;public class Test3 {public static void main(String[] args) {StringBuilder result = new StringBuilder();LibVosk.setLogLevel(LogLevel.DEBUG);AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 44100, false);DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);TargetDataLine microphone;SourceDataLine speakers;try (Model model = new Model("I:\\workspace\\vosk-model-small-cn-0.22");InputStream ais = AudioSystem.getAudioInputStream(new BufferedInputStream(new FileInputStream("I:\\workspace\\test_audio.wav")));Recognizer recognizer = new Recognizer(model, 120000)) {try {microphone = (TargetDataLine) AudioSystem.getLine(info);microphone.open(format);microphone.start();ByteArrayOutputStream out = new ByteArrayOutputStream();int numBytesRead;int CHUNK_SIZE = 1024;int bytesRead = 0;DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, format);speakers = (SourceDataLine) AudioSystem.getLine(dataLineInfo);speakers.open(format);speakers.start();byte[] b = new byte[4096];while (bytesRead <= 100000000) {byte[] audioData = new byte[CHUNK_SIZE];numBytesRead = ais.read(audioData, 0, CHUNK_SIZE);bytesRead += numBytesRead;out.write(audioData, 0, numBytesRead);speakers.write(audioData, 0, numBytesRead);if (recognizer.acceptWaveForm(audioData, numBytesRead)) {result.append(getResult(recognizer.getResult()));} else {result.append(getResult(recognizer.getPartialResult()));}}result.append(getResult(recognizer.getFinalResult()));speakers.drain();speakers.close();microphone.close();} catch (Exception e) {e.printStackTrace();}System.out.println(result.toString());} catch (IOException e) {throw new RuntimeException(e);} catch (UnsupportedAudioFileException e) {throw new RuntimeException(e);}}/*** 获取返回结果** @param result* @return*/private static String getResult(String result) {VoskResult vr = JSON.parseObject(result,VoskResult.class);return  Optional.ofNullable(vr).map(VoskResult::getText).orElse("");}public static void main1(String[] argv) throws IOException, UnsupportedAudioFileException {LibVosk.setLogLevel(LogLevel.DEBUG);StringBuilder result = new StringBuilder();try (Model model = new Model("I:\\workspace\\vosk-model-small-cn-0.22");InputStream ais = AudioSystem.getAudioInputStream(new BufferedInputStream(new FileInputStream("I:\\workspace\\test_audio.wav")));Recognizer recognizer = new Recognizer(model, 120000)) {int nbytes;byte[] b = new byte[4096];while ((nbytes = ais.read(b)) >= 0) {if (recognizer.acceptWaveForm(b, nbytes)) {result.append(getResult(recognizer.getResult()));} else {result.append(getResult(recognizer.getPartialResult()));}}result.append(getResult(recognizer.getFinalResult()));}System.out.println(result);}
}

感谢网上各位大佬能分享这些信息

测试可行,识别率没有做过对比、大模型也没有试过。这里也就提供一种可行的离线解决方案。


http://www.ppmy.cn/devtools/13814.html

相关文章

C++模版初阶

目录 1.泛型编程 2.函数模版 2.1 函数模版概念 2.2 函数模版格式 2.3 函数模版的原理 2.4 函数模版的实例化 2.5 模版参数的匹配原则 3.类模版 3.1 类模版的定义格式 3.2 类模版的实例化 1.泛型编程 如何实现一个通用的交换函数&#xff1f; void Swap(char& l…

Springboot的日常操作技巧

文章目录 1、自定义横幅2、容器刷新后触发方法自定义3、容器启动后触发方法自定义**CommandLineRunner**ApplicationRunner 不定时增加 参考文章 1、自定义横幅 简单就一点你需要把banner.text放到classpath 路径下 &#xff0c;默认它会找叫做banner的文件&#xff0c;各种格式…

发票查验详情、C票据识别、发票ocr

翔云人工智能开放平台自从上架了发票识别、发票验真两个API产品接到了不少咨询&#xff0c;除了产品本身咨询&#xff0c;同时也记录了一些容易被忽略的开票注意事项&#xff0c;在此分享几个典型的示例给大家&#xff0c;希望能帮到相关业务人员。 翔云发票验真 问题1&#…

解密数字经济时代,元宇宙企业如何重塑商业价值?

从复盘中感知自我&#xff0c;坚持和过去对话&#xff0c;并引入未来的思考&#xff0c;飞天云动是一个典型的案例。 在科技的飞速发展和数字化浪潮的推动下&#xff0c;元宇宙这一概念如同一颗冉冉升起的新星&#xff0c;吸引了全球的目光。就目前而言&#xff0c;围绕元宇宙…

【方案探讨】 出现java.io.IOException解决方法

出现java.io.IOException解决方法 解决问题的博客&#xff1a;探索新思路&#xff0c;共同成长 &#x1f331;壹、出现背景贰、排查方向叁、场景复现1、放单个大文件2、修改后端请求其他服务器时间3、多次请求多个文件4、单词请求多个文件 肆、解决方案谢谢您的阅读和支持&…

Laravel 6 - 第十五章 验证器

​ 文章目录 Laravel 6 - 第一章 简介 Laravel 6 - 第二章 项目搭建 Laravel 6 - 第三章 文件夹结构 Laravel 6 - 第四章 生命周期 Laravel 6 - 第五章 控制反转和依赖注入 Laravel 6 - 第六章 服务容器 Laravel 6 - 第七章 服务提供者 Laravel 6 - 第八章 门面 Laravel 6 - …

《十》Qt各种对话框之QFontDialog

QFontDialog 在介绍 QFontDialog 对话框之前&#xff0c;我们先简单介绍一下 QFont 字体类。QFont 主要用于控制文本显示的字体&#xff0c;字体主要有四大属性&#xff1a;①字体家族 family 决定字体外观家族&#xff0c;比如宋体、楷体等&#xff1b; ②字号 pointSize &am…

Vue3从入门到实战:深度掌握组件通信(上部曲)

props的概念&#xff1a; 当你使用Vue 3的组合式API时&#xff0c;props就是一种让你可以从父组件向子组件传递数据的方式。你可以想象成你在给子组件写一封信&#xff0c;把需要传递的信息放在信封里。 在Vue 3中&#xff0c;你可以在子组件的代码中定义props&#xff0c;就…