android lame wav 转 mp3,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主界面布局

首先是建立JNI目录

1、把lameC语言源码导入jni中

2、创建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)

3、编写C语言文件

#include

#include

#include "com_example_ndkpassdata_DataProvider.h"

#include

#include

#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、运行程序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值