音频文件的上传和合并

音频文件的上传页面
注:上传组件使用web uploader组件

<div id="merge_picker">上传文件</div>
<div id="merge_audio"></div>
<button type="button" onclick="mergeAudio()">合并</button>
<link href="$path/js/webuploader-0.1.5/webuploader.css" rel="stylesheet" type="text/css"/>
<script src="$path/js/webuploader-0.1.5/webuploader.min.js"></script>
<script type="text/javascript">
    $(document).ready(function(e) {
        // 初始化Web Uploader
        var uploader = WebUploader.create({
            // 选完文件后,是否自动上传。
            auto: true,
            // swf文件路径
            swf:  '$!path/js/webuploader-0.1.5/Uploader.swf',
            // 文件接收服务端。
            server: '$!path/text/uploadaudio',
            // 内部根据当前运行是创建,可能是input元素,也可能是flash.
            pick: '#merge_picker',
            fileVal:'Filedata',
            //同一文件是否可以重复上传
            duplicate :true,
            // 只允许选择图片文件。
            accept: {
                title: 'audio',
                extensions: 'mp3,wav',
                mimeTypes: 'audio/*'
            }
        });
        //上传过程中
        uploader.on('uploadProgress',function( file, percentage ) {
            $(".bs-example-modal-sm").modal("show");
        });
        //上传结束
        uploader.on( 'uploadComplete', function( file ) {
            $(".bs-example-modal-sm").modal("hide");;
        });
        // 完成上传完了,成功或者失败,先删除进度条。
        uploader.on( 'uploadSuccess', function(file,resp) {
            var url = '$!path/' + resp.url;
            var audio = '<embed id="lshfEmbed" src="'+url+'" windowlessVideo="true" autostart="0" loop="true" ></embed>';
            var input = '<input name="audio_path" class="merge_audio_path" value="'+resp.url+'" type="hidden">';
            $("#merge_audio").append(audio+input);
        });
    });

    function mergeAudio(){
        var audio_path = "";
        $(".merge_audio_path").each(function(){
            var merge_audio_path = $(this).val();
            if(audio_path==""){
                audio_path = merge_audio_path;
            }else{
                audio_path = audio_path + ";" + merge_audio_path;
            }
        });
        $.ajax({
            type:'post',
            data:{audioPath:audio_path},
            url:'$path/text/mergeaudio',
            success:function(date){
                var url = "$path/" + date;
                var merge_audio = '<embed id="lshfEmbed" src="'+url+'" windowlessVideo="true" autostart="0" loop="true" ></embed>';
                $("#merge_audio").html(merge_audio);
            }
        });
    }
</script>

java代码 音频文件上传

@Post("uploadaudio")
public Object uploadaudio(Invocation inv, Model model, MultipartFile Filedata){
    String uploadDir = config.getString("upload.audio");
    int maxDirCount = config.getInt("upload.maxDirCount", 100);
    HashMap<String,Object> map = uploadVideo(inv, Filedata, uploadDir, maxDirCount);
    model.add("result", map);
    return "result.json";
}
public static HashMap<String,Object> uploadVideo(Invocation inv, MultipartFile Filedata,
        String uploadDir,Integer maxDirCount){

    String urls = new String();
    String url = null;
    //Filedata-上传文件;uploadDir-上传路径;
    String urlDir = uploadDir;
    uploadDir = inv.getServletContext().getRealPath(uploadDir);

    long tmp = System.currentTimeMillis();
    long dirName = (tmp % new Long(maxDirCount));

    urlDir = urlDir + "/" + dirName;
    File dir = new File(uploadDir, String.valueOf(dirName));
    if (!dir.exists()) {
        dir.mkdirs();
    }
    String extName = FilenameUtils.getExtension(Filedata
            .getOriginalFilename());
    if (StringUtils.isEmpty(extName)) {
        String type = Filedata.getContentType();
        extName = MimeTypes.getExtension(type);
        extName = StringUtils.substring(extName, 1);
    }
    String mainFileName = FilenameUtils.getBaseName(Filedata
            .getOriginalFilename());
    String fileName = mainFileName + "." + extName;
    File file = new File(dir, fileName);
    String path = urlDir + "/" + fileName;
    try {
        Filedata.transferTo(file);
        Thumbnails.of(file);
        urls = path;
        url = ArrayUtils.toString(urls);
        url = StringUtils.removeStart(url, "{");
        url = StringUtils.removeEnd(url, "}");
    } catch (Exception e) {
        e.printStackTrace(System.err);
    }
    HashMap<String,Object> map = new HashMap<String,Object>();
    map.put("url", url);
    return map;
}

