安卓原生聊天面板开发(五)自定义音频录制压缩组件

请添加图片描述

背景

产品喝大了,说开发一个聊天界面,功能参照微信即可。
这是应了那句话:新人一开口,便知有没有~~真是风趣幽默。

问题分析

其实仔细看微信的聊天面板,功能拆分出来,主要有以下几点:
(1)emoji表情,自定义表情等等。这里可以归类为“表情”tab。
(2)语音交互,音频录制播放压缩。
(3)媒体交互,选择图片,视频,文件等等。
核心就是上面的内容,锦上添花的功能就不再叙述了。

实现效果

在这里插入图片描述

开发环境

win10
jdk8+
as2024+

本文内容

本文将会讲解安卓原生进行音频录制,并且压缩生成mp3的核心流程。

音频录制

对于音频录制,安卓原生应该是支持两种方式,一种是MediaRecorder,一种是AudioRecord。第一种就不再提及了,封装度比较高,网上很多教程。
本文主要讲解的是第二种,AudioRecord录制音频,生成pcm文件,通过lamb音频压缩把文件转换为mp3。

(1)初始化录制参数

在这里插入图片描述
双声道,44100赫兹频录,麦克风,这些都是常规参数,正常初始化AudioRecorder对象即可。

接着调用AudioRecorder对象 startRecording方法,指定开始录音。通过read方法,读取录制内容,然后通过流的方式,写出到文件,核心代码如下:

 int bufferReadResult = audioRecorder.read(buffer, 0, mBufferSizeInBytes);
 if (bufferReadResult == -1) {
           bufferReadResult = 0;
 }
 mDataOutputStream.write(buffer, 0, bufferReadResult);

上述思路,就完成了音频的录制了,得到的一个产物就是xxxx.pcm。然后我们要对这个pcm进行压缩,这里选用的是Lamb进行音频压缩。

C核心代码如下:


/**
 * 音频文件转换为mp3
 * bit -- 44100
 * channel -- 2
 * */
extern "C"
JNIEXPORT void JNICALL
Java_com_north_light_liblame_LameUtils_convertToMp3(JNIEnv *env, jobject obj, jstring orgFile,
                                                    jstring jmp3,jint bit ,jint channel) {
    char *corgFile = Jstring2CStr(env, orgFile);
    char *cmp3 = Jstring2CStr(env, jmp3);
    LOGI("org = %s", corgFile);
    LOGI("mp3 = %s", cmp3);
    //1.打开文件
    FILE *forgFile = fopen(corgFile, "rb");
    FILE *forgFileCount = fopen(corgFile, "rb");
    FILE *fmp3 = fopen(cmp3, "wb");
    short int wav_buffer[8192 * 2];
    unsigned char mp3_buffer[8192];
    //1.初始化lame的编码器
    lame_t lame = lame_init();
    //2. 设置lame mp3编码的采样率
    lame_set_in_samplerate(lame, bit);
    lame_set_num_channels(lame, channel);
    // 3. 设置MP3的编码方式
    lame_set_VBR(lame, vbr_default);
    lame_init_params(lame);
    LOGI("lame init finish");
    long read;
    long write; //代表读了多少个次 和写了多少次
    long total = 0; // 当前读的wav文件的byte数目
    do {
        read = fread(wav_buffer, sizeof(short int) * 2, 8192, forgFile);
        total += read * sizeof(short int) * 2;
        fseek(forgFileCount, 0, SEEK_END);
        long length = ftell(forgFileCount);
        rewind(forgFileCount);
        LOGI("converting ....%d", total);
        publishJavaProgress(env, obj, total, length, jmp3);
        // 调用java代码 完成进度条的更新
        if (read != 0) {
            write = lame_encode_buffer_interleaved(lame, wav_buffer, read, mp3_buffer, 8192);
            //把转化后的mp3数据写到文件里
            fwrite(mp3_buffer, sizeof(unsigned char), write, fmp3);
        }
        if (read == 0) {
            lame_encode_flush(lame, mp3_buffer, 8192);
        }
    } while (read != 0);
    LOGI("convert  finish");
    lame_close(lame);
    fclose(forgFile);
    fclose(forgFileCount);
    fclose(fmp3);
}

其中,部分引用,是用lamb提供的库
官网地址:https://lame.sourceforge.io/download.php
下载集成到项目中即可。至于项目中,ndk如何配置,这里就不一一详述了,我直接贴一下我的cmakelists.txt文件吧。

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.
#指定cmake的最小版本号
cmake_minimum_required(VERSION 3.4.1)
#定义项目名称,可以不定义
#project(demo)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

#设置so库的输出路径
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/libs/${ANDROID_ABI})


#设置编译类型
#add_executable(demo demo.cpp) # 生成可执行文件
#生成动态共享库
add_library( # 设置编译成so库的名称
        lame-lib

        # 生成动态库或共享库,此处如果SHARED改为STATIC,其含义是生成静态库
        SHARED

        # 提供一个需要编译的源文件的相对路径(),native-lib.cpp就是需要编译的源文件
        native-lib-lamb.cpp
        lame/bitstream.c
        lame/encoder.c
        lame/fft.c
        lame/gain_analysis.c
        lame/id3tag.c
        lame/lame.c
        lame/mpglib_interface.c
        lame/newmdct.c
        lame/presets.c
        lame/psymodel.c
        lame/quantize.c
        lame/quantize_pvt.c
        lame/reservoir.c
        lame/set_get.c
        lame/tables.c
        lame/takehiro.c
        lame/util.c
        lame/vbrquantize.c
        lame/VbrTag.c
        lame/version.c
        )

#明确指定编译时需要编译哪些源文件
#add_library(demo demo.cpp test.cpp util.cpp)

#aux_source_directory(dir VAR) 发现一个目录下所有的源代码文件并将列表存储在一个变量中。
#例如:aux_source_directory(. SRC_LIST) # 搜索当前目录下的所有.cpp文件
#add_library(demo ${SRC_LIST})


# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
#查找到指定的预编译库,并将它的路径存储在变量中
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)

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

#设置target需要链接的库
target_link_libraries( # Specifies the target library.目标库
        lame-lib

        # Links the target library to the log library 目标库需要链接的库,log-lib是上面find_library指定的变量名
        # included in the NDK.
        ${log-lib})

目录结构如下:
在这里插入图片描述
其中,lame目录,就是存放刚刚从官网下载的c代码。
LameUtils就是jni文件编写给java层使用的。


至此,你已经有了大概的思路,还有下载官方代码库的初步了解,录制音频,压缩音频核心方法的认识,那么,文章这里就结束了,如需源码,文末有下载方式。

注意点

注意录制文件格式保存,文中是pcm,其他格式可能会引起问题。如wav。

源码

源码获取方式,关注回复: 安卓录音插件源码
即可获得:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值