您的位置 首页 > 职场江湖

【视频怎么制成word文档】把手有助于将视频转换为文本(1-视频-音频)

本系列介绍了如何逐步实现MP4视频的语音对话,自动转换为文本,并输出到word文档中。这里的第一篇首先完成视频-音频处理。本项目的所有代码也全部公开在代码云上,可以直接下载试用版。

总体技术架构

下图是整个转换过程。

首先,MP4视频文件通过ffmpeg工具库大量转换为基于PCM音频文件(语音识别服务仅支持此格式)的基于云的技术,将PCM文件上传到百度对象存储BOS,并将日志等内容写入本地MySQL数据库。Pcm文件上载完成后,调用免费语音识别(录音转换)服务来创建离线录音传输作业。查询成功转换的作业,并将相关写入结果保存到本地MySQL库中。基于Docx4j库,将数据库的录制结果导出到标准化的word文档中。

转换结果示例

我们将《托马斯和他的朋友们第18季》 20次MP4视频转换为word故事文档。

以下是第一集具体对话文本表。

视频转音频

视频音频传输基于ffmpeg库。Ffmpeg是一个功能强大的跨平台音频和视频录制和转换程序(官网:a complete、cross-platform solution to record、convert and stream audio and video)

Ffmpeg主要以命令行模式进行音频和视频转换和处理。此处实现的功能包括:

从Mp4文件中删除片头和片尾音乐,并修剪中间片段。将剪裁的MP4文件转换为PCM文件。根据Ffplay检查PCM是否可播放。

用于截断Mp4文件中间部分的命令的默认格式如下:

FFM peg-ss[start]-I[input]-t[duration]-c copy[output]

FFM peg-ss[start]-I[input]-to[end]-c copy[output]

#例如,以下是将30秒至524秒剪切的文件另存为c1-1801.mp4文件。

Ffmpeg-y-ss30-I-to 524-c复制C1-1801.mp4

将Mp4文件转换为PCM音频文件命令参数:

-i输入文件

-移除an音频流

-删除vn视频流

-acodec音频编码设置

-f强制指定输入或输出文件的编码

-设置交流音频轨道数

-设置ar音频采用频率

-y不确认,直接复盖同名文件

#例如,以下是删除视频流并将音频编码为pcm_s16le的文件。输出文件也编码为s16le,轨迹为1,采样频率为16000。

FFM peg-I-VN-acodecpcm _ s 16le-fs 16le-AC 1-ar 16000

使用Ffplay播放PCM文件:

Ffplay -ar 16000 -ac 1 -f s16le -i使用更多ffmpeg命令,请参阅正式文档:

Java音视频处理

以上只是在命令行模式下基于ffmpeg验证基本音频和视频操作。需要以编程方式调用ffmpeg进行批量处理。

基于Org.bytedeco的ffmpeg和ffmpeg-platform使用Java实现ffmpeg调用。虽然每集视频的片头和片尾曲长度基本是固定的,但由于每集视频的总时间不同,可以通过org.mp4parser的isoparser库读取每集的总时间,并动态执行装配转换命令。引进的基本相依性如下:

!-实施视频文件读取-

Dependency

gt; <groupId>org.mp4parser</groupId> <artifactId>isoparser</artifactId> <version>1.9.41</version> </dependency> <!--实现对ffmpeg的操作--> <dependency> <groupId>org.bytedeco</groupId> <artifactId>ffmpeg</artifactId> <version>4.2.2-1.5.3</version> </dependency> <dependency> <groupId>org.bytedeco</groupId> <artifactId>ffmpeg-platform</artifactId> <version>4.2.2-1.5.3</version> </dependency>

以下是基于isoparser,读取MP4文件的总时长(秒数):

public long readDuration(Path mp4Path) { if (mp4Path) || !Files.isReadable(mp4Path)) { log.warn("文件路径不存在或不可读 {}", mp4Path); return 0; } try { IsoFile isoFile = new IsoFile()); long duration = i().getMovieHeaderBox().getDuration(); long timescale = i().getMovieHeaderBox().getTimescale(); return duration / timescale; } catch (IOException e) { log.error("读取MP4文件时长出错", e); return 0; } }

