Android 音视频配音之音频提取、截断、混音、合并、合成(二)——将提取的PCM根据时间戳截断

前言

  1. 通过上篇文章我们知道了如何从MP4视频中如何提取出PCM或者WAV,那么这篇文章则是如何截断PCM音频
  2. 该文章系列是视频配音,涉及到把背景音频从视频中提取出来、背景音频根据台词时间戳进行截断、截断的背景和录音混合、混合音频进行拼接合并、合并后的音频转码为m4a格式、将m4a格式音频和视频合并生成mp4视频文件
  3. 使用的视频格式:MP4     音频格式以及编码:m4a(aac)    采样率:44100   声道:双声道  采样位数:16
  4. 文章使用的测试音频为http网络视频,如果不是在视频丢失的情况下无法读取,请阅读一下该文章:Http网络请求无响应解决办法
  5. 上篇文章:Android 音视频配音之音频提取、截断、混音、合并、合成(一)——从视频中提取音频文件

截断前的准备

  • 了解pcm音频的属性

          pcm主要有声道数、采样率、采样大小这几个关键属性参数,而我们可以通过这几个参数,进行换算,得到pcm的码率,进而换算出音频长度,从而可以根据所要截取的音频时间进行相应截断

  • 截取公式

         每秒数据量=采样率∗声倒数∗bitnum/1000/8

        得到每秒数据量之后我们就可以得到截取时间区间的开始数据量和结束数据量,进而截取到相应片段,即:

       开始时间索引=每秒采样率*开始时间

      结束时间索引=每秒采样率*结束时间

     截取的音频片段数据=总音频数据[结束时间索引]-总音频数据[开始时间索引]

 

开始截断

通过上面的公式和从视频中提取音频文件我们就可以知道,只需要知道音频每一句的开始时间和结束时间,那么代码如下

        byte[] bytes=byteArrayOutputStream.toByteArray();//读取整个音频的数据
        byteArrayOutputStream.close();
        if (bytes.length==0){
            if (handler!=null){
                handler.sendEmptyMessage(0);
            }
            return;
        }
        for (int i=0;i<times.length-1;i++){
            long startTime=times[i];
            long endTime=times[i+1];
            //获取数据开始数据索引
            int startPosition=getPositionFromWave(startTime,KEY_SAMPLE_RATE,KEY_CHANNEL_COUNT,bitNumber);
            //获取数据结束数据索引
            int endPosition=endTime==-1?bytes.length-1:getPositionFromWave(endTime,KEY_SAMPLE_RATE,KEY_CHANNEL_COUNT,bitNumber);
            if (endPosition>bytes.length-1){
                endPosition=bytes.length-1;
            }
            if (startPosition==endPosition-1||startPosition>=endPosition){
                break;
            }
            byte[]  cutBytes;//= Arrays.copyOfRange(bytes,startPosition,endPosition+1);
            if (KEY_CHANNEL_COUNT==1){//如果是单通道需要转为双通道
                cutBytes= byteMerger(Arrays.copyOfRange(bytes,startPosition,endPosition+1));
            }else{
                cutBytes= Arrays.copyOfRange(bytes,startPosition,endPosition+1);
            }
            File cutFile=new File(dirPath,audioName+"_"+i+suffixName);
            if (!cutFile.exists()){
                cutFile.createNewFile();
                FileOutputStream cutFileOutputStream=new FileOutputStream(cutFile);
                if (isWav){
                    convertPcmToWav(cutFileOutputStream,cutBytes,KEY_SAMPLE_RATE,KEY_CHANNEL_COUNT,bitNumber);
                }else{
                    cutFileOutputStream.write(cutBytes);
                    cutFileOutputStream.close();
                }
            }
        }

timeis的数据,这个数据是提取出来的音频时间戳得到的,所以只适合我的测试数据。你们的数据需要根据你们的方法提炼需要截取的时间段

private static final long[] times={0,1060,2620,4240,8680,9860,11520,13920,17530,19150,20510,22020,25330,27770,30030,33110,34950,39730,43570,-1};

Demo下载

github

csdn

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值