Android下使用lamemp3庫將PCM錄音數據壓縮爲MP3格式

以前已經介紹過iOS下使用lamemp3將PCM壓縮爲mp3格式,今天介紹一下Android的使用。 java


至於lamemp3庫的下載就再也不介紹了,你們能夠直接把iOS的那個庫拷過來,或者使用我附件中的庫也能夠。 c++


下面我介紹一下整個使用步驟,我將按照由上到下的方式來說解: 數組


1.  編寫連接動態庫的java文件: app


package com.example.mp3encodedemo; 框架


publicclass JNIMp3Encode { ui


   public native void init(int channel, int sampleRate, int brate); spa

   public native void destroy(); code

   public native byte[] encode(short[] buffer, int len); 內存


   static{ get

       System.loadLibrary("mp3lame");

   }


}


這裏聲明瞭3個native方法:init,destroy,encode,這些都是由c 、c++實現的。

init方法的參數:channel聲道數,sampleRate採樣率,brate壓縮的比特率

encode方法的參數:short[] buffer, int len這個是錄音的數據,注意是short類型


2.  根據java文件生成JNI的頭文件


cd到工程目錄下的bin/classes目錄下

hejinlai_iMac:classes hejinlai$ pwd

/Users/hejinlai/Workspace/Android/Mp3EncodeDemo/bin/classes


調用javah生成jni頭文件

hejinlai_iMac:classes hejinlai$ javah com.example.mp3encodedemo.JNIMp3Encode


3.  根據生成的頭文件,實現裏面的方法


/* DO NOT EDIT THIS FILE - it is machine generated */

#include<jni.h>

/* Header for class com_example_mp3encodedemo_JNIMp3Encode */


#ifndef _Included_com_example_mp3encodedemo_JNIMp3Encode

#define _Included_com_example_mp3encodedemo_JNIMp3Encode

#ifdef __cplusplus

extern"C" {

#endif


#include"libmp3lame/lame.h"

#define BUFFER_SIZE 4096


lame_t lame;


/*

* Class:     com_example_mp3encodedemo_JNIMp3Encode

* Method:    init

* Signature: (III)V

*/

JNIEXPORT void JNICALL Java_com_example_mp3encodedemo_JNIMp3Encode_init

 (JNIEnv *env, jobject obj, jint channel, jint sampleRate, jint brate)

{

lame = lame_init();

lame_set_num_channels(lame, channel);

lame_set_in_samplerate(lame, sampleRate);

lame_set_brate(lame, brate);

lame_set_mode(lame, 1);

lame_set_quality(lame, 2);

lame_init_params(lame);

}


/*

* Class:     com_example_mp3encodedemo_JNIMp3Encode

* Method:    destroy

* Signature: ()V

*/

JNIEXPORT void JNICALL Java_com_example_mp3encodedemo_JNIMp3Encode_destroy

 (JNIEnv *env, jobject obj)

{

lame_close(lame);

}


/*

* Class:     com_example_mp3encodedemo_JNIMp3Encode

* Method:    encode

* Signature: ([SI)[B

*/

JNIEXPORT jbyteArray JNICALL Java_com_example_mp3encodedemo_JNIMp3Encode_encode

 (JNIEnv *env, jobject obj, jshortArray buffer, jint len)

{

int nb_write = 0;

char output[BUFFER_SIZE];


// 轉換爲本地數組

jshort *input = (*env)->GetShortArrayElements(env, buffer, NULL);


// 壓縮mp3

nb_write = lame_encode_buffer(lame, input, input, len, output, BUFFER_SIZE);


// 局部引用,建立一個byte數組

jbyteArray result = (*env)->NewByteArray(env, nb_write);


// 給byte數組設置值

(*env)->SetByteArrayRegion(env, result, 0, nb_write, (jbyte *)output);


// 釋放本地數組(避免內存泄露)

(*env)->ReleaseShortArrayElements(env, buffer, input, 0);


return result;

}


#ifdef __cplusplus

}

#endif

#endif


這裏調用到了lame的方法,使用到了不少JNI的知識,不是很瞭解的你們能夠參考相關資料。


4.  將整個libmp3lame庫拷貝到jni目錄下,編寫Android.mk文件


LOCAL_PATH :$(call my-dir)


include$(CLEAR_VARS)


LOCAL_MODULE    := libmp3lame


LOCAL_SRC_FILES := \

./libmp3lame/bitstream.c \

./libmp3lame/encoder.c \

./libmp3lame/fft.c \

./libmp3lame/gain_analysis.c \

./libmp3lame/id3tag.c \

./libmp3lame/lame.c \

./libmp3lame/mpglib_interface.c \

./libmp3lame/newmdct.c \

./libmp3lame/presets.c \

./libmp3lame/psymodel.c \

./libmp3lame/quantize.c \

./libmp3lame/quantize_pvt.c \

./libmp3lame/reservoir.c \

./libmp3lame/set_get.c \

./libmp3lame/tables.c \

./libmp3lame/takehiro.c \

./libmp3lame/util.c \

./libmp3lame/vbrquantize.c \

./libmp3lame/VbrTag.c \

./libmp3lame/version.c \

lamemp3_wrapper.c


LOCAL_LDLIBS := -llog


include$(BUILD_SHARED_LIBRARY)


5.  調用ndk-build進行編譯,生成so文件


hejinlai_iMac:jni hejinlai$ ndk-build

........

Compile thumb  : mp3lame <= version.c

SharedLibrary  : libmp3lame.so

Install        : libmp3lame.so => libs/armeabi/libmp3lame.so


到這裏,整個調用的框架都搭建完成了,只須要在java中調用JNIMp3Encode中的方法便可,剩下的步驟就不在介紹了。


說明:


1.  我錄音的格式爲:16位  16k的pcm,這個要和lamemp3設置時的參數保持一致


2.  打開應用後,點擊底部按鈕的「開始說話」進行錄音,再點擊「說完了」中止錄音,壓縮後的MP3

文件保存在sdcard下mp3_recording目錄下的recording.mp3中,讀者能夠將它拷貝出來用通常的播放器播放,或者調用MediaPlayer播放

相關文章
相關標籤/搜索