赞
踩
之前项目中遇到过手机录音问题,Android端录制的格式为amr,但是却没法在iOS端播放,于是找到了通过lame库进行格式转换的方法,我们通过AudioRecord录制出原生的pcm格式音频,然后通过lame库进行格式转换,这里需要用到NDK,所以我们需要配置NDK开发环境。主要就是以下,具体不细说了。
接下来在原来的项目中build.gradle中添加如下代码
android {
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
}
}
}
然后在main文件夹下创建cpp/CMakeLists.txt文件
# Sets the minimum version of CMake required to build the native library. # 这里的3.4.1是我这里的cmake版本 这个可以直接创建一个ndk项目进行查看 cmake_minimum_required(VERSION 3.4.1) add_library( # Sets the name of the library. lame # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). lame.cpp ) find_library( # Sets the name of the path variable. log-lib # Specifies the name of the NDK library that # you want CMake to locate. log) target_link_libraries( # Specifies the target library. lame # Links the target library to the log library # included in the NDK. ${log-lib})
然后在cpp文件夹下创建一个lame.cpp ,添加如下代码测试
#include <jni.h>
#include <string>
extern "C"
JNIEXPORT jstring JNICALL
Java_com_we_convertdemo_Convert_stringFromJNI(JNIEnv *env, jobject) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
接着在我们的Java项目中创建一个Convert类添加如下代码:
public class Convert {
static {
System.loadLibrary("lame");
}
public native String stringFromJNI();
}
然后在activity当中调用测试一下通过即可。
lame包下载地址https://sourceforge.net/projects/lame/files/lame/
接下来解压该文件后找到libmp3lame文件夹,将该文件夹下面的.c和.h文件复制到项目的cpp文件夹下(该文件夹里面的文件夹不用管),接着把include目录下的lame.h文件也放到cpp目录当中。然后把所有的.c文件添加到CMakeList.txt文件的add_library中。同时对当中的部分文件做修改
1.在 fft.c 文件中删除 #include “vector/lame_intrin.h”
2.在set_get.h 文件中修改 #include <lame.h>为 #include“lame.h”
3.在 util.h 文件中将”extern ieee754_float32_t fast_log2(ieee754_float32_t x);”修改为 “extern float fast_log2(float x);”
修改完上诉文件后,我们编译一下会报错,接下来需要添加如下配置
cmake {
cFlags "-DSTDC_HEADERS"
cppFlags "-fexceptions", "-frtti"
}
接下来我们在Convert类中添加如下三个方法:
public native int init(String pcmPath,int audioChannels,int bitRate,int sampleRate,String mp3Path);
public native void encode();
public native void destroy();
然后实现创建两个编码类Mp3Encoder.h和Mp3Encoder.cpp
代码如下
#include <cstdio> #include "lame.h" class Mp3Encoder { private: FILE* pcmFile; FILE* mp3File; lame_t lameClient; public: Mp3Encoder(); ~Mp3Encoder(); int Init(const char* pcmFilePath,int channels,int bitRate,int sampleRate,const char* mp3FilePath); void Encode(); void Destory(); }; --------------------------------------------------------------------------------------- #include "Mp3Encoder.h" Mp3Encoder::Mp3Encoder() {} Mp3Encoder::~Mp3Encoder() {} int Mp3Encoder::Init(const char *pcmFilePath, int channels, int bitRate, int sampleRate, const char *mp3FilePath) { int ret = -1; pcmFile = fopen(pcmFilePath,"rb"); if (pcmFile){ mp3File = fopen(mp3FilePath,"wb"); if (mp3File){ lameClient = lame_init(); lame_set_in_samplerate(lameClient,sampleRate); lame_set_out_samplerate(lameClient,sampleRate); lame_set_num_channels(lameClient,channels); lame_set_brate(lameClient,bitRate/1000); lame_init_params(lameClient); ret = 0; } } return ret; } void Mp3Encoder::Encode() { int buffersize = 1024*256; short* buffer = new short[buffersize/2]; short* leftBuffer = new short[buffersize/4]; short* rightBuffer = new short[buffersize/4]; unsigned char* mp3_buffer = new unsigned char[buffersize]; size_t readBufferSize = 0; while ((readBufferSize=fread(buffer,2,buffersize/2,pcmFile))>0){ for (int i = 0; i < readBufferSize; ++i) { if (i%2==0){ leftBuffer[i/2] = buffer[i]; } else{ rightBuffer[i/2] = buffer[i]; } } size_t wroteSize = lame_encode_buffer(lameClient,leftBuffer,rightBuffer ,readBufferSize/2,mp3_buffer,buffersize); fwrite(mp3_buffer,1,wroteSize,mp3File); } delete[] buffer; delete[] leftBuffer; delete[] rightBuffer; delete[] mp3_buffer; } void Mp3Encoder::Destory() { if(pcmFile){ fclose(pcmFile); } if (mp3File){ fclose(mp3File); lame_close(lameClient); } }
然后把我们把所有的.c文件和.cpp文件添加到CMakeLists.txt的add_library中
add_library( # Sets the name of the library. lame # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). lame.cpp Mp3Encoder.cpp bitstream.c encoder.c fft.c gain_analysis.c id3tag.c lame.c mpglib_interface.c newmdct.c presets.c psymodel.c quantize.c quantize_pvt.c reservoir.c set_get.c tables.c takehiro.c util.c vbrquantize.c VbrTag.c version.c )
具体代码已经上传到github上可以下载查看
https://github.com/honghengqiang/ConvertDemo.git
参考文档:
https://developer.android.com/studio/projects/gradle-external-native-builds
https://developer.android.com/ndk/guides/cpp-support
以及《音视频开发进阶指南》
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。