一、程序运行效果图
二、下载链接
http://download.csdn.net/detail/caihongshijie6/6655407
三、实现
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){ }
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