java pcm转aac

Wesley13
• 阅读 683
import android.media.MediaCodec;import android.media.MediaCodecInfo;import android.media.MediaFormat;import android.util.Log;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.nio.ByteBuffer;/** * pcm转AAC编码 * Created by gj on 2017/4/7. */public class AacEncode {    private MediaCodec mediaCodec;    private String mediaType = "OMX.google.aac.encoder";    //解码后保存文件    private File file;    ByteBuffer[] inputBuffers = null;    ByteBuffer[] outputBuffers = null;    MediaCodec.BufferInfo bufferInfo;    FileOutputStream encFi = null;    //pts时间基数    long presentationTimeUs = 0;    //创建一个输出流用来输出转换的数据    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();    public AacEncode() {    }   //设置输出路径   public void setOutputPath(String outPath){        File file = new File(outPath);        try {            encFi = new FileOutputStream(file);        }catch (IOException e){            e.printStackTrace();        }    }    public void start(){        try {            mediaCodec = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_AUDIO_AAC);            //mediaCodec = MediaCodec.createByCodecName(mediaType);        } catch (IOException e) {            e.printStackTrace();        }        // 设置音频采样率,44100是目前的标准,但是某些设备仍然支持22050,16000,11025        final int kSampleRates[] = {8000, 11025, 22050, 44100, 48000};        //比特率 声音中的比特率是指将模拟声音信号转换成数字声音信号后,单位时间内的二进制数据量,是间接衡量音频质量的一个指标        final int kBitRates[] = {64000, 96000, 128000};        //初始化   此格式使用的音频编码技术、音频采样率、使用此格式的音频信道数(单声道为 1,立体声为 2)        MediaFormat mediaFormat = MediaFormat.createAudioFormat(                MediaFormat.MIMETYPE_AUDIO_AAC, kSampleRates[3], 2);        mediaFormat.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_AAC);        mediaFormat.setInteger(MediaFormat.KEY_AAC_PROFILE,MediaCodecInfo.CodecProfileLevel.AACObjectLC);        //比特率 声音中的比特率是指将模拟声音信号转换成数字声音信号后,单位时间内的二进制数据量,是间接衡量音频质量的一个指标        mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, kBitRates[1]);        //传入的数据大小        mediaFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 4096);// It will        //设置相关参数        mediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);        //开始        mediaCodec.start();        inputBuffers = mediaCodec.getInputBuffers();        outputBuffers = mediaCodec.getOutputBuffers();        bufferInfo = new MediaCodec.BufferInfo();    }    /**     * 关闭释放资源     *     * @author:gj     * @date: 2017/4/25     * @time: 16:19     **/    public void close() {        try {            mediaCodec.stop();            mediaCodec.release();            outputStream.flush();            outputStream.close();            encFi.close();        } catch (Exception e) {            e.printStackTrace();        }    }    /**     * 开始编码     * offset 偏移量   * size   数据大小     **/    public void encode(byte[] input, int offset, int size) throws Exception {        int inputBufferIndex = mediaCodec.dequeueInputBuffer(-1);//其中需要注意的有dequeueInputBuffer(-1),参数表示需要得到的毫秒数,-1表示一直等,0表示不需要等,传0的话程序不会等待,但是有可能会丢帧。        if (inputBufferIndex >= 0) {            ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];            inputBuffer.clear();            inputBuffer.put(input);            inputBuffer.limit(input.length);            //计算pts            long pts = computePresentationTime(presentationTimeUs);            mediaCodec.queueInputBuffer(inputBufferIndex, offset, size, pts, 0);            presentationTimeUs += 1;        }        int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);        while (outputBufferIndex >= 0) {            int outBitsSize = bufferInfo.size;            int outPacketSize = outBitsSize + 7; // 7 is ADTS size            ByteBuffer outputBuffer = outputBuffers[outputBufferIndex];            outputBuffer.position(bufferInfo.offset);            outputBuffer.limit(bufferInfo.offset + outBitsSize);            //添加ADTS头            byte[] outData = new byte[outPacketSize];            addADTStoPacket(outData, outPacketSize);            outputBuffer.get(outData, 7, outBitsSize);            outputBuffer.position(bufferInfo.offset);            //写到输出流里            outputStream.write(outData);            // Log.e("AudioEncoder", outData.length + " bytes written");            mediaCodec.releaseOutputBuffer(outputBufferIndex, false);            outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);        }        //输出流的数据转成byte[]        byte[] out = outputStream.toByteArray();        encFi.write(out);        //写完以后重置输出流,否则数据会重复        outputStream.flush();        outputStream.reset();    }    /**     * 给编码出的aac裸流添加adts头字段     *     * @param packet    要空出前7个字节,否则会搞乱数据     * @param packetLen     */    private void addADTStoPacket(byte[] packet, int packetLen) {        int profile = 2;  //AAC LC        int freqIdx = 4;  //44.1KHz        int chanCfg = 2;  //CPE        packet[0] = (byte) 0xFF;        packet[1] = (byte) 0xF9;        packet[2] = (byte) (((profile - 1) << 6) + (freqIdx << 2) + (chanCfg >> 2));        packet[3] = (byte) (((chanCfg & 3) << 6) + (packetLen >> 11));        packet[4] = (byte) ((packetLen & 0x7FF) >> 3);        packet[5] = (byte) (((packetLen & 7) << 5) + 0x1F);        packet[6] = (byte) 0xFC;    }    //计算PTS,实际上这个pts对应音频来说作用并不大,设置成0也是没有问题的    private long computePresentationTime(long frameIndex) {        return frameIndex * 90000 * 1024 / 44100;    }}//调用

import android.app.Activity;import android.os.Bundle;import android.util.Log;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class PcmAac extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_pcm_aac);        AacEncode aacEncode = new AacEncode();        aacEncode.start();        aacEncode.setOutputPath("/data/local/tmp/yi.aac");        int size = 4096;        byte[] inBuffer = new byte[size];        File inFile = new File("/data/local/tmp/yi.pcm");        FileInputStream in = null;        int len = 0;        try {            in = new FileInputStream(inFile);            while ((len = in.read(inBuffer, 0, 2048)) > 0){                aacEncode.encode(inBuffer, 1024, len);            }            aacEncode.close();        }catch (IOException e){            e.printStackTrace();        }catch (java.lang.Exception e){            e.printStackTrace();        }    }}
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Stella981 Stella981
3年前
Docker 部署SpringBoot项目不香吗?
  公众号改版后文章乱序推荐,希望你可以点击上方“Java进阶架构师”,点击右上角,将我们设为★“星标”!这样才不会错过每日进阶架构文章呀。  !(http://dingyue.ws.126.net/2020/0920/b00fbfc7j00qgy5xy002kd200qo00hsg00it00cj.jpg)  2
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这