关于ADPCM编码和PCM编码的wave文件通过Java进行相互转换

关于ADPCM编码和PCM编码的.wav文件通过Java进行相互转换

最近在做一个呼叫器的项目,中间碰到了点问题,就是呼叫器那边传过来的数据是ADPCM编码格式的,经过程序转换成.wav文件后可以在播放器上进行播放,但是无法在浏览器上进新播放。在网上查资料的时候,几乎都是C语言的版本,在程序中无法使用,就参考C语言用Java写了个编解码程序。

对.wav文件做编码转换,就需要对wav文件的格式进行了解,网上有很多wav文件格式解析的文章。我总结了一下,做了一个表格。

在这里插入图片描述代码里面有些重复的,没有进行优化缩减,用到的可以自行优化一下

wav头中的RIFF块

/**
 * @Description TODO
 * @Author liminghui
 * @Date 2020/3/14 9:14
 * @Version 1.0
 **/
public class RIFF {
    private String RIFFID;
    private Long RIFFSize;
    private String RIFFType;

    public RIFF() {
        this.RIFFID = "RIFF";
        this.RIFFType = "WAVE";
    }
    
    public String getRIFFID() {
        return RIFFID;
    }

    public void setRIFFID(String RIFFID) {
        this.RIFFID = RIFFID;
    }

    public Long getRIFFSize() {
        return RIFFSize;
    }

    public void setRIFFSize(Long RIFFSize) {
        this.RIFFSize = RIFFSize;
    }

    public String getRIFFType() {
        return RIFFType;
    }

    public void setRIFFType(String RIFFType) {
        this.RIFFType = RIFFType;
    }


}

wav头中的fmt 块

/**
 * @Description TODO
 * @Author liminghui
 * @Date 2020/3/14 9:14
 * @Version 1.0
 **/
public class FORMAT {
    private String FORMATID;
    private Long FORMATSize;
    private Integer FORMATAudioFormat;
    private Integer FORMATNumChannels;
    private Long FORMATSampleRate;
    private Long FORMATByteRate;
    private Integer FORMATBlockAlign;
    private Integer FORMATBitsPerSample;
    private Integer FORMATsbSize;
    private Integer FORMATSamplesPerBlock;

    public FORMAT(String str) {
        if (str == "ADPCM") {
            this.FORMATID = "fmt ";
            this.FORMATSize = 20l;
            this.FORMATAudioFormat = 17;
            this.FORMATNumChannels = 1;
            this.FORMATSampleRate = 8000l;
            this.FORMATByteRate = 4055l;
            this.FORMATBlockAlign = 256;
            this.FORMATBitsPerSample = 4;
            this.FORMATsbSize = 2;
            this.FORMATSamplesPerBlock = 505;
        } else {
            this.FORMATID = "fmt ";
            this.FORMATSize = 16l;
            this.FORMATAudioFormat = 1;
            this.FORMATNumChannels = 1;
            this.FORMATSampleRate = 8000l;
            this.FORMATByteRate = 16000l;
            this.FORMATBlockAlign = 2;
            this.FORMATBitsPerSample = 16;
        }

    }
    public String getFORMATID() {
        return FORMATID;
    }

    public void setFORMATID(String FORMATID) {
        this.FORMATID = FORMATID;
    }

    public Long getFORMATSize() {
        return FORMATSize;
    }

    public void setFORMATSize(Long FORMATSize) {
        this.FORMATSize = FORMATSize;
    }

    public Integer getFORMATAudioFormat() {
        return FORMATAudioFormat;
    }

    public void setFORMATAudioFormat(Integer FORMATAudioFormat) {
        this.FORMATAudioFormat = FORMATAudioFormat;
    }

    public Integer getFORMATNumChannels() {
        return FORMATNumChannels;
    }

    public void setFORMATNumChannels(Integer FORMATNumChannels) {
        this.FORMATNumChannels = FORMATNumChannels;
    }

    public Long getFORMATSampleRate() {
        return FORMATSampleRate;
    }

