当前位置: 代码迷 >> Android >> Android JNI Lame编解码实现wav到MP3的变换
  详细解决方案

Android JNI Lame编解码实现wav到MP3的变换

热度:309   发布时间:2016-04-27 23:30:20.0
Android JNI Lame编解码实现wav到MP3的转换

1、JNI简介
JNI全称为Java Native Interface(JAVA本地调用)。从Java1.1开始,JNI成为java平台的一部分,它允许Java代码和其他语言写的代码(如C&C++)进行交互。并非从Android发布才引入JNI的概念的。
2、JNI与NDK
简单来说,Android的NDK提供了一些交叉编译工具链和Android自带的库,这些Android的库可以让开发者在编写本地语言的程序时调用。而NDK提供的交叉编译工具链就对已经编写好的C&C++代码进行编译,生成库。
当然了,你也可以自己搭建交叉编译环境,而不用NDK的工具和库。然后生成库,只要规范操作,一样可以生成能让JAVA层成功调用的库文件的。

    使用JNI技术,其实就是在Java程序中,调用C语言的函数库中提供的函数,来完成一些Java语言无法完成的任务。由于Java语言和C语言结构完全不相同,因此若想让它们二者交互,则需要制定一系列的规范。JNI就是这组规范,此时    Java只和JNI交互,而由JNI去和C语言交互。

JNI技术分为两部分:Java端和C语言端。且以Java端为主导。
|- 首先,Java程序员在Java端定义一些native方法,并将这些方法以C语言头文件的方式提供给C程序员。
|- 然后,C程序员使用C语言,来实现Java程序员提供的头文件中定义的函数。
|- 接着,C程序员将函数打包成一个库文件,并将库文件交给Java程序员。

在Java程序执行的时候,若在某个类中调用了native方法,则虚拟机会通过JNI来转调用库文件中的C语言代码。提示:C代码最终是在Linux进程中执行的,而不是在虚拟机中。

下面是一个Android调用JNI实现通过LAME转码器实现wav格式到MP3格式的转换.

准备:首先下载lame源码文件。
需要三个条件 :cgywin,cdt,ndk才能实现JNI的开发。
开发lame需要从http://lame.sourceforge.net/选择Using Lame 下载源代码。

新建工程
1、Android主界面布局

<?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/118/ccc.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/118/ccccc.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>

首先是建立JNI目录

1、把lameC语言源码导入jni中
2、创建Android.mk文件

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := HelloLOCAL_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.cLOCAL_LDLIBS += -lloginclude $(BUILD_SHARED_LIBRARY)

3、编写C语言文件

#include <stdio.h>#include <jni.h>#include "com_example_ndkpassdata_DataProvider.h"#include <android/log.h>#include<malloc.h>#define LOG_TAG "System.out.c"#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)char* Jstring2CStr(JNIEnv* env, jstring jstr) {    char* rtn = NULL;    jclass clsstring = (*env)->FindClass(env, "java/lang/String"); //String    jstring strencode = (*env)->NewStringUTF(env, "GB2312"); // 得到一个java字符串 "GB2312"    jmethodID mid = (*env)->GetMethodID(env, clsstring, "getBytes",            "(Ljava/lang/String;)[B"); //[ String.getBytes("gb2312");    jbyteArray barr = (jbyteArray)(*env)->CallObjectMethod(env, jstr, mid,            strencode); // String .getByte("GB2312");    jsize alen = (*env)->GetArrayLength(env, barr); // byte数组的长度    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;}JNIEXPORT jint JNICALL Java_com_example_ndkpassdata_DataProvider_add(        JNIEnv *env, jobject obj, jint x, jint y) {    LOGD("x=%d", x);    LOGD("y=%d", y);    return x + y;}JNIEXPORT jstring JNICALL Java_com_example_ndkpassdata_DataProvider_sayHelloInc(        JNIEnv *env, jobject obj, jstring jstr) {    char *cstr = Jstring2CStr(env, jstr);    LOGD("cstr=%s", cstr);    char arr[7] = { ' ', 'h', 'e', 'l', 'l', 'o', '/0' };    strcat(cstr, arr);    LOGD("newcstr=%s", cstr);    return (*env)->NewStringUTF(env, cstr);}JNIEXPORT jintArray JNICALL Java_com_example_ndkpassdata_DataProvider_intMethod(        JNIEnv *env, jobject obj, jintArray arr) {    int len = (*env)->GetArrayLength(env, arr);    LOGD("SHUZU length-=%d", len);    jint *intarr = (*env)->GetIntArrayElements(env, arr, 1);    int i = 0;    for (; i < len; i++) {        LOGD("intarr[%d]=%d", i, intarr[i]);        *(intarr + i) += 10;        //intarr[i] += 10;    }    (*env)->ReleaseIntArrayElements(env, arr, intarr, len);    return arr;}JNIEXPORT jint JNICALL Java_com_example_ndkpassdata_DataProvider_sub(        JNIEnv *env, jclass clazz, jint x, jint y) {    LOGD("x=%d", x);    LOGD("Y=%d", y);    return x - y;}

4、使用cgywin工具进行ndk-build编译
成功之后
5、编写Activity文件

package cn.itcast.lame;import java.io.File;import android.app.Activity;import android.app.ProgressDialog;import android.os.Bundle;import android.view.View;import android.widget.EditText;import android.widget.Toast;public class LameActivity 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    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        et_wav =  (EditText) this.findViewById(R.id.editText1);        et_mp3 = (EditText) this.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("文件大小 "+ size);        if("".equals(mp3name)||"".equals(wavname)){            Toast.makeText(this, "路径不能为空", 1).show();            return;        }        //convertmp3(wavname,mp3name);        pd.setMessage("转换中....");        pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);        pd.setMax(size); // 设置进度条的最大值        //pd.setCancelable(false);        pd.show();        new Thread(){            @Override            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, 0).show();    }}

6、运行程序

源码地址:
http://download.csdn.net/detail/kai46385076/8999373

版权声明:本文为博主原创文章,未经博主允许不得转载。

  相关解决方案