錄音檔案上傳且amr格式轉mp3格式
1.錄音檔案
前臺測試程式碼:
<form id="upload" enctype="multipart/form-data" method="post"> <input type="file" name="file" id="pic"/> <input type="button" value="提交" onclick="uploadPic();"/> <span class="showUrl"></span> <img src="" class="showPic" alt=""> </form>
function uploadPic() { var form = document.getElementById('upload'), formData = new FormData(form); $.ajax({ url:"http://localhost:8080/api/uploadVoiceFile", type:"post", data:formData, processData:false, contentType:false, success:function(res){ if(res){ alert(res+"上傳成功!"); } console.log(res); $("#pic").val(""); $(".showUrl").html(res); $(".showPic").attr("src",res); }, error:function(err){ alert("網路連線失敗,稍後重試",err); } }) }
後臺接收檔案程式碼:
發現問題1:
SpringBoot下測試時,發現的該問題,即在解析請求時List list = upload.parseRequest(request);得到的list size=0,也就是根本沒有得到檔案資料。我在網上搜索該問題的解決方法,大致有以下兩種:
(1)原因在於Spring的配置檔案中已經配置了MultipartResolver,導致檔案上傳請求已經被預處理過了,所以此處解析檔案列表為空,對應的做法是刪除該段配置。
(2)認為是structs的過濾器導致請求已被預處理,所以也要修改對應過濾器的配置。
然而,在SpringBoot下,上述兩種解決方法不可能做到,因為SpringBoot的相關配置都是自己完成的,根本沒有顯示的配置檔案。況且以上兩種解決方法,修改配置檔案可能影響整個工程的其他部分,所以得另尋方案。
我通過斷點除錯該Controller程式碼,發現傳入的引數HttpServletRequest例項已經為StandardMultipartHttpServletRequest 物件了,且其結構中包含整個form表單的所有欄位資訊,我就想,區別於網上已有的兩種解決方案,總是想避免這種預處理,何不就利用這種預處理,來簡化自己的程式碼結構呢?於是就有了下面的解決程式碼。其方法很簡單,就是對傳入的request做強制轉型,從而可以根據StandardMultipartHttpServletRequest 例項方法得到相關form表單資料 。
/**
* 上傳檔案(從request中獲取inputstream)
* @param request
* @param response
* @return
* @throws ServletException
* @throws IOException
*/
@ResponseBody
@PostMapping("/uploadVoiceFile")
public void uploadVoiceFile(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
logger.info("進入上傳檔案uploadVoiceFile方法");
try{
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
String realpath =request.getContextPath()+"/audio/";
String fileName = ""+System.currentTimeMillis();
if (isMultipart) {
File dir = new File(realpath);
if (!dir.exists()){
dir.mkdirs();
}
StandardMultipartHttpServletRequest req = (StandardMultipartHttpServletRequest) request;
Iterator<String> iterator = req.getFileNames();
while (iterator.hasNext()) {
MultipartFile file = req.getFile(iterator.next());
InputStream sis = file.getInputStream();
//儲存檔案
logger.info("建立音訊檔案"+request.getContextPath()+fileName+".amr");
FileOutputStream fos = new FileOutputStream(request.getContextPath()+"/audio/"+fileName+".amr");
logger.info("開始寫音訊檔案");
fos.write(file.getBytes()); // 開始寫音訊檔案
fos.flush();
fos.close();
String sourceDir = request.getContextPath()+"/audio/"+fileName+".amr";
String targetDir = request.getContextPath()+"/audio/"+fileName+".mp3";
changeToMp3(sourceDir, targetDir);
response.getWriter().append(fileName);
logger.info("檔案地址"+request.getContextPath()+"/audio/"+fileName+".amr");
}
}else{
response.getWriter().append("file not find error");
}
}catch (Exception e) {
e.printStackTrace();
logger.info(e.getMessage());
logger.info(e.getStackTrace().toString());
}
logger.info("退出上傳檔案uploadVoiceFile方法");
}
發現問題2:
專案需要將 amr 格式的檔案轉成 mp3格式,網路上提供的思路大多是使用jave-x-x.jar。
這個包確實有用,因為開發時是在windows環境中,測試轉換雖然報了異常:
it.sauronsoftware.jave.EncoderException: Duration: N/A, bitrate: N/A
但也確實轉換成功了,可以播放。
可是一旦部署到Linux環境當中,不是轉換失敗,就是轉換的檔案為大小 0 k。
public static void changeToMp3(String sourceDir,String targetDir) throws InputFormatException {
File source = new File(sourceDir); // 原始檔
File target = new File(targetDir); // 目標檔案
AudioAttributes audio = new AudioAttributes();
audio.setCodec("libmp3lame");
audio.setBitRate(new Integer(128000));
audio.setChannels(new Integer(2));
audio.setSamplingRate(new Integer(44100));
EncodingAttributes attrs = new EncodingAttributes();
attrs.setFormat("mp3");
attrs.setAudioAttributes(audio);
attrs.setDuration(30.0f);
attrs.setOffset(0f);
Encoder encoder = new Encoder();
try {
encoder.encode(source, target, attrs);
} catch (IllegalArgumentException | EncoderException e) {
e.printStackTrace();
}
}