Android使用LAME将pcm文件转mp3文件
Android使用LAME将pcm格式转mp3格式
lame介绍:LAME是一款开源的MP3编码器,被认为是中高比特率和VBR的最佳MP3编码器,质量和速度方面的改进仍在继续,可能使LAME成为仍在积极开发的唯一MP3编码器。使用lame进行mp3编码,需要了解一些NDK相关的知识,比如jni和cmake。
准备工作:
- 下载lame源码:https://lame.sourceforge.io/ 直接下载最新版本,本文使用的是3.100版本
- android studio新建一个c++ support项目
集成lame源码
在cpp目录下,新建一个文件夹lamemp3,将下载的的源码文件中的\lame-3.100\libmp3lame文件夹下的所有.c和.h文件拷贝到lamemp3下并将\lame-3.100\include下的lame.h也拷贝进去,到这里,lame的源码都已经拷贝完成了,接下来,需要修改部分源码内容以及gradle配置参数。
1)删除fft.c文件的47行的”include “vector/lame_intrin.h”“
2)修改set_get.h文件的24行的#include“lame.h”
3)将util.h文件的574行的”extern ieee754_float32_t fast_log2(ieee754_float32_t x);”
替换为 “extern float fast_log2(float x);”
需要修改app 下的build.gradle文件
android {
...defaultConfig {...externalNativeBuild{cmake{cFlags "-DSTDC_HEADERS"}}}
}
接下来,我们编辑cmake,编辑好以后,点击android studio的build下的refresh linked c++ project,关于cmake部分,看cmake文件注释部分,cmake编写方式不局限一种,取决于你对cmake相关方法的了解
# Sets the minimum version of CMake required to build the native library.
#设置构建本地库所需的最低cmake版本
cmake_minimum_required(VERSION 3.4.1)
#设置库文件导出目录
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lameLibs/${ANDROID_ABI})
#批量导入c文件和cpp文件
file(GLOB lame lamemp3/*.c)
file(GLOB lame2 lamemp3/*.cpp)
#批量导入头文件
include_directories(${CMAKE_CURRENT_LIST_DIR}/lamemp3)
# 创建和给一个库命名,可以设置为静态库
# 或动态库,并且提供它源码的相关路径
# 你可以定义多个库,然后cmake为你构建他们
# gradle会自动打包共享库到你的apk中
add_library( # Sets the name of the library.native-lib# Sets the library as a shared library.SHARED# 导入所有源文件native-lib.cpp${lame}${lame2})#所有指定的预构建库,并将路径定义为变量,用于后面引入
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)#指令cmake需要链接到的库
target_link_libraries(#指定目标librarynative-lib#链接目标库到log库${log-lib})
编写MP3转换的c++实现,
在cpp/lamemp3文件夹下载新建pcm2pm3.cpp和pcm2pm3.h文件,这里贴出实现部分,完成代码参考项目源码
//初始化lame
int pcm2mp3::init(const char *pcm_path, const char *mp3_path, int sample_rate, int channel,int bitRate) {int result=-1;pcm_file=fopen(pcm_path,"rb");if(pcm_file!= NULL){mp3_file=fopen(mp3_path,"wb");if (mp3_file!= NULL){//开始初始化lame_client=lame_init();lame_set_in_samplerate(lame_client,sample_rate);lame_set_out_samplerate(lame_client,sample_rate);lame_set_num_channels(lame_client,channel);lame_set_brate(lame_client,bitRate);lame_set_quality(lame_client,2);lame_init_params(lame_client);result=0;}}return result;
}
//pcm文件转mp3文件
void pcm2mp3::pcm_to_mp3() {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, pcm_file)) > 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(lame_client, (short int *) leftBuffer, (short int *) rightBuffer, (int)(readBufferSize / 2), mp3_buffer, bufferSize);fwrite(mp3_buffer, 1, wroteSize, mp3_file);}delete [] buffer;delete [] leftBuffer;delete [] rightBuffer;delete [] mp3_buffer;}
接下来就是编写jni调用c++方法,定义了三个native方法,一个获取版本号用于测试lame加载是否成功,pcmTomp3进行文件转换,destroy进行相关对象的释放
public class LameJni {static {System.loadLibrary("native-lib");}public native String getVersion();//初始化lamepublic native int pcmTomp3(String pcmPath,String mp3Path,int sampleRate, int channel, int bitRate);public native void destroy();}
然后是对native方法的实现,这里只贴出转换的实现,关于jni的命名规则以及类型转换规则,这里不多赘述,查看jni相关资料即可
pcm2mp3 *mp3_encoder;
extern "C"
JNIEXPORT int JNICALL
Java_com_david_sampling_util_LameJni_pcmTomp3(JNIEnv *env, jclass clazz, jstring pcm_path,jstring mp3_path, jint sample_rate, jint channel,jint bit_rate) {int result=-1;const char *pcm_path_=env->GetStringUTFChars(pcm_path,0);const char *mp3_path_=env->GetStringUTFChars(mp3_path,0);mp3_encoder=new pcm2mp3();mp3_encoder->init(pcm_path_,mp3_path_,sample_rate,channel,bit_rate);mp3_encoder->pcm_to_mp3();env->ReleaseStringUTFChars(pcm_path,pcm_path_);env->ReleaseStringUTFChars(mp3_path,mp3_path_);return result;
}
然后java层通过jni调用即可实现mp3文件的编码
//注:本例经过尝试,发现如果采样率不缩小,那么声音会变快,原因还未找到
lameJni.pcmTomp3(pcmFile.getAbsolutePath(),mp3File.getAbsolutePath(),mSampleRate/2,mChannel==AudioFormat.CHANNEL_IN_MONO?1:2,128);
以上,即可将pcm转换为mp3,关于pcm的获取,可以参考上一篇:https://blog.csdn.net/s591628545/article/details/104525958
项目地址:https://github.com/kingdavidsun/AudioSampling.git
Android使用LAME将pcm文件转mp3文件相关推荐
- Android使用lame将PCM文件转码为MP3文件
Android使用lame将PCM文件转码为MP3文件 1. 软件版本 Android Studio版本:4.2 lame版本:3.100 编译参考:centos7使用ndk编译lame 2. 项目配 ...
- android 录音的格式转换,Android仿微信录音功能(录音后的raw文件转mp3文件)
现在很多时候需要用到录音,然后如果我们的App是ios和android两端的话,就要考虑录音的文件在两端都能使用,这个时候就需要适配,两端的录音文件都要是mp3文件,这样才能保证两边都能播放. 针对这 ...
- 语音amr文件转换为mp3文件
1.安卓前端生成amr语音文件,经过base64加密变成加密字符串 2.把加密后的字符串解密成amr文件 生成amr文件目录 String fileUrl = System.getProperty ...
- Java使用ffmpeg合并多个视频文件、mp3文件
/*** 合并多个视频文件.mp3文件*/@Testpublic void mergeFile(){// 合并命令String commit = "$0 -f concat -safe 0 ...
- 如何将微信amr文件转换为mp3文件
本篇经验将介绍,如何将微信的amr文件转换为mp3文件. 工具/原料 电脑 电脑软件:silk2mp3 amr文件 方法/步骤 下载软件,解压. 进入以下目录,打开软件. silk-v3-decode ...
- 医用设备心跳心率检测mp3文件输出(mp3文件处理)(二)
本系统是通过一套国外先进的医用设备将用户心跳心率存储到 mp3文件中, 该软件系统由于日本以非常高的价格出售, 公司决定由我破译硬件数据,开发一套替换日本软件产品. 该项目共花费2个月时间完成. ...
- android 视频转音频,将mp4文件转换为mp3文件的方法
很多文章关于将MP4转为MP3写的都很复杂,我这里总结一个比较简单的方法.此方法有个BUG,最后再说.但整体功能比较简单可用. 一,导入第三方文件 此方法用到3个第三方库文件如下,(资源和Demo在文 ...
- c# m4a文件转mp3文件 【.net】
我的需求是手机上传录音.客户因手机上传的文件是m4a录音文件,按需求方要求,只要是m4a文件统一转成mp3格式上传,并且保留m4a格式文件.这两种方法跟自己业务有关,希望能帮到相同业务需求的朋友 第一 ...
- C++播放音频mav文件和mp3文件
更多语音提示资料,阅读:为自己的软件添加语音提示功能 实现了一个类,该类提供播放音频文件功能 获得音频文件路径: void PlayAudio::GetDataPath(string path, st ...
最新文章
- 解决SVN提示https证书验证失败问题svn: E230001: Server SSL certificate verification failed: certificate issued
- Qt Creator使用ClearCase
- PC SERVER 序列号查询
- 通过getSystemServices获取手机管理大全
- Le-net网络总结
- android开发仿原生联系人,android 仿IOS联系人列表
- html/js/css资源
- 20个开发人员非常有用的Java功能代码(二)
- Asp.net2.0页面的生命周期
- activate激活虚拟环境无效解决办法
- 人眼分辨 PPI_1080P=2K,分辨率≠清晰度?关于显示器大多数人都错了
- python os.path.splitext()的用法_Python中的os.path路径模块中的操作方法总结
- 安卓rom制作教程_Android ROM制作教程-开发必需
- 稳压二极管型号对照表
- MySQL学习笔记第8课(共10课)
- 单片机数字时钟/闹钟
- 霍夫斯特拉大学计算机科学专业排名,院校排名
- 量化择业 银行vs券商vs公募vs私募?(行内人深度分享)
- 41.clip-path 滚动特效
- 使用JDK中的安全包对数据进行加解密