一、编译LAME

编译脚本:

#!/bin/bash
NDK_ROOT=/Users/huozhenpeng/Library/Android/sdk/ndk-bundle
PREBUILT=$NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
PLATFORM=$NDK_ROOT/platforms/android-9/arch-arm
export PATH=$PATH:$PREBUILT/bin:$PLATFORM/usr/include:
export LDFLAGS="-L$PLATFORM/usr/lib -L$PREBUILT/arm-linux-androideabi/lib -march=armv7-a"
export CFLAGS="-I$PLATFORM/usr/include -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -ffast-math -O2"
export CPPFLAGS="$CFLAGS"
export CFLAGS="$CFLAGS"
export CXXFLAGS="$CFLAGS"
export LDFLAGS="$LDFLAGS"
export AS=$PREBUILT/bin/arm-linux-androideabi-as
export LD=$PREBUILT/bin/arm-linux-androideabi-ld
export CXX="$PREBUILT/bin/arm-linux-androideabi-g++ --sysroot=${PLATFORM}"
export CC="$PREBUILT/bin/arm-linux-androideabi-gcc --sysroot=${PLATFORM} -march=armv7-a"
export NM=$PREBUILT/bin/arm-linux-androideabi-nm
export STRIP=$PREBUILT/bin/arm-linux-androideabi-strip
export RANLIB=$PREBUILT/bin/arm-linux-androideabi-ranlib
export AR=$PREBUILT/bin/arm-linux-androideabi-ar
./configure --host=arm-linux \
--disable-shared \
--disable-frontend \
--enable-static \
--prefix=/Users/huozhenpeng/Desktop/voicevideo/lame-3.99.5/armv7a
make clean
make -j8
make install

编译成功后:


image.png

这个armv7a是我新建的目录
我们使用configure的方式来生成makefile文件,然后利用make命令完成编译,make install进行安装


image.png

这个makefile文件就是利用configure生成的,configure中最后的命令

make clean
make -j8
make install

都是对这个文件进行操作的

--prefix:指定将编译好的库放在哪个目录下
--host:指定编译好的库最终要运行的平台
CC:指定交叉工具编译链的路径,其实这里就是指定gcc的路径
--CFLAGS:指定编译时所带的参数
--LDFLAGS:指定链接过程中的参数
--disable-shared:通常是GNU标准中关闭动态链接库的选项
--disable-frontend:不编译出LAME的可执行文件

在AndroidStudio中集成LAME库

目录结构:


image.png

lamemp3encoder.h

//
// Created by 霍振鹏 on 2018/9/10.
//

#ifndef LAMEPROJECT_LAMEMP3ENCODER_H
#define LAMEPROJECT_LAMEMP3ENCODER_H

#include "../../../../../../Library/Android/sdk/ndk-bundle/platforms/android-21/arch-mips64/usr/include/stdio.h"

extern "C"
{
#include 
#include "lame/lame.h"
}


class Mp3Encoder {
private:
    FILE *pcmFile;
    FILE *mp3File;
    lame_t lameClient;
public:
    Mp3Encoder();

    ~Mp3Encoder();

    int Init(const char *pcmFilePath, const char *mp3FilePath, int sampleRate, int channels,
             int bitRate);

    void Encode();

    void Destroy();
};

#endif //LAMEPROJECT_LAMEMP3ENCODER_H

lamemp3encoder.cpp

//
// Created by 霍振鹏 on 2018/9/10.
//

#include "lamemp3encoder.h"




Mp3Encoder::Mp3Encoder() {
}

Mp3Encoder::~Mp3Encoder() {
}

int Mp3Encoder::Init(const char *pcmFilePath, const char *mp3FilePath, int sampleRate, int channels,
         int bitRate){
    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];
    uint8_t* mp3_buffer = new uint8_t[bufferSize];
    int 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];
            }
        }
        int wroteSize = lame_encode_buffer(lameClient, (short int *) leftBuffer, (short int *) rightBuffer, readBufferSize / 2, mp3_buffer, bufferSize);
        fwrite(mp3_buffer, 1, wroteSize, mp3File);
    }
    delete[] buffer;
    delete[] leftBuffer;
    delete[] rightBuffer;
    delete[] mp3_buffer;
}

void Mp3Encoder::Destroy(){
    if(pcmFile) {
        fclose(pcmFile);
    }
    if(mp3File) {
        fclose(mp3File);
        lame_close(lameClient);
    }
}


MainActivity.java

package com.example.huozhenpeng.lametest;

import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View v) {
                String pcmPath = Environment.getExternalStorageDirectory()+"/ffmpeg.pcm";
                int audioChannels = 2;
                int bitRate = 128 * 1024;
                int sampleRate = 44100;
                String mp3Path =Environment.getExternalStorageDirectory()+"/lame.mp3";
                int ret = init(pcmPath, mp3Path,sampleRate,audioChannels, bitRate);
                if(ret >= 0) {
                    encode();
                    destroy();
                } else {
                }

            }
        });
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native int init(String pcmPath,String mp3Path,int sampleRate,int audioChannels,int bitRate);
    public native void encode();
    public native void destroy();
}

native-lib.cpp

#include 
#include 

extern "C"
{
#include "lamemp3encoder.h"
}


Mp3Encoder* encoder=NULL;
extern "C"
JNIEXPORT jint JNICALL
Java_com_example_huozhenpeng_lametest_MainActivity_init(JNIEnv *env, jobject instance,
                                                        jstring pcmPath_, jstring mp3Path_,
                                                        jint sampleRate, jint audioChannels,
                                                        jint bitRate) {
    const char *pcmPath = env->GetStringUTFChars(pcmPath_, 0);
    const char *mp3Path = env->GetStringUTFChars(mp3Path_, 0);

    // TODO
    encoder=new Mp3Encoder();
    int ret=encoder->Init(pcmPath,mp3Path,sampleRate,audioChannels,bitRate);

    env->ReleaseStringUTFChars(pcmPath_, pcmPath);
    env->ReleaseStringUTFChars(mp3Path_, mp3Path);
    //坑点,忘记写return值了,运行报错
    return ret;
}
extern "C"
JNIEXPORT void JNICALL
Java_com_example_huozhenpeng_lametest_MainActivity_encode(JNIEnv *env, jobject instance) {

    // TODO
    encoder->Encode();

}
extern "C"
JNIEXPORT void JNICALL
Java_com_example_huozhenpeng_lametest_MainActivity_destroy(JNIEnv *env, jobject instance) {

    // TODO
    encoder->Destroy();

}

build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.example.huozhenpeng.lametest"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        sourceSets {
            main {
                jniLibs.srcDirs = ['libs']
            }
        }
        externalNativeBuild {
            cmake {
                cppFlags "-frtti -fexceptions"
                abiFilters 'armeabi-v7a'
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
}

CMakeList.txt

cmake_minimum_required(VERSION 3.4.1)

set(distribution_DIR ../../../../libs)

include_directories(libs/include)


add_library( # Sets the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             src/main/cpp/native-lib.cpp
             src/main/cpp/lamemp3encoder.cpp
             )


# 坑点,注意路径正确性
add_library(mp3lame STATIC IMPORTED)
set_target_properties(mp3lame
  PROPERTIES IMPORTED_LOCATION
  ${distribution_DIR}/armeabi-v7a/libmp3lame.a)




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.
                       native-lib
                       # 坑点,不要忘记添加这儿
                       mp3lame

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )
image.png

libs下存放的是上面利用configure编译成的include中的头文件和lib中的静态库(.a)文件
测试:


image.png

你可能感兴趣的:(一、编译LAME)