zoukankan      html  css  js  c++  java
  • 录音文件截取

    Java代码  收藏代码
    1. import it.sauronsoftware.jave.Encoder;  
    2. import it.sauronsoftware.jave.MultimediaInfo;  
    3.   
    4. import java.io.File;  
    5. import java.io.FileInputStream;  
    6. import java.io.FileOutputStream;  
    7. import java.io.IOException;  
    8. import java.nio.ByteBuffer;  
    9.   
    10. /** 
    11.  * wav音频文件截取工具 
    12.  * (适用于比特率为128kbps的wav音频文件,此类音频文件的头部信息占用长度44字节) 
    13.  * @author lwj 
    14.  * 
    15.  */  
    16. public class WavCut {  
    17.       
    18.     /** 
    19.      * 截取wav音频文件 
    20.      * @param sourcepath  源文件地址 
    21.      * @param targetpath  目标文件地址 
    22.      * @param start  截取开始时间(秒) 
    23.      * @param end  截取结束时间(秒) 
    24.      *  
    25.      * return  截取成功返回true,否则返回false 
    26.      */  
    27.     public static boolean cut(String sourcefile, String targetfile, int start, int end) {  
    28.         try{  
    29.             if(!sourcefile.toLowerCase().endsWith(".wav") || !targetfile.toLowerCase().endsWith(".wav")){  
    30.                 return false;  
    31.             }  
    32.             File wav = new File(sourcefile);  
    33.             if(!wav.exists()){  
    34.                 return false;  
    35.             }  
    36.             long t1 = getTimeLen(wav);  //总时长(秒)  
    37.             if(start<0 || end<=0 || start>=t1 || end>t1 || start>=end){  
    38.                 return false;  
    39.             }  
    40.             FileInputStream fis = new FileInputStream(wav);  
    41.             long wavSize = wav.length()-44;  //音频数据大小(44为128kbps比特率wav文件头长度)  
    42.             long splitSize = (wavSize/t1)*(end-start);  //截取的音频数据大小  
    43.             long skipSize = (wavSize/t1)*start;  //截取时跳过的音频数据大小  
    44.             int splitSizeInt = Integer.parseInt(String.valueOf(splitSize));  
    45.             int skipSizeInt = Integer.parseInt(String.valueOf(skipSize));  
    46.               
    47.             ByteBuffer buf1 = ByteBuffer.allocate(4);  //存放文件大小,4代表一个int占用字节数  
    48.             buf1.putInt(splitSizeInt+36);  //放入文件长度信息  
    49.             byte[] flen = buf1.array();  //代表文件长度  
    50.             ByteBuffer buf2 = ByteBuffer.allocate(4);  //存放音频数据大小,4代表一个int占用字节数  
    51.             buf2.putInt(splitSizeInt);  //放入数据长度信息  
    52.             byte[] dlen = buf2.array();  //代表数据长度  
    53.             flen = reverse(flen);  //数组反转  
    54.             dlen = reverse(dlen);  
    55.             byte[] head = new byte[44];  //定义wav头部信息数组  
    56.             fis.read(head, 0, head.length);  //读取源wav文件头部信息  
    57.             for(int i=0; i<4; i++){  //4代表一个int占用字节数  
    58.                 head[i+4] = flen[i];  //替换原头部信息里的文件长度  
    59.                 head[i+40] = dlen[i];  //替换原头部信息里的数据长度  
    60.             }  
    61.             byte[] fbyte = new byte[splitSizeInt+head.length];  //存放截取的音频数据  
    62.             for(int i=0; i<head.length; i++){  //放入修改后的头部信息  
    63.                 fbyte[i] = head[i];  
    64.             }  
    65.             byte[] skipBytes = new byte[skipSizeInt];  //存放截取时跳过的音频数据  
    66.             fis.read(skipBytes, 0, skipBytes.length);  //跳过不需要截取的数据  
    67.             fis.read(fbyte, head.length, fbyte.length-head.length);  //读取要截取的数据到目标数组  
    68.             fis.close();  
    69.               
    70.             File target = new File(targetfile);  
    71.             if(target.exists()){  //如果目标文件已存在,则删除目标文件  
    72.                 target.delete();  
    73.             }  
    74.             FileOutputStream fos = new FileOutputStream(target);  
    75.             fos.write(fbyte);  
    76.             fos.flush();  
    77.             fos.close();  
    78.         }catch(IOException e){  
    79.             e.printStackTrace();  
    80.             return false;  
    81.         }  
    82.         return true;  
    83.     }  
    84.       
    85.     /** 
    86.      * 获取音频文件总时长 
    87.      * @param filePath  文件路径 
    88.      * @return 
    89.      */  
    90.     public static long getTimeLen(File file){  
    91.         long tlen = 0;  
    92.         if(file!=null && file.exists()){  
    93.             Encoder encoder = new Encoder();  
    94.             try {  
    95.                  MultimediaInfo m = encoder.getInfo(file);  
    96.                  long ls = m.getDuration();  
    97.                  tlen = ls/1000;  
    98.             } catch (Exception e) {  
    99.                 e.printStackTrace();  
    100.             }  
    101.         }  
    102.         return tlen;  
    103.     }  
    104.       
    105.     /** 
    106.     * 数组反转 
    107.     * @param array 
    108.     */  
    109.     public static byte[] reverse(byte[] array){  
    110.         byte temp;  
    111.         int len=array.length;  
    112.         for(int i=0;i<len/2;i++){  
    113.             temp=array[i];  
    114.             array[i]=array[len-1-i];  
    115.             array[len-1-i]=temp;  
    116.         }  
    117.         return array;  
    118.     }  
    119.       
    120.     public static void main(String[] args){  
    121.         System.out.println(cut("f:\111.wav","f:\111-cut_0_10.wav",0,10));  
    122.         System.out.println(cut("f:\111.wav","f:\111-cut_10_20.wav",10,20));  
    123.         System.out.println(cut("f:\111.wav","f:\111-cut_20_28.wav",20,28));  
    124.     }  
    125.   
    126. }  

    wave类型的音频文件切割时必须注意头信息,128kbps比特率的wave文件头信息占用44字节。

    可以把头信息作为一个对象,用ByteBuffer获取头信息。

    注意:wave文件的头信息字节数组中每个属性都进行了数组反转

    wave头信息对象模型如下:

    Java代码  收藏代码
    1. /** 
    2.  * wave文件头信息 
    3.  * @author lwj 
    4.  * 
    5.  */  
    6. public class Head {  
    7.       
    8.     public int riff_id;           //4 byte , 'RIFF'  
    9.     public int file_size;         //4 byte , 文件长度(数据长度+36)  
    10.     public int riff_type;         //4 byte , 'WAVE'  
    11.   
    12.     public int fmt_id;            //4 byte , 'fmt'  
    13.     public int fmt_size;          //4 byte , 数值为16或18,18则最后又附加信息  
    14.     public short fmt_tag;          //2 byte , 编码方式,一般为0x0001  
    15.     public short fmt_channel;     //2 byte , 声道数目,1--单声道;2--双声道  
    16.     public int fmt_samplesPerSec;//4 byte , 采样频率  
    17.     public int avgBytesPerSec;   //4 byte , 每秒所需字节数,记录每秒的数据量  
    18.     public short blockAlign;      //2 byte , 数据块对齐单位(每个采样需要的字节数)  
    19.     public short bitsPerSample;   //2 byte , 每个采样需要的bit数  
    20.   
    21.     public int data_id;           //4 byte , 字符data  
    22.     public int data_size;         //4 byte , 数据长度  
    23.       
    24.     public int getRiff_id() {  
    25.         return riff_id;  
    26.     }  
    27.     public void setRiff_id(int riff_id) {  
    28.         this.riff_id = riff_id;  
    29.     }  
    30.     public int getFile_size() {  
    31.         return file_size;  
    32.     }  
    33.     public void setFile_size(int file_size) {  
    34.         this.file_size = file_size;  
    35.     }  
    36.     public int getRiff_type() {  
    37.         return riff_type;  
    38.     }  
    39.     public void setRiff_type(int riff_type) {  
    40.         this.riff_type = riff_type;  
    41.     }  
    42.     public int getFmt_id() {  
    43.         return fmt_id;  
    44.     }  
    45.     public void setFmt_id(int fmt_id) {  
    46.         this.fmt_id = fmt_id;  
    47.     }  
    48.     public int getFmt_size() {  
    49.         return fmt_size;  
    50.     }  
    51.     public void setFmt_size(int fmt_size) {  
    52.         this.fmt_size = fmt_size;  
    53.     }  
    54.     public short getFmt_tag() {  
    55.         return fmt_tag;  
    56.     }  
    57.     public void setFmt_tag(short fmt_tag) {  
    58.         this.fmt_tag = fmt_tag;  
    59.     }  
    60.     public short getFmt_channel() {  
    61.         return fmt_channel;  
    62.     }  
    63.     public void setFmt_channel(short fmt_channel) {  
    64.         this.fmt_channel = fmt_channel;  
    65.     }  
    66.     public int getFmt_samplesPerSec() {  
    67.         return fmt_samplesPerSec;  
    68.     }  
    69.     public void setFmt_samplesPerSec(int fmt_samplesPerSec) {  
    70.         this.fmt_samplesPerSec = fmt_samplesPerSec;  
    71.     }  
    72.     public int getAvgBytesPerSec() {  
    73.         return avgBytesPerSec;  
    74.     }  
    75.     public void setAvgBytesPerSec(int avgBytesPerSec) {  
    76.         this.avgBytesPerSec = avgBytesPerSec;  
    77.     }  
    78.     public short getBlockAlign() {  
    79.         return blockAlign;  
    80.     }  
    81.     public void setBlockAlign(short blockAlign) {  
    82.         this.blockAlign = blockAlign;  
    83.     }  
    84.     public short getBitsPerSample() {  
    85.         return bitsPerSample;  
    86.     }  
    87.     public void setBitsPerSample(short bitsPerSample) {  
    88.         this.bitsPerSample = bitsPerSample;  
    89.     }  
    90.     public int getData_id() {  
    91.         return data_id;  
    92.     }  
    93.     public void setData_id(int data_id) {  
    94.         this.data_id = data_id;  
    95.     }  
    96.     public int getData_size() {  
    97.         return data_size;  
    98.     }  
    99.     public void setData_size(int data_size) {  
    100.         this.data_size = data_size;  
    101.     }  
    102.       
    103. }  

    附件为wave切割程序所依赖的外部jar包

    Next lines extracts audio informations from an AVI and store them in a plain WAV file:

    File source = new File("source.avi");
    File target = new File("target.wav");
    AudioAttributes audio = new AudioAttributes();
    audio.setCodec("pcm_s16le");
    EncodingAttributes attrs = new EncodingAttributes();
    attrs.setFormat("wav");
    attrs.setAudioAttributes(audio);
    Encoder encoder = new Encoder();
    encoder.encode(source, target, attrs);




    Next example takes an audio WAV file and generates a 128 kbit/s, stereo, 44100 Hz MP3 file:

    File source = new File("source.wav");
    File target = new File("target.mp3");
    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);
    Encoder encoder = new Encoder();
    encoder.encode(source, target, attrs);



    http://lwjwd.iteye.com/blog/2025072



    http://www.sauronsoftware.it/projects/jave/manual.php#10




    自己的代码

    package io.renren.util;


    import it.sauronsoftware.jave.AudioAttributes;
    import it.sauronsoftware.jave.Encoder;
    import it.sauronsoftware.jave.EncoderException;
    import it.sauronsoftware.jave.EncodingAttributes;
    import it.sauronsoftware.jave.InputFormatException;
    import it.sauronsoftware.jave.MultimediaInfo;

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.nio.ByteBuffer;

    /**
    * wav音频文件截取工具
    * (适用于比特率为128kbps的wav音频文件,此类音频文件的头部信息占用长度44字节)
    * @author lwj
    *
    */
    public class WavCut {

    /**
    * 截取wav音频文件
    * @param sourcepath 源文件地址
    * @param targetpath 目标文件地址
    * temFile 128文件,中间文件
    * @param start 截取开始时间(毫秒)
    * @param end 截取结束时间(毫秒)
    *
    * return 截取成功返回true,否则返回false
    * @throws Exception
    * @throws InputFormatException
    * @throws IllegalArgumentException
    */
    public static boolean cut(String sourcefile,String temFile, String targetfile, long start, long end) throws IllegalArgumentException, InputFormatException, Exception {
    try{
    if(!sourcefile.toLowerCase().endsWith(".wav") || !targetfile.toLowerCase().endsWith(".wav")){
    return false;
    }
    //转出128文件
    remake(sourcefile, temFile);

    File wav = new File(temFile);



    if(!wav.exists()){
    return false;
    }
    long t1 = getTimeLenMs(wav); //总时长(毫秒)
    System.out.println(t1);




    if(start<0 || end<=0 || start>=t1 || end>t1 || start>=end){
    return false;
    }
    FileInputStream fis = new FileInputStream(wav);
    long wavSize = wav.length()-44; //音频数据大小(44为128kbps比特率wav文件头长度)
    long splitSize = (wavSize/t1)*(end-start); //截取的音频数据大小
    long skipSize = (wavSize/t1)*start; //截取时跳过的音频数据大小



    int splitSizeInt = Integer.parseInt(String.valueOf(splitSize));
    int skipSizeInt = Integer.parseInt(String.valueOf(skipSize));

    ByteBuffer buf1 = ByteBuffer.allocate(4); //存放文件大小,4代表一个int占用字节数
    buf1.putInt(splitSizeInt+36); //放入文件长度信息
    byte[] flen = buf1.array(); //代表文件长度
    ByteBuffer buf2 = ByteBuffer.allocate(4); //存放音频数据大小,4代表一个int占用字节数
    buf2.putInt(splitSizeInt); //放入数据长度信息
    byte[] dlen = buf2.array(); //代表数据长度
    flen = reverse(flen); //数组反转
    dlen = reverse(dlen);
    byte[] head = new byte[44]; //定义wav头部信息数组
    fis.read(head, 0, head.length); //读取源wav文件头部信息
    for(int i=0; i<4; i++){ //4代表一个int占用字节数
    head[i+4] = flen[i]; //替换原头部信息里的文件长度
    head[i+40] = dlen[i]; //替换原头部信息里的数据长度
    }
    byte[] fbyte = new byte[splitSizeInt+head.length]; //存放截取的音频数据
    for(int i=0; i<head.length; i++){ //放入修改后的头部信息
    fbyte[i] = head[i];
    }
    byte[] skipBytes = new byte[skipSizeInt]; //存放截取时跳过的音频数据
    fis.read(skipBytes, 0, skipBytes.length); //跳过不需要截取的数据
    fis.read(fbyte, head.length, fbyte.length-head.length); //读取要截取的数据到目标数组
    fis.close();

    File target = new File(targetfile);
    if(target.exists()){ //如果目标文件已存在,则删除目标文件
    target.delete();
    }
    FileOutputStream fos = new FileOutputStream(target);
    fos.write(fbyte);
    fos.flush();
    fos.close();
    }catch(IOException e){
    e.printStackTrace();
    return false;
    }
    return true;
    }

    /**
    * 获取音频文件总时长
    * @param filePath 文件路径
    * @return
    */
    public static long getTimeLen(File file){
    long tlen = 0;
    if(file!=null && file.exists()){
    Encoder encoder = new Encoder();
    try {
    MultimediaInfo m = encoder.getInfo(file);
    long ls = m.getDuration();
    tlen = ls/1000;
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    return tlen;
    }

    /**
    * 获取音频文件总时长(ms)
    * @param filePath 文件路径
    * @return
    */
    public static long getTimeLenMs(File file){
    long tlen = 0;
    if(file!=null && file.exists()){
    Encoder encoder = new Encoder();
    try {
    MultimediaInfo m = encoder.getInfo(file);
    long ls = m.getDuration();
    tlen = ls;
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    return tlen;
    }

    /**
    * 数组反转
    * @param array
    */
    public static byte[] reverse(byte[] array){
    byte temp;
    int len=array.length;
    for(int i=0;i<len/2;i++){
    temp=array[i];
    array[i]=array[len-1-i];
    array[len-1-i]=temp;
    }
    return array;
    }



    /**
    * 把256转出128
    * @author yanwenbin
    * @version 创建时间:2018年10月25日 下午3:11:24
    */
    public static void remake(String sourcefile, String targetfile) throws IllegalArgumentException, InputFormatException, EncoderException{
    File tag = new File(targetfile);
    File wav = new File(sourcefile);
    Encoder encoder = new Encoder();
    //ywb
    /*文件来源=新文件(“source.wav”);
    文件目标=新文件(“target.mp3”); */
    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("wav");
    //attrs.setAudioAttributes("音频");

    attrs.setAudioAttributes(audio);
    //编码器编码器=新编码器();

    encoder.encode(wav,tag,attrs);

    //ywb
    }

    public static void main(String[] args){
    /*try {
    a("C:\Users\Administrator\Desktop\20_1_1539940059183.wav","f:\111-cut_0_10.wav");
    } catch (IllegalArgumentException | EncoderException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }*/
    try {
    System.out.println(cut("C:\Users\Administrator\Desktop\audio\5.wav","C:\Users\Administrator\Desktop\audio\5-128.wav","C:\Users\Administrator\Desktop\audio\5-son1.wav",0,3000));
    } catch (IllegalArgumentException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (InputFormatException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    /* System.out.println(cut("f:\111.wav","f:\111-cut_10_20.wav",10,20));
    System.out.println(cut("f:\111.wav","f:\111-cut_20_28.wav",20,28)); */
    }

    }

  • 相关阅读:
    openpyxl(python操作Excel)
    python爬虫之数据加密解密
    python爬虫之字体反爬
    识别缩略图加载
    Windows文件共享自动失效解决办法
    pygame
    获取文件路径、文件名、后缀名
    Oracle EBS INV 挑库发放物料搬运单
    Oracle EBS INV 删除保留
    Oracle EBS INV 创建货位
  • 原文地址:https://www.cnblogs.com/ywb2018/p/9850108.html
Copyright © 2011-2022 走看看