前言
文章開(kāi)始之前先給大家分享一個(gè)B站的視頻教程弦叶,感興趣的小伙伴可以去看看席镀。
音視頻開(kāi)發(fā)全系列教程:https://www.bilibili.com/video/BV1fb4y1d7JU?spm_id_from=333.999.0.0
移動(dòng)環(huán)境搭建(以AS為例)
其實(shí)很多網(wǎng)站都已經(jīng)有過(guò)這樣的介紹了硬萍,不過(guò)既然是自己的文章,還是需要講講的塞颁,嘿嘿浪讳。創(chuàng)建一個(gè)新的AS
項(xiàng)目,并且選擇到我們的Native C++
的選項(xiàng)來(lái)創(chuàng)建我們的項(xiàng)目惑芭。當(dāng)然我們里面會(huì)看到一個(gè)C++ standard
坠狡,我直接默認(rèn)選的Toolchain Defalut
。
到了這里其實(shí)我們的程序就可以運(yùn)行了强衡,不信你可以直接跑擦秽,不過(guò)看看代碼码荔,你會(huì)發(fā)現(xiàn)存在一定的不同
為什么我們要是用Native C++
?
這個(gè)問(wèn)題是讀者必須清楚的漩勤,Java
終究并不是一門萬(wàn)能的語(yǔ)言,每門語(yǔ)言都是如此缩搅,有著自己的長(zhǎng)處和局限性越败。不然為什么還需要Binder
機(jī)制去調(diào)用一些底層的服務(wù),因?yàn)楹芏鄸|西硼瓣,上層做不了究飞。
情況可以分為以下幾種:
(1)應(yīng)用程序需要一些平臺(tái)的相關(guān)特性支持,而Java
層并沒(méi)有提供相應(yīng)的API堂鲤,(比如OpenSL ES的使用)亿傅。
(2)調(diào)用已然存在的用C\C++
編寫的函數(shù)庫(kù)。
(3)應(yīng)用程序?qū)σ恍╆P(guān)鍵操作存在一定的處理速度要求瘟栖。
如何去調(diào)用Native
代碼
(1)編寫一個(gè)帶native
方法的函數(shù)葵擎。
public class NativeTest {
public native void encode();
}
就如上面一般創(chuàng)建一個(gè)文件,用native
修飾即可半哟,但是你可能會(huì)看到這個(gè)函數(shù)爆紅酬滤,其實(shí)沒(méi)什么關(guān)系签餐,我們先用小錘子Build
一下,正常情況下是不會(huì)報(bào)錯(cuò)的盯串,因?yàn)橹皇沁@個(gè)native
函數(shù)沒(méi)有找到對(duì)應(yīng)的C\C++
函數(shù)而已氯檐,并不影響我們本身的Java
類。
(2)生成一個(gè)我們需要的C\C++
文件了体捏。
1\. 切換到src/main/java目錄下
2\. 在Terminal中輸入javah -jni 包名.帶native的Java類
// 在我的項(xiàng)目中的語(yǔ)句
javah -jni com.clericyi.player.NativeTest
3\. 得到一個(gè)格式為:(包名_類名).h的頭文件冠摄,并將他移動(dòng)到cpp的目錄下
(3)得到的.h的頭文件并不能夠被使用,自然需要.cpp的文件來(lái)支持使用了译打。(上圖已經(jīng)給出位置)
#include <jni.h>
#include <string.h>
#include "com_clericyi_player_NativeTest.h"
JNIEXPORT jstring JNICALL Java_com_clericyi_player_NativeTest_encode
(JNIEnv *env, jobject) {
return env->NewStringUTF("Encoder encoding");
}
(4)使用
其實(shí)這個(gè)時(shí)候還是用不起來(lái)的耗拓,需要進(jìn)行一定的配置才行,走完下面的流程應(yīng)該就能看到我們的運(yùn)行效果了奏司。
(1) 修改CMakeList.txt中的對(duì)應(yīng)數(shù)據(jù)乔询,添加創(chuàng)建的cpp文件
add_library(
# 。韵洋。竿刁。
audioencoder.cpp)
(2) app -> build.gradle
android {
defaultConfig {
externalNativeBuild {
cmake {
cppFlags "-frtti -fexceptions"
cFlags "-DSTDC_HEADERS"
}
}
ndk {
// 可以加入x86等等,跟應(yīng)用的手機(jī)架構(gòu)相對(duì)應(yīng)
// 寫了幾個(gè)搪缨,到時(shí)候build中就會(huì)生成幾個(gè)
abiFilters "armeabi-v7a"
}
}
}
關(guān)于NDK的安裝
因?yàn)槲覀冊(cè)陂_(kāi)發(fā)過(guò)程中必須要使用到NDK
食拜,而NDK
的版本兼容是一個(gè)很重要的事情。為了能向下兼容一些版本副编,我們選用低一級(jí)的版本即可负甸。(下載路徑:Prefereces -> Android SDK -> SDK Tools)
相信很多人會(huì)在查資料時(shí)發(fā)現(xiàn)別人安裝的都是
NDK
,而我安裝的是NDK(Side by Side)
痹届,但是你在自己的AS上也同樣的找不到我們需要的NDK
呻待。所以給出一個(gè)網(wǎng)址來(lái)給讀者們作為安裝的教程:安裝及配置 NDK 和 CMake
效果圖
交叉編譯的原理及實(shí)踐
什么叫做交叉編譯?
三部分構(gòu)成:
- 來(lái)自于第三方的源碼
- 運(yùn)行設(shè)備為
Android
或者iOS
- 編譯機(jī)器是我們的PC
簡(jiǎn)單來(lái)說(shuō)就是我們本地PC
編譯生成了一份給別人用的東西队腐。
交叉編譯實(shí)踐
以LAME
作為示范例子蚕捉,來(lái)做一個(gè)詳細(xì)的示范。
這里已經(jīng)不再建議用書上的方法了柴淘,我試了一天了迫淹,太難調(diào)通了。這里還是使用Android Studio
現(xiàn)在自動(dòng)生成帶有的解決方案 -- CMake
为严。
- 下載完我們的
LAME
敛熬,把libmp3lame
下的文件和include
下的lame.h
文件全都移動(dòng)到AS
中cpp\lame
的文件夾下。
- 修改
CMakeLists.txt
add_library( # Sets the name of the library.
# 資源庫(kù)的目標(biāo)名
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
# 我們要放入的cpp文件
native-lib.cpp
# lame
lame/bitstream.c lame/encoder.c lame/gain_analysis.c
lame/lame.c lame/id3tag.c lame/mpglib_interface.c
lame/newmdct.c lame/presets.c lame/psymodel.c
lame/quantize.c lame/fft.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)
- 用小錘子
build
一下我們的項(xiàng)目第股,會(huì)報(bào)錯(cuò)应民,我出現(xiàn)的錯(cuò)誤即解決方案下方給出。
錯(cuò)誤1:#include <lame.h>
解決方案:#include "lame.h"
---
錯(cuò)誤2:ieee754_float32_t fast_log2(ieee754_float32_t x);
解決方案:float fast_log2(float x);
- 報(bào)錯(cuò)調(diào)整好以后我們就可以開(kāi)始我們的使用了。
#include <jni.h>
#include <string.h>
#include "com_clericyi_player_NativeTest.h"
JNIEXPORT jstring JNICALL Java_com_clericyi_player_NativeTest_encode
(JNIEnv *env, jobject) {
return env->NewStringUTF(get_lame_version());
}
可以把上文中使用過(guò)的那個(gè)C++
文件的返回值修改成這個(gè)瑞妇,就能夠得到效果了稿静。
基本這就完事兒了,如果想要做更深層次的了解辕狰,你可以看這樣項(xiàng)目結(jié)構(gòu)用于自學(xué)改备,對(duì)應(yīng)的項(xiàng)目中的內(nèi)容是書上的一個(gè)用于將PCM
格式文件轉(zhuǎn)化為MP3
格式的范例。
PCM
的文件可以自己去隨便撈一個(gè)蔓倍,因?yàn)榍蠓奖阄沂怯?code>adb直接推到虛擬機(jī)中的悬钳。
本文轉(zhuǎn)自 https://juejin.cn/post/6844904086744072200,如有侵權(quán)偶翅,請(qǐng)聯(lián)系刪除默勾。