Android Lame - 从RAW转换为MP3

时间:2015-10-14 10:59:17

标签: java android audio lame

我尝试使用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();
    }
}
}

0 个答案:

没有答案