音频与视频合成技术



前言:前段时间负责了一个口语配音的项目,用到了音视频的合成技术,觉得挺简单实用于是来分享一下,
这也是我第一次写原创博文,都是一笔一划敲出来的,如需转载请注明出处:http://blog.csdn.net/xiaopy_0508/article/details/54962386

在使用之前肯定是要引用jar包的
		<dependency>
			<groupId>com.googlecode.mp4parser</groupId>
			<artifactId>isoparser</artifactId>
			<version>1.1.21</version>
		</dependency>
以上jar包只支持MP4格式的视频文件操作,如果是其他类型的多媒体文件可以使用JAVE或者其他转码程序和工具转码


先附上我的转码程序,但是我在项目中并没有用到,需要引入jave-1.0.2.jar
		File source = new File("C:\\Users\\xfy\\desktop\\工作文档\\2817\\test.avi");
		File target = new File("C:\\Users\\xfy\\desktop\\工作文档\\2817\\test__001.flv");
		AudioAttributes audio = new AudioAttributes();
		audio.setCodec("libmp3lame");
		audio.setBitRate(new Integer(64000));
		audio.setChannels(new Integer(1));
		audio.setSamplingRate(new Integer(22050));
		VideoAttributes video = new VideoAttributes();
		video.setCodec("flv");
		video.setBitRate(new Integer(160000));
		video.setFrameRate(new Integer(15));
		video.setSize(new VideoSize(400, 300));
		EncodingAttributes attrs = new EncodingAttributes();
		attrs.setFormat("flv");
		attrs.setAudioAttributes(audio);
		attrs.setVideoAttributes(video);
		Encoder encoder = new Encoder();
		encoder.encode(source, target, attrs);
	
		File source = new File("C:\\Users\\xfy\\desktop\\工作文档\\2817\\test_1111.mp4");
		File target = new File("C:\\Users\\xfy\\desktop\\工作文档\\2817\\test_1111.avi");// 转MP4
		System.out.println(source.length());

		AudioAttributes audio = new AudioAttributes();
		audio.setCodec("libmp3lame");
		audio.setBitRate(new Integer(64000));
		audio.setChannels(new Integer(1));
		audio.setSamplingRate(new Integer(22050));
		VideoAttributes video = new VideoAttributes();
		video.setCodec("libxvid");// 转MP4
		video.setBitRate(new Integer(180000));// 180kb/s比特率
		video.setFrameRate(new Integer(1));// 1f/s帧频,1是目前测试比较清楚的,越大越模糊
		EncodingAttributes attrs = new EncodingAttributes();
		attrs.setFormat("avi");// 转MP4
		attrs.setAudioAttributes(audio);
		attrs.setVideoAttributes(video);
		Encoder encoder = new Encoder();
		long beginTime = System.currentTimeMillis();
		try {
			// 获取时长
			MultimediaInfo m = encoder.getInfo(source);
			System.out.println(m.getDuration());
			System.out.println("获取时长花费时间是:" + (System.currentTimeMillis() - beginTime));
			beginTime = System.currentTimeMillis();
			encoder.encode(source, target, attrs);
			System.out.println("视频转码花费时间是:" + (System.currentTimeMillis() - beginTime));
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InputFormatException e) {
			e.printStackTrace();
		} catch (EncoderException e) {
			e.printStackTrace();
		}



然后是音视频合成代码,我使用的是M4A声音文件,其他类型的不知道是否支持
        // mp4音视频合成    
        try {    
            Movie countVideo = MovieCreator.build("D:\\uploadFiles\\dictionary\\demo-V0.2\\视频\\unit6_Cartoon time.mp4");    
            Movie countAudioEnglish = MovieCreator    
                    .build("D:\\uploadFiles\\dictionary\\demo-V0.2\\声音\\temp6.m4a");    
            Track audioTrackEnglish = countAudioEnglish.getTracks().get(0);    
            countVideo.addTrack(audioTrackEnglish);    
            Container out = new DefaultMp4Builder().build(countVideo);    
            FileOutputStream fos = new FileOutputStream(new File(    
                    "D:\\demo_test.mp4"));    
            out.writeContainer(fos.getChannel());  
            fos.flush();
            fos.close();    
        } catch (IOException e) {    
            e.printStackTrace();    
        }  

如果你想先消除视频的声音再与其它声音文件合成可以这样写
/**
	  * @Title:mux
	  * @Description:视频消音后进行音视频合成
	  * @param moive
	  * @param audio
	  * @param resultPath
	  * @return boolean
	  * @author XPY
	  * @date 2016年12月6日下午9:04:41
	 */
	@SuppressWarnings("resource")
	public static boolean mux(String moive, String audio, String resultPath) {
	        boolean result = false;

	        if (moive == null || audio == null || resultPath == null) {
	            throw new IllegalArgumentException();
	        }

	        try {
	            Movie mv =  MovieCreator.build(moive);
	            Movie ad =  MovieCreator.build(audio);
	            // 分别取出音轨和视频
	            List<Track> videoTracks = new LinkedList<>();
	            List<Track> audioTracks = new LinkedList<>();
	            for (Track t : mv.getTracks()) {
	            	 if (t.getHandler().equals("vide")) {
	 	            	videoTracks.add(t);
	 				}
				}
	            for (Track t : ad.getTracks()) {
	            	 if (t.getHandler().equals("soun")) {
	            		 audioTracks.add(t);
	 				}
				}

	            // 合并到最终的视频文件
	            Movie outMovie = new Movie();
	            if (videoTracks.size() > 0) {
	                outMovie.addTrack(new AppendTrack(videoTracks.toArray(new Track[videoTracks.size()])));
	            }
	            if (audioTracks.size() > 0) {
	                outMovie.addTrack(new AppendTrack(audioTracks.toArray(new Track[audioTracks.size()])));
	            }
	  

	            Container mp4file = new DefaultMp4Builder().build(outMovie);

	            // 将文件输出
	            File resultFile = new File(resultPath);
	            if (resultFile.exists() && resultFile.isFile()) {
	                resultFile.delete();
	            }
	            FileChannel fc = new RandomAccessFile(resultFile, "rw").getChannel();
	            mp4file.writeContainer(fc);
	            fc.close();
	            result = true;
	        } catch (FileNotFoundException e) {
	            e.printStackTrace();
	        } catch (Exception e) {
	            e.printStackTrace();
	        }
	        return result;
	    }
	
	
	public static void main(String[] args) {
		String movie = "D:\\uploadFiles\\dictionary\\demo-V0.2\\视频\\unit6_Cartoon time-1.mp4";
		String audio = "D:\\uploadFiles\\dictionary\\demo-V0.2\\声音\\背景音1.m4a";
		String resultPath = "D:\\1125.mp4";
		mux(movie, audio, resultPath);
	}


此方法的最大的好处在于不需要引入任何第三方库,也不需要JNI调用,全部都是java程序实现,跨平台,效率高,适用于服务器端的程序


如有问题可以留言给我
  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 43
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值