当前位置: 首页 > 面试题库 >

在Android中使用liblame将pcm文件转换为mp3

齐兴运
2023-03-14
问题内容

我正在使用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是正确的吗?和…


问题答案:

昨天,我使用la脚为我的应用程序实现了PCM到MP3编码器。我建议不要使用SimpleLameLibForAndroid,而是自己添加la脚到您的项目中。如果您使用的是Android
Studio,那么如果您以前没有做过NDK,那么这里是个不错的指南。

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

至于实现la脚本身,下面是一个非常好的指南,我遵循该指南来启动并运行应用程序。使用wrapper.c页面顶部的.zip中的。这暴露了有用的方法,这样就可以避开所有的肮脏StreamBuffer东西。

html" target="_blank">html" target="_blank">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()



 类似资料:
  • 我想在Python脚本中使用SOX之类的工具将。PCM文件转换为。wav文件。该工具需要跨平台兼容(Windows和Linux)。有什么建议吗?

  • 我有一个应用程序,可以用相机拍摄视频。我可以获取视频的文件路径,但我需要它作为Uri。 我得到的文件路径: 我需要的是这样的: 这是我的密码。 我需要一个Uri从字符串变量。

  • 问题内容: 我有一个文本文件(.txt)。我想将其转换为图像(.png或.jpg)。例如,在白色背景上的黑色文本。如何以编程方式做到这一点? 问题答案: 此(未经测试的)代码应使您走上正确的道路。

  • 问题内容: 我需要帮助来理解使用java将XML文件转换为CSV文件所涉及的步骤。这是XML文件的示例 这是生成的CSV文件。 我当时正在考虑使用DOM解析器读取xml文件。我遇到的问题是,我需要按名称指定要编码的特定元素,但我希望它能够解析它而不这样做。 Java中是否有任何工具或库可以帮助我实现这一目标。 如果我下面有这种格式的XML文件,并且想在与MSgId相同的行中添加InitgPty的值

  • 我是JavaFX的新手,我正在尝试使用javafxmobile插件转换到Android apk。 在使用gradlew转换到Android时,我遇到了一个错误,如执行失败。 我的系统安装了JDK 1.8U40,并且使用它配置了gradle。 我也尝试使用Dalvik SDK,但它仍然无法转换。 以下是完整的错误: > 出了问题: 任务“:dex”执行失败。 org.gradle.api.gradl

  • 我正在收听现场电话,并能够获得原始的PCM字节。我还可以通过java的音频api来收听这些字节。这些都在一个小程序上工作。 现在,我希望能够将电话呼叫的原始PCM字节转换为WAV字节,以便直接将其写入ServletOutputStream。这将允许浏览器实际监听电话。 有人知道我如何能够将一些原始PCM字节[]转换为WAV字节[]吗? 我看到的例子都与将一个文件转换为另一个文件有关。 java p