【问题标题】:converting pcm file to mp3 using liblame in android在android中使用liblame将pcm文件转换为mp3
【发布时间】:2016-02-16 11:46:03
【问题描述】:

我正在使用SimpleLameLibForAndroid 将使用 Android 中的 AudioRecord 类创建的 pcm 文件转换为 mp3。我读取 pcm 文件并将其编码为 mp3,然后将其写入文件中。结果是 mp3 文件,但不正确,上面有很多噪音,很难理解它是录制的 pcm 文件。 这些是录制的音频规格(pcm 文件):

    private static final int RECORDER_SAMPLERATE = 8000;
    private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO;
    private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;    
    int BufferElements2Rec = 1024; // want to play 2048 (2K) since 2 bytes we use only 1024
    int BytesPerElement = 2; // 2 bytes in 16bit format
    recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
    RECORDER_SAMPLERATE, RECORDER_CHANNELS,
    RECORDER_AUDIO_ENCODING, BufferElements2Rec * BytesPerElement);

这是我使用 liblame 编码 mp3 并将其写入文件的代码:

//Encoder.Builder(int inSamplerate,int outChannel,int outSampleRate,int outBitrate)
Encoder en = new Encoder.Builder(8000, 1,8000,128).quality(7).create();
private int PCM_BUF_SIZE = 8192;
private int MP3_SIZE = 8192;
private void readFile()  {
    File pcm = new File("/sdcard/voice8K16bitmono.pcm");
    File mp3 = new File("/sdcard/BOOOB.mp3");
    pcm.setReadable(true);
    mp3.setWritable(true);
    try {
        InputStream is = new FileInputStream(pcm);
        BufferedInputStream bis = new BufferedInputStream(is);
        bis.skip(44);//skip pcm header
        OutputStream os = new FileOutputStream(mp3);
        FileOutputStream fos = new FileOutputStream(mp3);
        int n_bytes_read ;
        int n_bytes_write;
        int i;

        byte mp3_buffer[] = new byte[MP3_SIZE];
        byte pcm_buffer1[] = new byte[PCM_BUF_SIZE * 2];

        do {
            n_bytes_read = bis.read(pcm_buffer1 , 0 , PCM_BUF_SIZE);
            if (n_bytes_read == 0){
                n_bytes_write = en.flush(mp3_buffer);
            }
            else{
                n_bytes_write = en.encodeBufferInterleaved(byte2short(pcm_buffer1) ,n_bytes_read , mp3_buffer);
            }

            bof.write(mp3_buffer, 0, PCM_BUF_SIZE);

        } while (n_bytes_read > 0);
        bis.close();
        fos.close();
        is.close();
        en.close();

    }catch (IOException e) {
        e.printStackTrace();
    }
}
private short[] byte2short(byte[] pcm_buffer1) {
    short[] shorts = new short[pcm_buffer1.length/2];
   ByteBuffer.wrap(pcm_buffer1).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
    return shorts;
}

如何修复此代码,bufferSizes 是真的吗?使用 BufferedInputStream 是否正确?还有……

【问题讨论】:

    标签: java android mp3 lamemp3


    【解决方案1】:

    我昨天使用 lame 为我的应用程序实现了一个 PCM 到 MP3 编码器。我建议不要使用 SimpleLameLibForAndroid,而是自己将 lame 添加到您的项目中。如果您使用的是 Android Studio,如果您之前没有使用过 NDK,这里有一个很好的指南可以帮助您入门。

    http://www.shaneenishry.com/blog/2014/08/17/ndk-with-android-studio/

    至于实现 lame 本身,下面是一个非常好的指南,我按照它来启动和运行我的应用程序。使用页面顶部 .zip 中的 wrapper.c。这公开了有用的方法,因此您可以避免所有讨厌的 StreamBuffer 东西。

    http://developer.samsung.com/technical-doc/view.do?v=T000000090

    说到底,对跛脚编码器的实际调用非常简单,如下所示。

    用于初始化(使用您喜欢的任何设置):

    public static final int NUM_CHANNELS = 1;
    public static final int SAMPLE_RATE = 16000;
    public static final int BITRATE = 64;
    public static final int MODE = 1;
    public static final int QUALITY = 7;
    ...
    
    initEncoder(NUM_CHANNELS, SAMPLE_RATE, BITRATE, MODE, QUALITY);
    

    对于编码(非常简单):

    int result = encodeFile(pcm.getPath(), mp3.getPath());
    if (result == 0) {
        //success
    }
    

    当然,在使用destroyEncoder() 完成后会破坏编码器。

    【讨论】:

    • 朋友,我想在 android 中使用 Lame,但我不知道如何。您现在提供的链接不起作用。你能用一个简单的代码和要使用的库发一个帖子吗?谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多