    public void setFORMATSampleRate(Long FORMATSampleRate) {
        this.FORMATSampleRate = FORMATSampleRate;
    }

    public Long getFORMATByteRate() {
        return FORMATByteRate;
    }

    public void setFORMATByteRate(Long FORMATByteRate) {
        this.FORMATByteRate = FORMATByteRate;
    }

    public Integer getFORMATBlockAlign() {
        return FORMATBlockAlign;
    }

    public void setFORMATBlockAlign(Integer FORMATBlockAlign) {
        this.FORMATBlockAlign = FORMATBlockAlign;
    }

    public Integer getFORMATBitsPerSample() {
        return FORMATBitsPerSample;
    }

    public void setFORMATBitsPerSample(Integer FORMATBitsPerSample) {
        this.FORMATBitsPerSample = FORMATBitsPerSample;
    }

    public Integer getFORMATsbSize() {
        return FORMATsbSize;
    }

    public void setFORMATsbSize(Integer FORMATsbSize) {
        this.FORMATsbSize = FORMATsbSize;
    }

    public Integer getFORMATSamplesPerBlock() {
        return FORMATSamplesPerBlock;
    }

    public void setFORMATSamplesPerBlock(Integer FORMATSamplesPerBlock) {
        this.FORMATSamplesPerBlock = FORMATSamplesPerBlock;
    }

wav头中的FACT 块

/**
 * @Description TODO
 * @Author liminghui
 * @Date 2020/3/14 9:14
 * @Version 1.0
 **/
public class FACT {
    private String FACTID;
    private Long FACTSize;
    private Long FACTSampleLength;

    public FACT() {
        this.FACTID = "fact";
        this.FACTSize = 4l;
    }

    public Long getFACTSampleLength() {
        return FACTSampleLength;
    }

    public void setFACTSampleLength(Long FACTSampleLength) {
        this.FACTSampleLength = FACTSampleLength;
    }

    public Long getFACTSize() {
        return FACTSize;
    }

    public void setFACTSize(Long FACTSize) {
        this.FACTSize = FACTSize;
    }

    public String getFACTID() {
        return FACTID;
    }

    public void setFACTID(String FACTID) {
        this.FACTID = FACTID;
    }
}

wav头中的DATA 块

/**
 * @Description TODO
 * @Author liminghui
 * @Date 2020/3/14 9:14
 * @Version 1.0
 **/
public class DATA {
    private String DATAID;
    private Long DATASize;

    public DATA() {
        this.DATAID = "data";
    }

    public Long getDATASize() {
        return DATASize;
    }

    public void setDATASize(Long DATASize) {
        this.DATASize = DATASize;
    }

    public String getDATAID() {
        return DATAID;
    }

    public void setDATAID(String DATAID) {
        this.DATAID = DATAID;
    }
}

wav头中的BLOCKHEARD 块

/**
 * @Description TODO
 * @Author liminghui
 * @Date 2020/3/14 9:16
 * @Version 1.0
 **/
public class BLOCKHEARD {
    private Integer BLOCKPresample;
    private Integer BLOCKIndex;
    private Integer BLOCKRSV;

    public BLOCKHEARD() {
        this.BLOCKRSV = 0;
    }

    public Integer getBLOCKPresample() {
        return BLOCKPresample;
    }

    public void setBLOCKPresample(Integer BLOCKPresample) {
        this.BLOCKPresample = BLOCKPresample;
    }

    public Integer getBLOCKIndex() {
        return BLOCKIndex;
    }

    public void setBLOCKIndex(Integer BLOCKIndex) {
        this.BLOCKIndex = BLOCKIndex;
    }

    public Integer getBLOCKRSV() {
        return BLOCKRSV;
    }

