使用Lame库实现wav、pcm转mp3
文章目录
前言
一、Lame库是什么?
二、使用步骤
0.创建native项目
1.下载Lame库
2.pcm转MP3
3.wav转MP3
4、native方法如下
三、注意
总结
前言
因为使用android录音后生成的文件是wav或者pcm格式,项目要求最后的文件需要是mp3格式,于是就使用到了lame库。
一、Lame库是什么?
LAME 是最好的MP3编码器,编码高品质MP3的最好也是唯一的选择。
Demo放在了文章末尾,demo是一个lib库,直接引入就可以使用的。
本demo实例使用的是CMakeLists的方式编译的c库。
二、使用步骤
0.创建native项目
新建一个native项目或者native的module,创建成功后就会自动生成cpp文件夹和一个native.cpp、CMakeLists
1.下载Lame库
Lame官网https://sourceforge.net/projects/lame/files/lame/
下载完把libmp3lame 文件夹下的所有.c和.h文件还有include文件夹下的lame.h考入到新建工程的cpp文件下
demo使用的是3.99这个版本,如果你的网很慢可以使用在后面的 demo里面的lame库。
2.pcm转MP3
cpp代码如下(示例):
/************************************************************************* PCM 转 MP3 ************************************************************************/Mp3Encoder *encoder;
extern "C" JNIEXPORT jint JNICALL
Java_com_meng_nativelib_NativeLib_pcmToMp3JNI(JNIEnv *env,jobject,jstring pcm_path,jstring mp3_path,jint sample_rate,jint channel,jint bit_rate) {const char *pcmPath = env->GetStringUTFChars(pcm_path, NULL);const char *mp3Path = env->GetStringUTFChars(mp3_path, NULL);encoder = new Mp3Encoder();int initStatus = encoder->Init(pcmPath, mp3Path, sample_rate, channel, bit_rate);if (initStatus != 0) {return -1;}encoder->Encode();env->ReleaseStringUTFChars(pcm_path, pcmPath);env->ReleaseStringUTFChars(mp3_path, mp3Path);return 0;
}extern "C" JNIEXPORT void JNICALL
Java_com_meng_nativelib_NativeLib_pcmToMp3JNIDestroy(JNIEnv *env,jobject) {encoder->Destroy();
}
3.wav转MP3
int flag = 0;
/*** wav转换mp3*/extern "C"
JNIEXPORT void JNICALL Java_com_meng_nativelib_NativeLib_wavToMp3(JNIEnv *env, jobject obj, jstring jwav, jstring jmp3, jint inSamplerate, jint inChannel,jint outBitrate) {char *cwav = Jstring2CStr(env, jwav);char *cmp3 = Jstring2CStr(env, jmp3);//1.打开 wav,MP3文件FILE *fwav = fopen(cwav, "rb");fseek(fwav, 4 * 1024, SEEK_CUR);FILE *fmp3 = fopen(cmp3, "wb+");int channel = inChannel;//单声道short int wav_buffer[8192 * channel];unsigned char mp3_buffer[8192];//1.初始化lame的编码器lame_t lameConvert = lame_init();//2. 设置lame mp3编码的采样率lame_set_in_samplerate(lameConvert, inSamplerate);lame_set_out_samplerate(lameConvert, inSamplerate);lame_set_num_channels(lameConvert, channel);lame_set_mode(lameConvert, MONO);// 3. 设置MP3的编码方式lame_set_VBR(lameConvert, vbr_default);lame_init_params(lameConvert);int read;int write; //代表读了多少个次 和写了多少次int total = 0; // 当前读的wav文件的byte数目do {if (flag == 404) {return;}read = fread(wav_buffer, sizeof(short int) * channel, 8192, fwav);total += read * sizeof(short int) * channel;if (read != 0) {write = lame_encode_buffer(lameConvert, wav_buffer, NULL, read, mp3_buffer, 8192);//write = lame_encode_buffer_interleaved(lame,wav_buffer,read,mp3_buffer,8192);} else {write = lame_encode_flush(lameConvert, mp3_buffer, 8192);}//把转化后的mp3数据写到文件里fwrite(mp3_buffer, 1, write, fmp3);} while (read != 0);lame_mp3_tags_fid(lameConvert, fmp3);lame_close(lameConvert);fclose(fwav);fclose(fmp3);
}
4、native方法如下
package com.meng.nativelibobject NativeLib {// Used to load the 'lame_lib' library on application startup.init {System.loadLibrary("lame_lib")}external fun getVersion(): String?/*** wav 转mp3 16000,1,1* @param wavFilePath 源文件路径* @param mp3FilePath 生成mp3目标文件路径* @param sampleRate Lame采样率 最好写 16000 Lame采样率* MPEG1 MPEG2 MPEG2.5* 44100 22050 11025* 8000 24000 12000* 32000 16000 8000*@param channels 1* @param bitRate 实际没有使用*/external fun wavToMp3(wavFilePath: String, mp3FilePath: String, sampleRate: Int, channels: Int, bitRate: Int)external fun pcmToMp3JNI(pcmFilePath: String, mp3FilePath: String, sampleRate: Int, channels: Int, bitRate: Int): Intexternal fun pcmToMp3JNIDestroy()}
三、注意
- 在编写的cpp代码时一定要在方法上面添加 extern "C"(主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示编译器这部分代码按C语言(而不是C++)的方式进行编译。由于C++支持函数重载,因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名;而C语言并不支持函数重载,因此编译C语言代码的函数时不会带上函数的参数类型,一般只包括函数名。)
- 不要忘记把新增的cpp文件添加到CMakeLists的add_library里面
- 新增cpp文件后最好对cpp文件夹make一次(AndroidStudio的顶部Build->Make Moduie)
- 如果编译运行过后报没有找到你编译的so文件,可以去build下面查看是否编译so文件成功
Demo地址https://gitcode.net/weixin_41620505/pcm-and-wav-to-mp3
总结
第一次编译还是有挺多坑的,比如上面需要注意的那几点。
相关文章:
使用Lame库实现wav、pcm转mp3
文章目录 前言 一、Lame库是什么? 二、使用步骤 0.创建native项目 1.下载Lame库 2.pcm转MP3 3.wav转MP3 4、native方法如下 三、注意 总结 前言 因为使用android录音后生成的文件是wav或者pcm格式,项目要求最后的文件需要是mp3格式,于…...
c++11 标准模板(STL)(std::multimap)(三)
定义于头文件 <map> template< class Key, class T, class Compare std::less<Key>, class Allocator std::allocator<std::pair<const Key, T> > > class multimap;(1)namespace pmr { template <class Key, class T…...
【报复性赚钱】2023年5大风口行业
今天就来和大家分享一下,在时代的洪流下,普通人如何顺应大势抓住机遇! 实现人在风口上,猪都会飞起来。 根据对市场的观察及各平台数据分析结果,结合国家政策和经济专家的分析,小编预测了2023年将会迎来大…...
单目相机、双目相机和RGB-D相机学习笔记(一些视频和博文网址)
目录1. 单目相机1.1 摄像头原理1.2 单目相机的标定2 双目相机2.1 双目相机定位原理2.2 双目相机的缺陷3 RGB-D相机3.1 深度相机结构光原理3.2 RGB-D相机的应用1. 单目相机 1.1 摄像头原理 视频网址:【全网最详细】摄像头原理分析(约25分钟课程…...
word和wps添加mathtype选项卡
word或wps添加mathtype选项卡 前提 安装好word或wps安装好mathtype 步骤 确认word或wps具体安装位置确认word或wps位数为32位还是64位复制mathtype中的MathPage.wll文件和MathType Commands 2016.dotm文件到STARTUP位置添加受信任位置添加加载项 安装位置 通过开始页面&a…...
获取成员userID
文章目录一、简介二、获取token1、获取秘钥2、获取Token三、获取部门数据1、获取部门列表2、获取子部门ID列表3、获取单个部门详情四、获取成员信息1、读取成员2、获取部门成员3、获取部门成员详情一、简介 同步数据到企微: 企业如果需要从自有的系统同步通讯录到…...
DOM编程-显示网页时钟
<!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>显示网页时钟</title> </head> <body bgcolor"antiquewhite"> <script type"text/javascrip…...
浅谈保护数据的加密策略
加密是一种将信息从可读格式转换为混乱字符串的技术。这样做可以防止数据传输中的机密数据泄露。文档、文件、消息和所有其他形式的网络通信都可以加密。加密策略和身份验证服务的结合,还能保障企业机密信息只对授权用户开启访问权限。常见的数据加密包括以下两种&a…...
Java中String,StringBuffer和StringBuilder
String类 我们在定义string变量时 常常写 String str "hello word"; 这样的代码,看起来和int a 0; 是一样的声明方式, 但其实两者是不同的, int 是java中定义的基本数据类型, 而String是一个类,是一个特殊的类,可以像基本数据类型一样直接赋…...
华为认证常见技术问答整理:什么是Datacom认证?
一、关于Datacom认证Q:什么是Datacom认证?A:Datacom,即DatacomCommunication的缩写,中文为“数据通信”,属于ICT技术架构认证类别(华为认证包含ICT技术架构认证、平台与服务认证和行业ICT认证三…...
Read book Netty in action (Chapter II) (Netty Introduction)
前言 支持15W的并发客户端,我们应该视为理所当然的事情,很多公司甚至能够支撑更多,例如我们熟知的 BAT,当几年前双十一的夜晚,并发量是不可估计的。还有春节的时候购票的时候的并发。作为一个优秀的开发人员ÿ…...
python--route
routes是用python重新实现的Rails routes系统,用于将url映射到应用程序的actions ,并反过来生成url 它也是在openstack实现restful通信的方式,它被用来做将 URL 映射为 App 的 action,以及为 App的action 产生 URL 两个重要的方法…...
java面试中被问到项目中的难点,怎么回答
java面试中被问到项目中的难点,怎么回答回答步骤举例说明回答步骤 回答这个问题的方法取决于你的项目的类型和难度。 但是,一般来说,你可以遵循以下步骤来回答这个问题: 描述你的项目:首先简要描述你的项目的类型和目…...
【速通版】吴恩达机器学习笔记Part1
准备速通一下吴恩达的机器学习 很快做个笔记5.2.3 监督学习 part 2_哔哩哔哩_bilibili 目录 1.概述(P1-P3) 2.supervised learning:(P4,P5) regression: classification 3.unsupervised learning (P6- 1.聚类算…...
面试(九)小米C++开发一面 21.11.02
1、局部变量与全局变量的区别?可以同名嘛? 首先是作用域: 局部变量只在变量声明的代码块范围内生效 全局变量在其声明后的所有位置都能访问到 在局部变量与全局变量同名的情况下,全局变量会被屏蔽掉,只会使用局部变量的内容 2、extern 当在a.c中想要使用b.c中的函数fu…...
儿童书写台灯哪个牌子比较好?2023儿童护眼台灯分享
现在儿童的近视率高达52.7%,有科技水平的提高和电子产品的普及,近视率逐年攀升,出现低龄化现象,调查结果显示,其中6岁儿童达到14.3%,小学生为35.6%。初中生71.1%,高中生高达80.5%,可…...
市场调研计划书如何写?
想要做好一个产品,市场调研是必不可少的一步,也是第一步,那么如何进行市场调研呢?以下是我整理的一份市场调研计划书,希望能够帮助到大家!!! 一、文档版本控制 主要记录文档的版本…...
python网络爬虫—快速入门(理论+实战)(七)
系列文章目录 (1)python网络爬虫—快速入门(理论实战)(一) (2)python网络爬虫—快速入门(理论实战)(二) (3) p…...
机器学习笔记——Chapter 1 – The Machine Learning landscape
ML学习笔记 Chapter 1 – The Machine Learning landscape 1.如何定义机器学习? Answer:机器学习是一门通过编程让计算机从数据中进行学习的科学(和艺术)。 2.机器学习在哪些问题上表现突出,你能给出四种类型吗&am…...
skimage.feature--corner_harris、hog、local_binary_pattern说明
skimage.feature说明–corner_harris、hog、local_binary_pattern 文章目录skimage.feature说明--corner_harris、hog、local_binary_pattern1. 前言2. corner_harris2.1 介绍2.2 参数及返回3. hog3.1 介绍3.2 参数及返回4. local_binary_pattern4.1 介绍4.2 参数及返回5. 总结…...
致敬白衣天使,学习Python读取
名字:阿玥的小东东 学习:Python、c 主页:阿玥的小东东 故事设定:现在学校要求对所有同学进行核酸采集,每位同学先在宿舍内等候防护人员(以下简称“大白”)叫号,叫到自己时去停车场排…...
JVM - 认识JVM规范
目录 重识JVM JVM规范作用及其核心 JVM 整体组成 理解ClassFile结构 ASM开发 重识JVM JVM概述JVM: Java Virtual Machine,也就是Java虚拟机所谓虚拟机是指: 通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的计算机系统…...
文献阅读笔记 # CodeBERT: A Pre-Trained Model for Programming and Natural Languages
《CodeBERT: A Pre-Trained Model for Programming and Natural Languages》EMNLP 2020 (CCF-B)作者主要是来自哈工大、中山大学的 MSRA 实习生和 MSRA、哈工大的研究员。资源:code | pdf相关资源:RoBERTa-base | CodeNN词汇: bimodal: 双模态…...
openHarmony的UI开发
自适应布局 拉伸能力 Blank在容器主轴方向上,空白填充组件具有自动填充容器空余部分的能力。仅当父组件为Row/Column时生效,即是线性布局。这样便可以在两个固定宽度或高度的组件中间添加一个Blank(),将剩余空间占满,从而实现…...
【JavaSE】深入HashMap
文章目录1. HashMap概述2. 哈希冲突3. 树化与退化3.1 树化的意义3.2 树的退化4. 二次哈希5. put方法源码分析6. key的设计7. 并发问题参考 如何防止因哈希碰撞引起的DoS攻击_hashmap dos攻击_双子孤狼的博客-CSDN博客 为什么 HashMap 要用 h^(h >>&#…...
华为机试题:HJ62 查找输入整数二进制中1的个数(python)
文章目录博主精品专栏导航知识点详解1、input():获取控制台(任意形式)的输入。输出均为字符串类型。1.1、input() 与 list(input()) 的区别、及其相互转换方法2、print() :打印输出。1、整型int() :将指定进制…...
代码随想录训练营一刷总结|
分为几个大部分: 数组 最先接触的部分,虽然说感觉是最简单的,但是需要掌握好基础,特别是小心循环。这里面需要再仔细看的就是螺旋矩阵那一块,其他的在后续刷的时候能用一种方法一次a就行。 链表 需要注意链表的基础…...
CSS中的几种尺寸单位
一、尺寸单位 CSS 支持多种尺寸单位,包括: px:像素,固定大小单位em:相对于当前元素字体大小的单位rem:相对于根元素(HTML)字体大小的单位%:相对于父元素的百分比单位vh…...
运维必会:ansible剧本(piaybook)
playbooks 概述以及实例操作 Playbooks 组成部分: Inventory Modules Ad Hoc Commands Playbooks Tasks: 任务,即调用模块完成的某些操作 Variables: 变量 Templates: 模板 Handlers: 处理器,由某时间触发执行的操作 Roles: 角色 YAML 介绍…...
活动星投票午间修身自习室制作在线投票投票制作网页
“午间修身自习室”网络评选投票_免费小程序投票推广_小程序投票平台好处手机互联网给所有人都带来不同程度的便利,而微信已经成为国民的系统级别的应用。现在很多人都会在微信群或朋友圈里转发投票,对于运营及推广来说找一个合适的投票小程序能够提高工…...
惠州网站制作公司/关键词排名查询api
bgwriter.c 的代码中有如下部分: pqsignal(SIGQUIT, bg_quickdie); /* hard crash time */ [作者:技术者高健博客园 mail: luckyjackgaogmail.com ] 还有: /** bg_quickdie() occurs when signalled SIGQUIT by the postmaster.** So…...
有哪些网站主页做的比较好看/培训机构专业
今天结合流程图和代码来对Android事件分发机制做一个总结,我自己起一个叫法就是“3个3”。 跟事件分发相关的主要有三个节点方法: 1.dispatchTouchEvent2.onInterceptTouchEvent(这个只有ViewGroup有)3.onTouchEvent为了简单扼要,Demo总共就三…...
常用的oa系统办公软件/如何进行搜索引擎优化
正确理解单周期处理器的“数据通路” 这种是属于不懂会一脸懵逼,但理解了就会清晰畅快的知识点。 记录一下自己的理解: 建立数据通路的目的是为了让指令更好的执行,最基本的五个步骤:取指、译码、执行、访存、回写。与之相应的&am…...
汽车网站大全汽车网/seo推广优化
BGP进程 输入输出进程(BGP I/O):它为TCP和BGP之间提供了一个接口。(1)它从TCP套接字(socket)中读取消息,并把它们放到BGP输入队列,以便被BGP Router进程操作;(2)积聚在输出中的消息也…...
java做网站书/seo建站教程
代码地址: https://gitee.com/DanShenGuiZu/learnDemo/tree/master/springboot_admin_learn 一、介绍 默认情况下,日志文件无法通过执行器端点访问,因此在Spring Boot Admin中不可见。为了启用日志文件执行器端点,可以这样做 或者 设置logg…...
康乐县网站建设/简单网页设计模板html
戳蓝字"前端优选"关注我们哦!来源:CSDN 本文链接:https://blog.csdn.net/WangYangsea/article/details/95237722现在网络上,有非常多的JS在线编译器,非常好用,特备是在调试某些片段代码的时候&am…...