我尝试使用Lame将3gp转换为MP3。我通过内置的Android解码器解码文件后得到了字节缓冲区。在此之后,我将其放入带有OutputStream的RAW文件中,然后使用Lame创建MP3。但它不起作用。文件中只有噪音。这是我的代码。感谢您提前获得任何帮助。
public class MainActivityLame extends Activity {
static {
System.loadLibrary("mp3lame");
}
private native void initEncoder(int numChannels, int sampleRate, int bitRate, int mode, int quality);
private native void destroyEncoder();
private native int encodeFile(String sourcePath, String targetPath);
public static final int NUM_CHANNELS = 1;
public static final int SAMPLE_RATE = 44100;
public static final int BITRATE = 128;
public static final int MODE = 1;
public static final int QUALITY = 2;
private AudioRecord mRecorder;
private short[] mBuffer;
private File mRawFile;
private File mEncodedFile;
private TextView mTextViewFile;
private String strFile;
private AudioTrack audioTrack;
private int mChannels;
private ShortBuffer mDecodedSamples;
private ByteBuffer mDecodedBytes;
private int mFileSize;
private int bufferSize;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextViewFile = (TextView) findViewById(R.id.textViewFile);
initRecorder();
initEncoder(NUM_CHANNELS, SAMPLE_RATE, BITRATE, MODE, QUALITY);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void onClickFolder(View view) throws IOException {
Intent questionIntent = new Intent(MainActivityLame.this, MyListActivity.class);
startActivityForResult(questionIntent, 1);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
String itemName = data.getStringExtra(MyListActivity.ITEM);
mTextViewFile.setText(itemName);
} else {
mTextViewFile.setText("");
}
}
@Override
public void onDestroy() {
mRecorder.release();
destroyEncoder();
super.onDestroy();
}
private void initRecorder() {
bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);
mBuffer = new short[bufferSize];
mRecorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT, bufferSize);
}
private File getFile(final String suffix) {
Time time = new Time();
time.setToNow();
return new File(Environment.getExternalStorageDirectory(), time.format("%Y%m%d%H%M%S") + "." + suffix);
}
public void onClickExample(View view) {
strFile = mTextViewFile.getText().toString().trim();
MediaExtractor extractor = new MediaExtractor();
MediaFormat format = null;
extractor.setDataSource(strFile);
int numTracks = extractor.getTrackCount();
for (int i = 0; i < numTracks; ++i) {
format = extractor.getTrackFormat(i);
String mime = format.getString(MediaFormat.KEY_MIME);
if (mime.startsWith("audio/")) {
extractor.selectTrack(i);
break;
}
}
MediaCodec codec = MediaCodec.createDecoderByType(format.getString(MediaFormat.KEY_MIME));
codec.configure(format, null, null, 0);
codec.start();
int decodedSamplesSize = 0;
byte[] decodedSamples = null;
ByteBuffer[] inputBuffers = codec.getInputBuffers();
ByteBuffer[] outputBuffers = codec.getOutputBuffers();
int sample_size;
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
long presentation_time;
int tot_size_read = 0;
boolean done_reading = false;
mDecodedBytes = ByteBuffer.allocate(1 << 20);
while (true) {
int inputBufferId = codec.dequeueInputBuffer(100);
if (!done_reading && inputBufferId >= 0) {
sample_size = extractor.readSampleData(inputBuffers[inputBufferId], 0);
if (sample_size < 0) {
codec.queueInputBuffer(inputBufferId, 0, 0, -1, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
done_reading = true;
} else {
presentation_time = extractor.getSampleTime();
codec.queueInputBuffer(inputBufferId, 0, sample_size, presentation_time, 0);
extractor.advance();
tot_size_read += sample_size;
}
}
int outputBufferId = codec.dequeueOutputBuffer(info, 100);
if (outputBufferId >= 0 && info.size > 0) {
if (decodedSamplesSize < info.size) {
decodedSamplesSize = info.size;
decodedSamples = new byte[decodedSamplesSize];
}
outputBuffers[outputBufferId].get(decodedSamples, 0, info.size);
outputBuffers[outputBufferId].clear();
if (mDecodedBytes.remaining() < info.size) {
int position = mDecodedBytes.position();
int newSize = (int) ((position * (1.0 * mFileSize / tot_size_read)) * 1.2);
if (newSize - position < info.size + 5 * (1 << 20)) {
newSize = position + info.size + 5 * (1 << 20);
}
ByteBuffer newDecodedBytes = null;
int retry = 10;
while (retry > 0) {
try {
newDecodedBytes = ByteBuffer.allocate(newSize);
break;
} catch (OutOfMemoryError oome) {
retry--;
}
}
if (retry == 0) {
break;
}
mDecodedBytes.rewind();
newDecodedBytes.put(mDecodedBytes);
mDecodedBytes = newDecodedBytes;
mDecodedBytes.position(position);
}
mDecodedBytes.put(decodedSamples, 0, info.size);
codec.releaseOutputBuffer(outputBufferId, false);
} else if (outputBufferId == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
outputBuffers = codec.getOutputBuffers();
} else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
// Subsequent data will conform to new format.
format = codec.getOutputFormat();
}
if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
break;
}
}
extractor.release();
extractor = null;
codec.stop();
codec.release();
codec = null;
mDecodedBytes.rewind();
mDecodedBytes.order(ByteOrder.LITTLE_ENDIAN);
mDecodedSamples = mDecodedBytes.asShortBuffer();
mRawFile = getFile("raw");
OutputStream output = null;
try {
output = new BufferedOutputStream(new FileOutputStream(mRawFile));
try {
output.write(mDecodedBytes.array());
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
Toast.makeText(MainActivityLame.this, e.getMessage(), Toast.LENGTH_SHORT).show();
} finally {
if (output != null) {
try {
output.flush();
} catch (IOException e) {
Toast.makeText(MainActivityLame.this, e.getMessage(), Toast.LENGTH_SHORT).show();
} finally {
try {
output.close();
} catch (IOException e) {
Toast.makeText(MainActivityLame.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
}
}
mEncodedFile = getFile("mp3");
int result = encodeFile(mRawFile.getAbsolutePath(), mEncodedFile.getAbsolutePath());
if (result == 0) {
Toast.makeText(MainActivityLame.this, "Encoded to " + mEncodedFile.getName(), Toast.LENGTH_SHORT).show();
}
}
}