    public void setBLOCKRSV(Integer BLOCKRSV) {
        this.BLOCKRSV = BLOCKRSV;
    }
}

/**
* WAV文件以小端形式来进行数据存储。
* 所谓的大端模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;
* 所谓的小端模式,是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中。
* 以四个字节存储一个数据为例:类似于字符串,从右到左是从低位到高位
*/
编码encoder

package enCoder;

import entity.*;

import java.io.*;

/**
 * @Description TODO
 * @Author liminghui
 * @Date 2020/3/13 15:13
 * @Version 1.0
 **/
public class encoder02 {
    private static int[] indexTable={
            -1, -1, -1, -1, 2, 4, 6, 8,
            -1, -1, -1, -1, 2, 4, 6, 8};

    private static int[] stepsizeTable = {
            7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
            19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
            50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
            130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
            337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
            876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
            2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
            5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
            15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767};

    private static FileOutputStream fos = null;

    private static FileInputStream fis = null;

    private static RIFF riff = null;
    private static FORMAT format = null;
    private static DATA data = null;
    private static FACT fact = null;
    private static BLOCKHEARD blockheard = null;

    public static void main(String[] args) {
        try {
            File inFile = new File("C:\\Users\\Administrator\\Desktop\\pcm文档\\9110999302110.wav");
            File outFile = new File("C:\\Users\\Administrator\\Desktop\\pcm文档\\ddd.wav");
            if (!outFile.exists()) outFile.createNewFile();
            fis = new FileInputStream(inFile);
            fos = new FileOutputStream(outFile);
            long length = inFile.length();
            writeHeard(length);
            blockheard=new BLOCKHEARD();
            //设置默认的index和rsv
            blockheard.setBLOCKIndex(0);
            blockheard.setBLOCKRSV(0);
            byte[] inData=new byte[1024];
            //读取前44个字节的PCM编码的WAV头
            fis.read(inData, 0, 44);
            int len=0;
            while (len != -1) {
                byte[] bytes = new byte[2];
                fis.read(bytes,0,2);
                blockheard.setBLOCKPresample((bytes[0] & 0xff) | bytes[1] << 8);
                fos.write(Hex2ByteDTX(blockheard.getBLOCKPresample()));
                fos.write(HexByteDTX(blockheard.getBLOCKIndex()));
                fos.write(HexByteDTX(blockheard.getBLOCKRSV()));
                len = fis.read(inData, 0, 1008);
                if (len != -1) {
                    CoderRealize(inData, len, blockheard);
                }
            }
            fis.close();
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void CoderRealize(byte[] inData, int len, BLOCKHEARD blockheard) {
        try {
            int sign;
            int delta;
            int step;
            int valpred;
            int vpdiff;
            int diff;
            int index;
            boolean bufferstep;
            int outputbuffer = 0;

            valpred = blockheard.getBLOCKPresample();
            index = blockheard.getBLOCKIndex();
            step = stepsizeTable[index];
            bufferstep = true;
            for (int i = 0; i < len / 2; i++) {
                int val = (inData[i * 2] & 0xff) | inData[i * 2 + 1] << 8 ;
                    diff = val - valpred;
                    sign = (diff < 0) ? 8 : 0;
                    if (sign != 0) {
                        diff = (-diff);
                    }
                    delta = 0;
                    vpdiff = (step >> 3);

                    if (diff >= step) {
                        delta = 4;
                        diff -= step;
                        vpdiff += step;
                    }
                    step >>= 1;
                    if (diff >= step) {
                        delta |= 2;
                        diff -= step;
                        vpdiff += step;
                    }
                    step >>= 1;
                    if (diff >= step) {
                        delta |= 1;
                        vpdiff += step;
                    }
                    if (sign != 0)
                        valpred -= vpdiff;
                    else
                        valpred += vpdiff;
                    if (valpred > 32767)
                        valpred = 32767;
                    else if (valpred < -32768)
                        valpred = -32768;
                    delta |= sign;

                    index += indexTable[delta];
                    if (index < 0) index = 0;
                    if (index > 88) index = 88;
                    step = stepsizeTable[index];
                    if (bufferstep) {
                        outputbuffer = delta & 0x0f;
                    } else {
                        fos.write((byte) ((delta << 4) & 0xf0) | outputbuffer);
                    }
                    bufferstep = !bufferstep;
            }
            if (!bufferstep) {
                fos.write(outputbuffer & 0xff);
            }
            blockheard.setBLOCKIndex(index);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 16进制大端转小端
     *  WAV文件以小端形式来进行数据存储。
     */
    private static byte[] Hex4ByteDTX(Long l) {
        int len = 4;
        byte[] b = new byte[len];
        for (int i = 0; i < len; i++) {
            b[i] = (byte) (l >> (i * 8) & 0x00ff);
        }
        return b;
    }
    private static byte[] Hex2ByteDTX(int l) {
        int len = 2;
        byte[] b = new byte[len];
        for (int i = 0; i < len; i++) {
            b[i] = (byte) (l >> (i * 8) & 0x00ff);
        }
        return b;
    }
    private static byte HexByteDTX(int l) {
        byte b = (byte) (l & 0x00ff);
        return b;
    }


    private static void writeHeard(long length) {
        long dataSize = (length - 44) / 1010 * 256;
        if ((length - 44) % 1010 != 0) {
            dataSize += ((length - 44) % 1010 - 2) / 4 + 4;
        }
        riff = new RIFF();
        format = new FORMAT("ADPCM");
        data = new DATA();
        fact = new FACT();
        fact.setFACTSampleLength(dataSize);
        data.setDATASize(dataSize);
        riff.setRIFFSize(dataSize + 58);
        try {
            //写入RIFF块
            fos.write(riff.getRIFFID().getBytes());
            fos.write(Hex4ByteDTX(riff.getRIFFSize()));
            fos.write(riff.getRIFFType().getBytes());

            //写入‘fmt ’块
            fos.write(format.getFORMATID().getBytes());
            fos.write(Hex4ByteDTX(format.getFORMATSize()));
            fos.write(Hex2ByteDTX(format.getFORMATAudioFormat()));
            fos.write(Hex2ByteDTX(format.getFORMATNumChannels()));
            fos.write(Hex4ByteDTX(format.getFORMATSampleRate()));
            fos.write(Hex4ByteDTX(format.getFORMATByteRate()));
            fos.write(Hex2ByteDTX(format.getFORMATBlockAlign()));
            fos.write(Hex2ByteDTX(format.getFORMATBitsPerSample()));
            fos.write(Hex2ByteDTX(format.getFORMATsbSize()));
            fos.write(Hex2ByteDTX(format.getFORMATSamplesPerBlock()));

            //写入FACT块
            fos.write(fact.getFACTID().getBytes());
            fos.write(Hex4ByteDTX(fact.getFACTSize()));
            fos.write(Hex4ByteDTX(fact.getFACTSampleLength()));

            //写入Data块
            fos.write(data.getDATAID().getBytes());
            fos.write(Hex4ByteDTX(data.getDATASize()));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


解码decoder

package deCoder;

import entity.BLOCKHEARD;
import entity.DATA;
import entity.FORMAT;
import entity.RIFF;

import java.io.*;

/**
 * @Description TODO
 * @Author liminghui
 * @Date 2020/3/13 15:13
 * @Version 1.0
 **/
public class decoder {
    private static int[] indexTable={
            -1, -1, -1, -1, 2, 4, 6, 8,
            -1, -1, -1, -1, 2, 4, 6, 8};

    private static int[] stepsizeTable = {
            7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
            19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
            50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
            130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
            337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
            876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
            2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
            5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
            15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767};

    private static FileOutputStream fos = null;

    private static FileInputStream fis = null;

    private static RIFF riff = null;
    private static FORMAT format = null;
    private static DATA data = null;
    private static BLOCKHEARD blockheard = null;

    public static void main(String[] args) {
        try {
            File inFile = new File("C:\\Users\\Administrator\\Documents\\WeChat Files\\LMH13073784256\\FileStorage\\File\\2020-05\\888.pcm");
            File outFile = new File("C:\\Users\\Administrator\\Desktop\\pcm文档\\9110999302110.wav");
            if (!outFile.exists()) outFile.createNewFile();
            fis = new FileInputStream(inFile);
            fos = new FileOutputStream(outFile);
            long length = inFile.length();
            writeHeard(length);
            blockheard=new BLOCKHEARD();
            byte[] inData=new byte[1024];
            int len;
            while ((len = fis.read(inData, 0, 256)) != -1) {
                blockheard.setBLOCKPresample(inData[0]|inData[1]<<8);
                blockheard.setBLOCKIndex((int) inData[2]);
                blockheard.setBLOCKRSV((int) inData[3]);
                fos.write(inData[0]);
                fos.write(inData[1]);
                CoderRealize(inData, len, blockheard);
            }
            fis.close();
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void CoderRealize(byte[] inData, int len, BLOCKHEARD blockheard) {
        int sign;
        int delta;
        int step;
        int valpred;
        int vpdiff;
        int index;
        boolean bufferstep;
        int j=4;
        valpred = blockheard.getBLOCKPresample();
        index = blockheard.getBLOCKIndex();
        step = stepsizeTable[index];
        bufferstep = true;
        for (int i = 0; i < (len - 4) * 2; i++) {
            try {
                if (bufferstep) {
                    //取低四位
                    delta = inData[j] & 0xf;
                } else {
                    //取高四位
                    delta = (inData[j] >> 4) & 0xf;
                    j++;
                }
                bufferstep = !bufferstep;
                index += indexTable[delta];
                if (index < 0) index = 0;
                if (index > 88) index = 88;
                //取符号位 &(与运算)都为1才为1
                sign = delta & 8;//sing只会等于8或者0
                //取数据
                delta = delta & 7;
                //下边四则运算将vpdiff = (delta+0.5)*step/4四则运算转换成了二进制的与或运算(牛逼)
                vpdiff = step >> 3;
                if ((delta & 4) != 0) {
                    vpdiff += step;
                }
                if ((delta & 2) != 0) {
                    vpdiff += step >> 1;
                }
                if ((delta & 1) != 0) {
                    vpdiff += step >> 2;
                }
                if (sign != 0) {
                    valpred -= vpdiff;
                } else {
                    valpred += vpdiff;
                }
                if (valpred > 32767)
                    valpred = 32767;
                else if (valpred < -32768)
                    valpred = -32768;
                step = stepsizeTable[index];
                fos.write(Hex2ByteDTX(valpred));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

   
    private static byte[] Hex4ByteDTX(Long l) {
        int len = 4;
        byte[] b = new byte[len];
        for (int i = 0; i < len; i++) {
            b[i] = (byte) (l >> (i * 8) & 0x00ff);
        }
        return b;
    }
    private static byte[] Hex2ByteDTX(int l) {
        int len = 2;
        byte[] b = new byte[len];
        for (int i = 0; i < len; i++) {
            b[i] = (byte) (l >> (i * 8) & 0x00ff);
        }
        return b;
    }


    private static void writeHeard(long length) {
        long nBlock = length / 256;
        long dataSize=nBlock*505;
        long otherBytes = length % 256;
        if (otherBytes != 0) {
            dataSize +=(otherBytes-4)*2+1;
        }
        riff = new RIFF();
        format = new FORMAT("PCM");
        data = new DATA();
        data.setDATASize(dataSize * 2);
        riff.setRIFFSize(data.getDATASize() + 36);
        try {
            fos.write(riff.getRIFFID().getBytes());
            fos.write(Hex4ByteDTX(riff.getRIFFSize()));
            fos.write(riff.getRIFFType().getBytes());
            fos.write(format.getFORMATID().getBytes());
            fos.write(Hex4ByteDTX(format.getFORMATSize()));
            fos.write(Hex2ByteDTX(format.getFORMATAudioFormat()));
            fos.write(Hex2ByteDTX(format.getFORMATNumChannels()));
            fos.write(Hex4ByteDTX(format.getFORMATSampleRate()));
            fos.write(Hex4ByteDTX(format.getFORMATByteRate()));
            fos.write(Hex2ByteDTX(format.getFORMATBlockAlign()));
            fos.write(Hex2ByteDTX(format.getFORMATBitsPerSample()));
            fos.write(data.getDATAID().getBytes());
            fos.write(Hex4ByteDTX(data.getDATASize()));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
转换下面这些音频和视频,压缩包有包和源码,还有文档api. 整理资料不易,不喜欢可以自己百度 Audio decoders adpcm_4xm adpcm_adx adpcm_ct adpcm_ea adpcm_ea_r1 adpcm_ea_r2 adpcm_ea_r3 adpcm_ea_xas adpcm_ima_amv adpcm_ima_dk3 adpcm_ima_dk4 adpcm_ima_ea_eacs adpcm_ima_ea_sead adpcm_ima_qt adpcm_ima_smjpeg adpcm_ima_wav adpcm_ima_ws adpcm_ms adpcm_sbpro_2 adpcm_sbpro_3 adpcm_sbpro_4 adpcm_swf adpcm_thp adpcm_xa adpcm_yamaha alac ape atrac 3 cook dca dsicinaudio flac g726 imc interplay_dpcm liba52 libamr_nb libamr_wb libfaad libgsm libgsm_ms mace3 mace6 mp2 mp3 mp3adu mp3on4 mpc sv7 mpc sv8 mpeg4aac nellymoser pcm_alaw pcm_mulaw pcm_s16be pcm_s16le pcm_s16le_planar pcm_s24be pcm_s24daud pcm_s24le pcm_s32be pcm_s32le pcm_s8 pcm_u16be pcm_u16le pcm_u24be pcm_u24le pcm_u32be pcm_u32le pcm_u8 pcm_zork qdm2 real_144 real_288 roq_dpcm shorten smackaud sol_dpcm sonic truespeech tta vmdaudio vorbis wavpack wmav1 wmav2 ws_snd1 xan_dpcm Audio encoders ac3 adpcm_adx adpcm_ima_wav adpcm_ms adpcm_swf adpcm_yamaha flac g726 libamr_nb libamr_wb libfaac libgsm libgsm_ms libmp3lame libvorbis mp2 pcm_alaw pcm_mulaw pcm_s16be pcm_s16le pcm_s24be pcm_s24daud pcm_s24le pcm_s32be pcm_s32le pcm_s8 pcm_u16be pcm_u16le pcm_u24be pcm_u24le pcm_u32be pcm_u32le pcm_u8 pcm_zork roq_dpcm sonic sonicls vorbis wmav1 wmav2 Video decoders 4xm 8bps VMware video aasc amv asv1 asv2 avs bethsoftvid bmp c93 camstudio camtasia cavs cinepak cljr cyuv dnxhd dsicinvideo dvvideo dxa ffv1 ffvhuff flashsv flic flv fraps gif h261 h263 h263i h264 huffyuv idcinvideo indeo2 indeo3 interplayvideo jpegls kmvc loco mdec mjpeg mjpegb mmvideo mpeg1video mpeg2video mpeg4 mpegvideo msmpeg4 msmpeg4v1 msmpeg4v2 msrle msvideo1 mszh nuv pam pbm pgm pgmyuv png ppm ptx qdraw qpeg qtrle rawvideo roqvideo rpza rv10 rv20 sgi smackvid smc snow sp5x svq1 svq3 targa theora thp tiertexseqvideo tiff truemotion1 truemotion2 txd ultimotion vb vc1 vcr1 vmdvideo vp3 vp5 vp6 vp6a vp6f vqavideo wmv1 wmv2 wmv3 wnv1 xan_wc3 xl zlib zmbv Video encoders asv1 asv2 bmp dnxhd dvvideo ffv1 ffvhuff flashsv flv gif h261 h263 h263p huffyuv jpegls libtheora libx264 libxvid ljpeg mjpeg mpeg1video mpeg2video mpeg4 msmpeg4 msmpeg4v1 msmpeg4v2 pam pbm pgm pgmyuv png ppm qtrle rawvideo roqvideo rv10 rv20 sgi snow svq1 targa tiff wmv1 wmv2 zlib zmbv
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值