以下是将MP4文件进行截取,并转换为PCM文件:

/** * 将单个PM4文件进行片头和片尾歌曲删除后,转换为PCM文件 * * @param mp4Path * @param pcmDir * @return 转换完成后的pcm文件路径 */ public Optional<String> convertMP4toPCM(Path mp4Path, Path pcmDir) { long seconds = readDuration(mp4Path); if (seconds == 0) { log.warn("文件总时长为0"); return O(); } String ffmpeg = Loader.load); String endTime = S(seconds - 100 - 30); File src = m(); //在当前源mp4文件目录下生成临时文件 String mp4TempFile = () + "\\" + Sy() + ".mp4"; //基于ffmpeg进行截取 ProcessBuilder cutBuilder = new ProcessBuilder(ffmpeg, "-ss", "30", "-i", m().toString(), "-to", endTime, "-c", "copy", mp4TempFile); try { cu().start().waitFor(); } catch (InterruptedException | IOException e) { log.error("ffmpeg截取MP4文件出错", e); return O(); } // 基于ffmpeg进行pcm转换 // 基于输入路径的md5值来命名,也可以基于系统时间戳来命名 String pcmFile = ()) + ".pcm").toString(); ProcessBuilder pcmBuilder = new ProcessBuilder(ffmpeg, "-y", "-i", mp4TempFile, "-vn", "-acodec", "pcm_s16le", "-f", "s16le", "-ac", "1", "-ar", "16000", pcmFile); try { //inheritIO是指将 子流程的IO与当前java流程的IO设置为相同 ().start().waitFor(); } catch (InterruptedException | IOException e) { log.error("ffmpeg将mp4转换为pcm时出错", e); return O(); } // 删除MP4临时文件 try { Files.deleteIfExi(mp4TempFile)); } catch (IOException e) { log.error("删除mp4临时文件出错", e); } //返回pcm文件路径 return O(pcmFile); }

调用上述单个文件的处理方法,实现批量文件处理和转换:

/** * 批量将MP4文件转换为PCM文件 * * @param rootDir * @param pcmDir * @return 成功转换的PCM文件数 */ public int batchConvertMP4toPCM(Path rootDir, Path pcmDir) { if (rootDir) || !Files.isDirectory(rootDir)) { log.warn("mp4文件目录{}不存在", rootDir); return 0; } ​ if (pcmDir)) { //级联创建目录 try { Files.createDirectories(pcmDir); } catch (IOException e) { log.error("创建文件夹出错", e); } } AtomicInteger pcmCount = new AtomicInteger(0); //遍历rootdir,获取所有目录下子目录和文件 try { Files.list(rootDir).forEach(path -> { if (path)) { //递归遍历下级目录 (batchConvertMP4toPCM(path, pcmDir)); } if (path) && Files.isReadable(path) && () .toString() .endsWith("mp4")) { Optional<String> pcmFile = (path, pcmDir); if ()) { (); } } }); } catch (IOException e) { log.error("批量将MP4文件转换为PCM文件出错", e); } ​ return (); }

单个文件转换调用测试:

@Test void cutTest() { String file = "D:\\dev2\\project\\thomas\\local\\videos\\"; String pcmdir = "D:\\dev2\\project\\thomas\\local\\videos\\pcm"; Path path = Pa(file); u(path, Pa(pcmdir)); }

批量文件转换测试:

@Test void batchTest() { Path root = Pa("D:\\dev2\\project\\thomas\\local\\videos\\第18季"); Path pcmDir = Pa("D:\\dev2\\project\\thomas\\local\\videos\\pcm"); int pcmFiles = u(root, pcmDir); log.info("转换出PCM文件数{}", pcmFiles); }

至此,读取mp4文件,转换为pcm文件并剔除片头和片尾,就基本完成了,接下来将为你介绍如何基于百度云SDK和API实现语音转录。

关于作者: luda

无忧经验小编鲁达,内容侵删请Email至wohenlihai#qq.com(#改为@)

热门推荐