音频文件合并

/**
 * 合并音频文件
 * @param inv
 * @param model
 * @param audioPaths
 * @return
 */
@Post("mergeaudio")
public Object mergeAudio(Invocation inv,Model model,String audioPath){
    String upOutDir = config.getString("upload.audio");
    //剪辑后的路径
    upOutDir = inv.getServletContext().getRealPath(upOutDir);
    //获取年和月的时间
    DateFormat dft = new SimpleDateFormat("yyyyMM");
    Timestamp timestamp = new Timestamp((new Date()).getTime());
    String outFile = upOutDir + File.separator +dft.format(timestamp);
    File file = new File(outFile);
    if(!file.exists()){
        file.mkdirs();
    }

    List<HashMap<String,Object>> maps = new ArrayList<HashMap<String,Object>>();
    String[] audioPaths = audioPath.split(";");
    for(int i=0;i<audioPaths.length;i++){
        HashMap<String,Object> map = new HashMap<String,Object>();
        String path = inv.getServletContext().getRealPath(audioPaths[i]);
        map.put("path", path);
        map.put("start", 0);
        map.put("end", 0);
        maps.add(map);
//          int number = audioPaths[i].split("\\.").length-1;
    }

    String musicName = timestamp.getTime() + ".mp3";
    upOutDir = outFile+File.separator + musicName;
    mergeAudio(maps, upOutDir);
    String path = config.getString("upload.audio")+"/"+dft.format(timestamp)+"/"+musicName;
    model.add("result", path);
    return "result.json";
}

    /**
     * 合并音频文件
     * @param maps
     * @param output
     */
    public void mergeAudio(List<HashMap<String,Object>> maps,String output){
        BufferedOutputStream bos = null;
        //目标文件路径
        File target = new File(output);
        for(int i=0;i<maps.size();i++){
            try{
                String source = maps.get(i).get("path")+"";
                File file = new File(source);
                long totalTime = getVideoTime(source, "E:\\ffmpeg-20170425-b4330a0-win32-static\\ffmpeg-20170425-b4330a0-win32-static\\bin\\ffmpeg.exe");  //总时长(秒)
                int start = Integer.valueOf(maps.get(i).get("start").toString());
                int end = Integer.valueOf(maps.get(i).get("end").toString());
                if(start<0 || end<=0 || start>=totalTime || end>totalTime || start>=end){  
                    start = 0;
                    end = (int) totalTime;
                }
                FileInputStream fis = new FileInputStream(file);  
                long fileSize = file.length();  //音频数据大小 
                long splitSize = (fileSize/totalTime)*(end-start);  //截取的音频数据大小  
                long skipSize = (fileSize/totalTime)*start;  //截取时跳过的音频数据大小  
                int splitSizeInt = Integer.parseInt(String.valueOf(splitSize));  
                int skipSizeInt = Integer.parseInt(String.valueOf(skipSize));  

                byte[] fbyte = new byte[splitSizeInt];  //存放截取的音频数据  
                byte[] skipBytes = new byte[skipSizeInt];  //存放截取时跳过的音频数据  
                fis.read(skipBytes, 0, skipBytes.length);  //跳过不需要截取的数据  
                fis.read(fbyte, 0, fbyte.length);  //读取要截取的数据到目标数组  
                fis.close();

                if(target.exists()){  //如果目标文件已存在,则删除目标文件  
                    target.delete();  
                }
                //缓冲字节输出流(true表示可以在流的后面追加数据,而不是覆盖!!)
                bos = new BufferedOutputStream(new FileOutputStream(target, true));
                bos.write(fbyte);  
                bos.flush();
                System.out.println("第"+i+"首剪辑完成");
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
        //切记要关闭流!!
        if(bos!=null){
            try {
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
   /** 
   * 获取音频文件总时长 
   * @param video_path  文件路径 
   * @param ffmpeg_path 工具路径
   * @return 
   */  
   public int getVideoTime(String video_path, String ffmpeg_path) {  
       List<String> commands = new java.util.ArrayList<String>();  
       commands.add(ffmpeg_path);  
       commands.add("-i");  
       commands.add(video_path);  
       try {  
           ProcessBuilder builder = new ProcessBuilder();  
           builder.command(commands);  
           final Process p = builder.start();  

           //从输入流中读取视频信息  
           BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()));  
           StringBuffer sb = new StringBuffer();  
           String line = "";  
           while ((line = br.readLine()) != null) {  
               sb.append(line);  
           }  
           br.close();  
           //从视频信息中解析时长  
           String regexDuration = "Duration: (.*?), start: (.*?), bitrate: (\\d*) kb\\/s";  
           Pattern pattern = Pattern.compile(regexDuration);  
           Matcher m = pattern.matcher(sb.toString());
           if (m.find()) {  
               int time = getTimelen(m.group(1));  
               return time;  
           }  
       } catch (Exception e) {
           e.printStackTrace();  
       }  
       return 0;  
   }  

   //格式:"00:00:10.68"  
   private int getTimelen(String timelen){  
       int min=0;  
       String strs[] = timelen.split(":");  
       if (strs[0].compareTo("0") > 0) {  
           min+=Integer.valueOf(strs[0])*60*60;//秒  
       }  
       if(strs[1].compareTo("0")>0){  
           min+=Integer.valueOf(strs[1])*60;  
       }  
       if(strs[2].compareTo("0")>0){  
           min+=Math.round(Float.valueOf(strs[2]));  
       }  
       return min;  
   }

在剪辑和合并音频文件时,需要下载ffmpeg.exe工具。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
你可以使用FFmpeg库来合并音频和视频,并使用Spring Boot将结果返回给前端。下面是一个简单的示例代码: 1. 首先,你需要添加FFmpeg库的依赖。在pom.xml文件中添加以下代码: ``` <dependency> <groupId>com.github.wang-bin</groupId> <artifactId>java-ffmpeg</artifactId> <version>4.2.2</version> </dependency> ``` 2. 创建一个名为MediaController的Spring Boot控制器类,该类将处理视频和音频合并请求。以下是示例代码: ```java @RestController public class MediaController { @PostMapping("/merge") public ResponseEntity<Resource> mergeMedia(@RequestParam("video") MultipartFile videoFile, @RequestParam("audio") MultipartFile audioFile) throws IOException { // 创建临时文件夹 File tempDir = Files.createTempDir(); // 将视频和音频文件保存到临时文件夹 File video = new File(tempDir, videoFile.getOriginalFilename()); videoFile.transferTo(video); File audio = new File(tempDir, audioFile.getOriginalFilename()); audioFile.transferTo(audio); // 使用FFmpeg库将视频和音频合并 FFmpeg ffmpeg = new FFmpeg("ffmpeg"); FFmpegExecutor executor = new FFmpegExecutor(ffmpeg); FFmpegProbeResult videoInfo = FFmpegProbeResult .fromCommand(ffmpeg, Arrays.asList("-i", video.getAbsolutePath())) .execute(); FFmpegProbeResult audioInfo = FFmpegProbeResult .fromCommand(ffmpeg, Arrays.asList("-i", audio.getAbsolutePath())) .execute(); FFmpegBuilder builder = new FFmpegBuilder() .addInput(video.getAbsolutePath()) .addInput(audio.getAbsolutePath()) .overrideOutputFiles(true) .addOutput(tempDir.getAbsolutePath() + "/output.mp4") .setFormat("mp4") .setVideoCodec(videoInfo.getVideo().getCodecName()) .setVideoFrameRate(videoInfo.getVideo().getFrameRate()) .setVideoResolution(videoInfo.getVideo().getWidth(), videoInfo.getVideo().getHeight()) .setAudioCodec(audioInfo.getAudio().getCodecName()) .setAudioSampleRate(audioInfo.getAudio().getSampleRate()) .setAudioChannels(audioInfo.getAudio().getChannels()) .done(); executor.createJob(builder).run(); // 将合并结果返回给前端 Resource resource = new FileSystemResource(tempDir.getAbsolutePath() + "/output.mp4"); return ResponseEntity.ok() .contentType(MediaType.parseMediaType("video/mp4")) .body(resource); } } ``` 3. 在你的应用程序中配置MultipartResolver,以便能够处理文件上传。以下是示例代码: ```java @Configuration public class AppConfig { @Bean public MultipartResolver multipartResolver() { return new StandardServletMultipartResolver(); } } ``` 现在,你可以使用POST请求发送视频和音频文件,并从响应中获取合并后的视频文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值