>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>欢迎转载,转载请注明出处-VirgoArt,www.cnblogs.com
感谢xiangyuecn同学在GitHub上提供的音频操作组件,
一、客户端使用音频设备
HTML5采集麦克风音频 Web音频采集 录音时长,默认为三秒
序号 | 音频文件 | 播放 | 下载 | 上传 | 状态 |
其中,项目需要引用xiangyuecn/Recorder工程中的recorder-core.js、wav.js(个人测试只用到Wav格式,如有其他需求,参见工程ReadMe)。
二、后端数据通信
package cn.virgo.audio.controller;import cn.virgo.audio.utils.RemoteShellExecutor;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Controller;import org.springframework.util.ClassUtils;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.multipart.MultipartFile;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.*;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;import java.util.ArrayList;import java.util.List;@Controllerpublic class IndexController { @Value("${system.audiofile.path}") private String AUDIO_FILES_PATH; @Value("${system.ffmpeg.path}") private String AUDIO_FFMPEG_PATH; @Value("${system.ffmpeg.splittime}") private String AUDIO_SPLIT_TIME; /** * 首页跳转 * * @param request * @return */ @RequestMapping(path = {"/index"}, method = RequestMethod.GET) public ModelAndView defaultPage1(HttpServletRequest request) throws IOException { ModelAndView modelAndView = new ModelAndView("/mic"); return modelAndView; } /** * 音频文件上传 * * @param file * @return */ @RequestMapping(path = {"/upload"}, method = RequestMethod.POST) @ResponseBody public String upload1(@RequestParam("audioData") MultipartFile file) { if (file.isEmpty()) { return "Error"; } try { Files.createDirectories(Paths.get(AUDIO_FILES_PATH)); byte[] bytes = file.getBytes(); Path path = Paths.get(AUDIO_FILES_PATH + file.getOriginalFilename()); Files.write(path, bytes); } catch (IOException e) { e.printStackTrace(); } return "Success"; } /** * 音频文件上传 * * @param file * @return */ @RequestMapping(path = {"/upload2"}, method = RequestMethod.POST) @ResponseBody public String upload2(@RequestParam("audioData") MultipartFile file) { if (file.isEmpty()) { return "Error"; } try { Files.createDirectories(Paths.get(AUDIO_FILES_PATH)); byte[] bytes = file.getBytes(); Path path = Paths.get(AUDIO_FILES_PATH + file.getOriginalFilename()); Files.write(path, bytes); File srcFile = path.toFile(); //TODO:上传完成后,调用FFMPEG将音频分片,并删除源文件 run_exe(AUDIO_FFMPEG_PATH + "ffmpeg.exe -i " + AUDIO_FILES_PATH + file.getOriginalFilename() + " -f segment -segment_time " + AUDIO_SPLIT_TIME + " -c copy " + AUDIO_FILES_PATH + "out%03d.wav"); srcFile.delete(); } catch (IOException e) { e.printStackTrace(); } return "Success"; } /** * 准备就绪 * * @return */ @RequestMapping(path = {"/recognition"}, method = RequestMethod.GET) @ResponseBody public Listrecognition1() { //TODO:return null; } /** * 获取到项目路径 * * @return */ public static String getRootPath() { return ClassUtils.getDefaultClassLoader().getResource("").getPath(); } /** * 调用EXE * * @param cmd */ public static void run_exe(String cmd) { System.out.println("-------------Cmd info-------------"); System.out.println("CMD:" + cmd); String s1; String s2; StringBuilder sb1 = new StringBuilder(); sb1.append("ProcessInfo:"); StringBuilder sb2 = new StringBuilder(); sb2.append("ErrorInfo:"); Process proc = null; try { // 使用绝对路径 proc = Runtime.getRuntime().exec(cmd); InputStream pInfo = proc.getInputStream(); BufferedReader bufferedReader1 = new BufferedReader(new InputStreamReader(pInfo)); while ((s1 = bufferedReader1.readLine()) != null) { sb1.append(s1); } bufferedReader1.close(); System.out.println(sb1.toString()); InputStream pErr = proc.getErrorStream(); BufferedReader bufferedReader2 = new BufferedReader(new InputStreamReader(pErr)); while ((s2 = bufferedReader2.readLine()) != null) { sb2.append(s2); } bufferedReader2.close(); System.out.println(sb2.toString()); System.out.println("ExitCode:" + proc.waitFor()); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } }}
其中,项目中upload1对上传的音频不做二次加工,upload2对上传的音频使用FFMPEG进行二次加工。
三、备注
项目实例基于SpringBoot项目,需引用pom为:
4.0.0 cn.study audio 1.0-SNAPSHOT audio Demo project for audio org.springframework.boot spring-boot-starter-parent 2.1.3.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-logging org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-devtools org.springframework.boot spring-boot-starter-aop com.google.code.gson gson 2.8.5 org.springframework.boot spring-boot-starter-log4j2 org.apache.maven.plugins maven-compiler-plugin org.springframework.boot spring-boot-maven-plugin com.audio.App JAR repackage