一、程序运行效果图
二、下载链接
三、实现
1、main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<EditText
android:id="@+id/editText1"
android:hint="源wav文件的路径"
android:text="/sdcard/ylzs.wav"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</EditText>
<EditText
android:id="@+id/editText2"
android:hint="目标MP3文件的路径"
android:layout_width="match_parent"
android:text="/sdcard/ylzs.mp3"
android:layout_height="wrap_content" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="转化"
android:onClick="convert"
/>
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="获取lame版本号"
android:onClick="getversion"
/>
</LinearLayout>
2、MainActivity
package com.njupt.lame;
import java.io.File;
import android.os.Bundle;
import android.app.Activity;
import android.app.ProgressDialog;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;
public class MainActivity extends Activity {
private EditText et_wav;
private EditText et_mp3;
private ProgressDialog pd;
public native void convertmp3(String wav,String mp3);
public native String getLameVersion();
public native void stop();
static{
System.loadLibrary("Hello");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et_wav = (EditText) findViewById(R.id.editText1);
et_mp3 = (EditText) findViewById(R.id.editText2);
pd = new ProgressDialog(this);
}
public void convert(View view){
final String mp3name = et_mp3.getText().toString().trim();
final String wavname = et_wav.getText().toString().trim();
File file = new File(wavname);
int size = (int) file.length();
System.out.println("file size: " + size);
if("".equals(mp3name) ||"".equals(wavname)){
Toast.makeText(this, "path can not be null..", 1).show();
return ;
}
pd.setMessage("converting....");
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMax(size);
pd.show();
new Thread(){
public void run() {
convertmp3(wavname, mp3name);
pd.dismiss();
};
}.start();
}
public void setConvertProgress(int progress){
pd.setProgress(progress);
}
public void getversion(View view){
String version = getLameVersion();
Toast.makeText(this, version, 1).show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
3、Hello.c
#include <stdio.h>
#include <jni.h>
#include "com_njupt_lame_MainActivity.h"
#include <android/log.h>
#include <lame.h>
#define LOG_TAG "System.out"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
int flag = 0;
char* Jstring2CStr(JNIEnv* env, jstring jstr) {
char* rtn = NULL;
jclass clsstring = (*env)->FindClass(env, "java/lang/String");
jstring strencode = (*env)->NewStringUTF(env, "GB2312");
jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes",
"(Ljava/lang/String;)[B");
jbyteArray barr = (jbyteArray)(*env)->CallObjectMethod(env, jstr, mid,
strencode); // String .getByte("GB2312");
jsize alen = (*env)->GetArrayLength(env, barr);
jbyte* ba = (*env)->GetByteArrayElements(env, barr, JNI_FALSE);
if (alen > 0) {
rtn = (char*) malloc(alen + 1); //"\0"
memcpy(rtn, ba, alen);
rtn[alen] = 0;
}
(*env)->ReleaseByteArrayElements(env, barr, ba, 0); //
return rtn;
}
void publishJavaProgress(JNIEnv * env, jobject obj, jint progress) {
// 调用java代码 更新程序的进度条
// 1.找到java的LameActivity的class
// jclass (*FindClass)(JNIEnv*, const char*);
jclass clazz = (*env)->FindClass(env, "com/njupt/lame/MainActivity");
if (clazz == 0) {
LOGI("can't find clazz");
}
LOGI(" find clazz");
//2 找到class 里面的方法定义
// jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
jmethodID methodid = (*env)->GetMethodID(env, clazz, "setConvertProgress",
"(I)V");
if (methodid == 0) {
LOGI("can't find methodid");
}
LOGI(" find methodid");
//3 .调用方法
// void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
(*env)->CallVoidMethod(env, obj, methodid, progress);
}
JNIEXPORT void JNICALL Java_com_njupt_lame_MainActivity_convertmp3
(JNIEnv * env, jobject obj, jstring jwav, jstring jmp3){
char* cwav =Jstring2CStr(env,jwav) ;
char* cmp3=Jstring2CStr(env,jmp3);
LOGI("wav = %s", cwav);LOGI("mp3 = %s", cmp3);
//1.打开 wav,MP3文件
FILE* fwav = fopen(cwav,"rb");
FILE* fmp3 = fopen(cmp3,"wb");
short int wav_buffer[8192*2];
unsigned char mp3_buffer[8192];
//1.初始化lame的编码器
lame_t lame = lame_init();
//2. 设置lame mp3编码的采样率
lame_set_in_samplerate(lame , 44100);
lame_set_num_channels(lame,2);
// 3. 设置MP3的编码方式
lame_set_VBR(lame, vbr_default);
lame_init_params(lame);
LOGI("lame init finish");int read ; int write; //代表读了多少个次 和写了多少次
int total=0; // 当前读的wav文件的byte数目
do{
if(flag==404){
return;
}
read = fread(wav_buffer,sizeof(short int)*2, 8192,fwav);
total += read* sizeof(short int)*2;
LOGI("converting ....%d", total);publishJavaProgress(env,obj,total);
// 调用java代码 完成进度条的更新
if(read!=0){
write = lame_encode_buffer_interleaved(lame,wav_buffer,read,mp3_buffer,8192);
//把转化后的mp3数据写到文件里
fwrite(mp3_buffer,sizeof(unsigned char),write,fmp3);
}
if(read==0){
lame_encode_flush(lame,mp3_buffer,8192);
}
}while(read!=0);
LOGI(
"convert finish");
lame_close(lame);
fclose(fwav);
fclose(fmp3);
}
JNIEXPORT jstring JNICALL Java_com_njupt_lame_MainActivity_getLameVersion(
JNIEnv * env, jobject obj){
return (*env)->NewStringUTF(env,get_lame_version());
}
JNIEXPORT void JNICALL Java_com_njupt_lame_MainActivity_stop
(JNIEnv * env, jobject obj){
}
4、Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Hello
LOCAL_SRC_FILES := bitstream.c fft.c id3tag.c mpglib_interface.c presets.c quantize.c reservoir.c tables.c util.c VbrTag.c encoder.c gain_analysis.c lame.c newmdct.c psymodel.c quantize_pvt.c set_get.c takehiro.c vbrquantize.c version.c Hello.c
LOCAL_LDLIBS += -llog
include $(BUILD_SHARED_LIBRARY)
5、移植lame
主要是做好以下几步:
1)将include目录下的lame.h文件拷到jni目录下
2)将libmp3lame中的东西都拷到jni目录下。并删除一些不是以.rc 、.ico、MakeFile..文件
、删除i386那个目录
3)将util.h文件中的第374行左右的类型改成float