gpt4 book ai didi

android - 使用媒体编解码器将 PCM 转换为 AAC

转载 作者:IT老高 更新时间:2023-10-28 23:00:49 26 4
gpt4 key购买 nike

我正在使用 Android (Jelly Bean) 中的媒体编解码器类将 PCM 格式编码为 AAC。该文件已编码,但没有音乐播放器能够播放该文件。我在网上找不到任何工作代码或适当的文档。

这是我的代码:

public void doConvert()
{

new AsyncTask<Void, Void, Void>()
{

@Override
protected Void doInBackground(Void... params)
{
try
{
int codecCount = MediaCodecList.getCodecCount();

for ( int i=0; i < codecCount; i++)
{
MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
Logger.getLogger(MainActivity.class.getSimpleName()).log(Level.INFO, info.getName());
for ( String type : info.getSupportedTypes() )
{
Logger.getLogger(MainActivity.class.getSimpleName()).log(Level.INFO, type);
}

}

File inputFile = new File( Environment.getExternalStorageDirectory().getAbsolutePath()+"/Download/Ghajini27_Mono_8Khz.wav");
//File inputFile = new File( sampleFD.get);
Log.e("File", String.valueOf(inputFile.length()));
FileInputStream fis = new FileInputStream(inputFile);
fis.skip(44);//remove wav header

File outputFile = new File( Environment.getExternalStorageDirectory().getAbsolutePath()+"/Download/out.m4a");
if ( outputFile.exists()) outputFile.delete();

FileOutputStream fos = new FileOutputStream(outputFile);

//BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(outputFile));
MediaCodec codec = MediaCodec.createEncoderByType("audio/mp4a-latm");
MediaFormat outputFormat = MediaFormat.createAudioFormat("audio/mp4a-latm", 22050, 1);
outputFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
// outputFormat.setInteger(MediaFormat.KEY_CHANNEL_MASK, AudioFormat.CHANNEL_CONFIGURATION_MONO);
outputFormat.setInteger(MediaFormat.KEY_BIT_RATE, 22050 );
outputFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
//outputFormat.setLong(MediaFormat.KEY_MAX_INPUT_SIZE, inputFile.length());
double durationInMs = (inputFile.length()/16000)*1000;
Log.e("duration",String.valueOf((long)durationInMs));
outputFormat.setLong(MediaFormat.KEY_DURATION, (long)durationInMs );


codec.configure(outputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE );
codec.start();

ByteBuffer[] inputBuffers = codec.getInputBuffers();
ByteBuffer[] outputBuffer = codec.getOutputBuffers();

boolean hasMoreData = true;
MediaCodec.BufferInfo outBuffInfo = new BufferInfo();
byte readBuffer[] = new byte[48000];
byte writeBuffer[] = new byte[48000];

do
{
int nextBuffer = codec.dequeueInputBuffer(5000);
Log.e("NextBuffer","nextInputBuffer = "+nextBuffer);

if ( nextBuffer >= 0 )
{



ByteBuffer inBuf = inputBuffers[nextBuffer];
inBuf.clear();
int bytesRead = fis.read( readBuffer,0, inBuf.capacity() );

Log.e("bytesread","Read = "+bytesRead);

if ( bytesRead < inBuf.capacity() )
{
hasMoreData = false;
}

inBuf.put(readBuffer, 0, bytesRead);

codec.queueInputBuffer(nextBuffer, 0, bytesRead, 0, hasMoreData?0:MediaCodec.BUFFER_FLAG_END_OF_STREAM);
}


int outputBufferIndex = codec.dequeueOutputBuffer( outBuffInfo, 3000);
/* logger.log(Level.INFO,"nextOutputBuffer = "+outputBufferIndex);
logger.log(Level.INFO,"outBuffInfo offset = "+outBuffInfo.offset);
logger.log(Level.INFO,"outBuffInfo size = "+outBuffInfo.size);
logger.log(Level.INFO,"outBuffInfo flags = "+outBuffInfo.flags);*/


//while ( outputBufferIndex > -1 )
//{

outputBuffer[outputBufferIndex].position(outBuffInfo.offset);
outputBuffer[outputBufferIndex].get(writeBuffer,0,outBuffInfo.size);

fos.write(writeBuffer,0, outBuffInfo.size);
// logger.log(Level.INFO,"Writing = "+outBuffInfo.size+" bytes");


outputBuffer[outputBufferIndex].clear();

codec.releaseOutputBuffer(outputBufferIndex, false);

if ( outBuffInfo.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM )
{
codec.flush();
codec.stop();
codec.release();
break;
}

//outputBufferIndex = codec.dequeueOutputBuffer( outBuffInfo, 1000 );
//logger.log(Level.INFO,"nextOutputBuffer = "+outputBufferIndex);
//}

} while (outBuffInfo.flags != MediaCodec.BUFFER_FLAG_END_OF_STREAM);

fis.close();
fos.flush();
fos.close();



}
catch ( Exception e)
{
//Logger.getLogger(MainActivity.class.getSimpleName()).log(Level.INFO, "Codec Error",e);
}

//logger.log(Level.INFO,"Done");

return null;
}

}.execute();
}

最佳答案

您需要为其选择一个容器。我更喜欢广告。

将有效负载数据复制到一个对您的容器足够大的数组中,只需添加您的位即可。所以在网上搜索了我的解决方案后,我做了一些 fragment

方法'fillInADTSHeader'

    profile =( configParams[0]>>3 )&0x1f;

frequency_index = (this.configParams[0]&0x7) <<1 | (this.configParams[1]>>7) &0x1;

channel_config = (this.configParams[1]>>3) &0xf;

int finallength = encoded_length + 7;
ENCodedByteArray[0] = (byte) 0xff;
ENCodedByteArray[1] = (byte) 0xf1;
ENCodedByteArray[2] = (byte) ( ((profile - 1) << 6) + (frequency_index << 2) +(channel_config >> 2));
ENCodedByteArray[3] = (byte) (((channel_config & 0x3) << 6) + (finallength >> 11));
ENCodedByteArray[4] = (byte)( (finallength & 0x7ff) >> 3);
ENCodedByteArray[5] = (byte) (((finallength & 7) << 5) + 0x1f) ;
ENCodedByteArray[6] = (byte) 0xfc;

使用类似的东西

            byte chunkADTS[]=new byte[info.size + 7];
fillInADTSHeader(chunkADTS,info.size);
outputBuffers[bR].get(chunkADTS,7,info.size);
buffer.pushData(chunkADTS);

应该在广播等中播放...

关于android - 使用媒体编解码器将 PCM 转换为 AAC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14934305/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com