日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

lame库(iOS 和 Android)

發布時間:2023/12/16 Android 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 lame库(iOS 和 Android) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

用LAME這個開源的MP3編碼庫在iOS平臺和Android平臺上將一個PCM文件編碼為MP3文件,最終將編碼后的MP3文件發送到電腦上即可進行播放

在iOS上如何搭建一個基礎項目

xcode?選擇Single View Application模板,看到Xcode默認是以Story board的形式構建的界面部分,由于我們不希望使用這種形式來構建界面,而是希望使用xib的形式來構建界面,所以要在Main Interface選項中刪除其中的內容。

接下來,再建立一個界面文件作為應用的第一個界面,而在iOS中一個界面就是一個xib文件,iOS程序運行的時候其入口是main.m,但是蘋果公司不希望開發者修改該文件,而是要求開發者去修改應用的入口——AppDelgate.m文件。

開發者僅需要把引用C++的OC類的后綴名改為.mm(OC類的正常后綴名是.m),就可以和C++一塊編譯了。所以開發者僅需要把ViewController的后綴名改為.mm,再包含進Mp3Encoder.h頭文件,

Mp3Encoder* encoder = new Mp3Encoder();

encoder->encode ();
delete encoder;

在Android上如何搭建一個基礎項目

jni 項目

交叉編譯的原理與實踐

無論是自行安裝PC上的編譯器,還是下載其他平臺(Android或者iOS)的交叉工具編譯鏈,它們都會提供以下幾個工具:CC、AS、AR、LD、NM、GDB。那么,這幾個工具到底是做什么用的呢?下面就來逐一解釋一下。
·CC:編譯器,對C源文件進行編譯處理,生成匯編文件。
·AS:將匯編文件生成目標文件(匯編文件使用的是指令助記符,AS將它翻譯成機器碼)。
·AR:打包器,用于庫操作,可以通過該工具從一個庫中刪除或者增加目標代碼模塊。
·LD:鏈接器,為前面生成的目標代碼分配地址空間,將多個目標文件鏈接成一個庫或者是可執行文件。

·GDB:調試工具,可以對運行過程中的程序進行代碼調試工作。
·STRIP:以最終生成的可執行文件或者庫文件作為輸入,然后消除掉其中的源碼。
·NM:查看靜態庫文件中的符號表。
·Objdump:查看靜態庫或者動態庫的方法簽名。
了解了這些之后,當讀者再進行交叉編譯或者使用交叉編譯工具鏈提供的工具時,就不會感到陌生了,接下來將會在iOS平臺和Android平臺分別演示如何交叉編譯出幾個常用的音視頻開源庫。
編譯器對比
正常編譯一個程序的過程如下:
編譯:gcc-c main.cpp./libmad/mad_decoder.cpp-I./libmad/include
打包:ar cr../prebuilt/libmedia.a mad_decoder.o
鏈接:g++-o main main.o-L../prebuilt-l mdedia
在這個過程中,gcc、ar、g++是我們用到的三個編譯工具,在這里沒有用到的ranlib、gdb、nm、strip等都會包含在PC的編譯器中,同樣其他平臺提供的交叉工具編譯鏈中也會包含這些命令行工具,比如Android提供的NDK,其交叉工具編譯鏈中的prebuilt/darwin-x86_64/bin中,就包含了對應的gcc、ar、g++、gdb、strip、nm、ranlib等工具。

iOS平臺交叉編譯的實踐

前面提到的目標平臺雖然都基于ARM平臺,但是隨著時間的推移,平臺也在不斷地演進,就像armv5到armv6、armv7以及到現在的arm64

·armv6:iPhone、iPhone 2、iPhone 3G

armv7:iPhone 4、iPhone 4S
·armv7s:iPhone 5、iPhone 5S
·arm64:iPhone 5S、iPhone 6(P)、iPhone 6S(P)、iPhone 7(P)

? ? ? ? ?機器對指令集的支持是向下兼容的,因此armv7的指令集是可以運行在iPhone 5S中的,只是效率沒那么高而已。借此機會,先來討論一下iOS項目文件中的一項配置,即Build Settings里面的Architectures選項。Architectures指的是該App支持的指令集,一般情況下,在Xcode中新建一個項目,其默認的Architectures選項值是Standard architectures(armv7、arm64),表示該App僅支持armv7和arm64的指令集;Valid architectures選項指即將編譯的指令集,一般設置為armv7、armv7s、arm64,表示一般會編譯這三個指令集;Build Active Architecture Only選項表示是否只編譯當前適用的指令集,一般情況下在Debug的時候設置為YES,以便可以更加快速、高效地調試程序,而在Release的情況下設置為NO,以便App在各個機器上都能夠以最高效率運行,因為Valid architectures選擇的對應指令集是armv7、armv7s和arm64,在Release下會為各個指令集編譯對應的代碼,因此最后的ipa體積基本上翻了3倍。
? ? ? ? ?基于上面的描述,以及設備與指令集平臺的對比,大多數情況下,我們在實際的交叉編譯過程中只編譯armv7與arm64這兩個指令集平臺下的庫,因為armv7s設備的數量比較少,有armv7來保底完全是可以運行的,并且armv7到armv7s指令集的變動又比較少,而arm64的變動則比較大,設備數量也比較多,所以需要單獨編譯出來,以保證這一批設備可以享受到最優質的運行狀況。

LAME的交叉編譯

https://sourceforge.net/projects/lame/files/lame/3.99/

編寫一個build_armv7.sh腳本,用于編譯armv7指令集下的版本,以支持iPhone 5S及以下的設備

./configure \ ——disable-shared \ ——disable-frontend \ ——host=arm-apple-darwin \ ——prefix="./thin/armv7" \ CC="xcrun -sdk iphoneos clang -arch armv7" \ CFLAGS="-arch armv7 -fembed-bitcode -miphoneos-version-min=7.0" \ LDFLAGS="-arch armv7 -fembed-bitcode -miphoneos-version-min=7.0" make clean make -j8 make install

·——prefix:指定將編譯好的庫放到哪個目錄下,這是GNU大部分庫的標準配置。
·——host:指定最終庫要運行的平臺。
·CC:指定交叉工具編譯鏈的路徑,其實這里就是指定gcc的路徑。
·CFLAGS:指定編譯時所帶的參數。Shell腳本中指定-march是armv7平臺,代表編譯的庫運行的目標平臺是armv7平臺;另外Shell腳本中也指定了打開bitcode選項,這使得使用編譯出來的這個庫的工程,可以將enable-bitcode選項設置為YES,如果沒有打開該選項,那么其在Xcode中只能設置為NO,而這對于最終App的運行性能會有一定的影響。Shell腳本中同時也指定了編譯出來的這個庫所支持的最低iOS版本是7.0,如果不配置該參數的話,則默認是iOS 9.0版本,而所使用的編譯出來的這個庫的工程,若所支持的最低iOS版本不是9.0的話,Xcode就會給出警告。
·LDFLAGS:指定鏈接過程中的參數,同樣也要帶上bitcode的選項以及開發者期望App支持的最低iOS版本的選項參數。
·——disable-shared:通常是GNU標準中關閉動態鏈接庫的選項,一般是在編譯出命令行工具的時候,期望命令行工具可以單獨使用而不需要動態鏈接庫的配置。
·——disable-frontend:不編譯出LAME的可執行文件。
bitcode模式是表明當開發者提交應用(App)到App Store上的時候,Xcode會將程序編譯為一個中間表現形式(bitcode)。App Store會將該bitcode中間表現形式的代碼進行編譯優化,鏈接為64位或者32位的程序。如果程序中用到了第三方靜態庫,則必須在編譯第三方靜態庫的時候也開啟bitcode,否則在Xcode的Build Setting中必須要關閉bitcode,這對于App來講可能會造成性能的降低。

建立build_arm64.sh文件

./configure \ ——disable-shared \ ——disable-frontend \ ——host=arm-apple-darwin \ ——prefix="./thin/arm64" \ CC="xcrun -sdk iphoneos clang -arch arm64" \ CFLAGS="-arch arm64 -fembed-bitcode -miphoneos-version-min=7.0" \ LDFLAGS="-arch arm64 -fembed-bitcode -miphoneos-version-min=7.0" make clean make -j8 make install

如果想在模擬器上運行,那么就需要編譯出i386架構下的靜態庫,而編譯i386平臺的Shell腳本也與此類似,僅僅是改變平臺架構。

? ? ? ?待兩個腳本執行完畢之后,就可以去thin-lame目錄下尋找對應的armv7與arm64目錄,并且在這兩個目錄下會看到bin、lib、include、share這四個目錄。由于在配置的時候裁剪掉了可執行文件,所以bin目錄下不會有內容;在lib目錄下則是鏈接過程中需要鏈接的libmp3lame.a靜態庫文件;在include目錄下則是編譯過程所需要引用的頭文件。
? ? ? ?至此已經編譯出了兩個指令集平臺下的靜態庫文件與include文件目錄,其實這兩個include文件的目錄是一樣的,隨便使用哪一份都可以,但是對于靜態庫文件,應該如何用呢?這里就會涉及如何合并靜態庫的知識,合并靜態庫應該使用lipo命令,在終端下切換到thin-lame目錄下鍵入:
lipo -create ./arm64/lib/libmp3lame.a ./armv7/lib/libmp3lame.a -output
libmp3lame.a
? ? ? ? ? ?這行命令會把兩個平臺架構下的靜態庫文件合并到一個libmp3lame.a的靜態庫文件中,現在來驗證一下最終的libmp3lame.a是否包含armv7與arm64這兩個平臺架構的靜態庫,在命令行鍵入:
file libmp3lame.a
如果看到如下信息,則說明編譯成功了:

libmp3lame.a:Mach-O universal binary with 2 architectures:[arm_v7:current ar
archive][arm64:current ar archive]
libmp3lame.a (for architecture armv7): current ar archive
libmp3lame.a (for architecture arm64): current ar archive

? ? ? 如果在開發過程中編譯的第三方庫比較多,而同時編譯的指令集平臺也比較多,則每次都需要新建幾個腳本文件,然后編譯出各個平臺的靜態庫,最終再用lipo命令進行合并,將會非常麻煩。而軟件工程師就是要把重復性的東西做成工具,讓工作變得更加簡單,所以后續在代碼倉庫中會有完整的編譯腳本,可以編譯出所有架構平臺下的靜態庫,并且也已經用 lipo 命令把所有指令集平臺下的靜態庫合并到了一個靜態庫文件中

Android平臺交叉編譯的實踐

Android原生開發包(NDK)可用于Android平臺上的C++開發,NDK不僅僅是一個單一功能的工具,還是一個包含了API、交叉編譯器、鏈接程序、調試器、構建工具等的綜合工具集。
下面大致列舉了一下經常會用到的組件。

  • ·ARM、x86的交叉編譯器
  • ·構建系統
  • ·Java原生接口頭文件
  • ·C庫
  • ·Math庫
  • ·最小的C++庫
  • ·ZLib壓縮庫
  • ·POSIX線程
  • ·Android日志庫
  • ·Android原生應用API
  • ·OpenGL ES(包括EGL)庫
  • ·OpenSL ES庫

下面來看一下Android所提供的NDK根目錄下的結構。

  • ·ndk-build:該Shell腳本是Android NDK構建系統的起始點,一般在項目中僅僅執行這一個命令就可以編譯出對應的動態鏈接庫了,后面會有詳細的介紹。
  • ·ndk-gdb:該Shell腳本允許用GUN調試器調試Native代碼,并且可以配置到Eclipse的IDE中,可以做到像調試Java代碼一樣調試Native的代碼。
  • ·ndk-stack:該Shell腳本可以幫助分析Native代碼崩潰時的堆棧信息,后續會針對Native代碼的崩潰進行詳細的分析。
  • ·build:該目錄包含NDK構建系統的所有模塊。
  • ·platforms:該目錄包含支持不同Android目標版本的頭文件和庫文件,NDK構建系統會根據具體的配置來引用指定平臺下的頭文件和庫文件。
  • ·toolchains:該目錄包含目前NDK所支持的不同平臺下的交叉編譯器——ARM、x86、MIPS,其中比較常用的是ARM和x86。構建系統會根據具體的配置選擇不同的交叉編譯器。

? ? 在了解了NDK的目錄結構之后,接下來詳細了解一下NDK的編譯腳本語法——Android.mk和Application.mk。
Android.mk是在Android平臺上構建一個C或者C++語言編寫的程序系統的Makefile文件,不同的是,Android提供了一系列的內置變量來提供更加方便的構建語法規則。?Application.mk文件實際上是對應用程序本身進行描述的文件,它描述了應用程序要針對哪些CPU架構打包動態so包、要構建的是release包還是debug包以及一些編譯和鏈接參數等。
(1)Android.mk
Android.mk分為以下幾部分。

  • ·LOCAL_PATH:=$(call my-dir),返回當前文件在系統中的路徑,Android.mk文件開始時必須定義該變量。
  • ·include$(CLEAR_VARS),表明清除上一次構建過程的所有全局變量,因為在一個Makefile編譯腳本中,會使用大量的全局變量,使用這行腳本表明需要清除掉所有的全局變量。
  • ·LOCAL_SRC_FILES,要編譯的C或者Cpp的文件,注意這里不需要列舉頭文件,構建系統會自動幫助開發者依賴這些文件。
  • ·LOCAL_STATIC_LIBRARIES,所依賴的靜態庫文件。
  • ·LOCAL_LDLIBS:=-L$(SYSROOT)/usr/lib-llog-lOpenSLES-lGLESv2-lEGL-lz,指定編譯過程所依賴的NDK提供的動態與靜態庫,SYSROOT變量代表的是NDK_ROOT下面的目錄$NDK_ROOT/platforms/android-18/arch-arm,而在這個目錄的usr/lib/目錄下有很多對應的so的動態庫以及.a的靜態庫。
  • ·LOCAL_CFLAGS,編譯C或者Cpp的編譯標志,在實際編譯的時候會發送給編譯器。比如常用的實例是加上-DAUTO_TEST,然后在代碼中就可以利用條件判斷#ifdef AUTO_TEST來做一些與自動化測試相關的事情。
  • ·LOCAL_LDFLAGS,鏈接標志的可選列表,當對目標文件進行鏈接以生成輸出文件的時候,將這些標志帶給鏈接器。該指令與LOCAL_LDLIBS有些類似,一般情況下,該選項會用于指定第三方編譯的靜態庫,LOCAL_LDLIBS經常用于指定系統的庫(比如log、OpenGL ES、EGL等)。
  • ·LOCAL_MODULE,該模塊的編譯的目標名,用于區分各個模塊,名字必須是唯一并且不包含空格的,如果編譯目標是so庫,那么該so庫的名字就是lib項目名.so。
  • ·include$(BUILD_SHARED_LIBRARY),其實類似的include還有很多,都是構建系統提供的內置變量,該變量的意義是構建動態庫,其他的內置變量還包括如下幾種。
  • ·——BUILD_STATIC_LIBRARY:構建靜態庫。
  • ·——PREBUILT_STATIC_LIBRARY:對已有的靜態庫進行包裝,使其成為一個模塊。
  • ·——PREBUILT_SHARED_LIBRARY:對已有的動態庫進行包裝,使其成為一個模塊。
  • ·——BUILD_EXECUTABLE:構建可執行文件。

? ? ?構建系統提供的這些內置變量在哪里能夠看到呢?它們都在$NDK_ROOT/build/core/目錄下,這里面會有所有預先定義好的Makefile,開發者include一個變量,實際上就是把對應的Makefile包含到Android.mk中,包括前面提到的CLEAR_VARS,其也是該目錄下面的一個Makefile。

  • ·include$(call all-makefiles-under,$(LOCAL_PATH)),也是構建系統提供的變量,該命令會返回該目錄下所有子目錄的Android.mk列表。

? ? ? 上面已經清楚地講解了Android.mk里的基本語法規則,那么,在輸入命令ndk-build之后,系統到底會使用哪些編譯器以及打包器和鏈接器來編譯我們的程序呢?
? ? ? 會使用$NDK_ROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/bin/目錄(以Mac平臺為例)下面的gcc、g++、ar、ld等工具。同樣在該目錄下的strip工具將會用于清除so包里面的源碼,nm工具可以供開發者查看靜態庫下的符號表。
? ? ? 那么進行gcc編譯的時候,頭文件將放在哪里呢?
? ? ?$NDK_ROOT/platforms/android-18/arch-arm/usr/include/目錄下會存放編譯過程所依賴的頭文件。
? ? 那么在鏈接過程中,經常使用的log或者OpenSL ES以及OpenGL ES等庫又將放在哪里呢?

答案其實已在前文中提到過,$NDK_ROOT/platforms/android-18/arch-arm/usr/lib/目錄下會存放鏈接過程中所依賴的庫文件。
(2)Application.mk
Application.mk分為以下幾個部分。

  • ·APP_ABI:=XXX,這里的XXX是指不同的平臺,可以選填的有x86、mips、armeabi、armeabi-v7a、all等,值得一提的是,若選擇all則會構建出所有平臺的so,如果不填寫該項,那么將默認構建為armeabi平臺下的庫。由于工作的原因,筆者和Intel的員工打過交道,構建armeabi-v7a平臺的so之所以可以運行在Intel x86架構的CPU平臺下,是因為Intel針對armeabi做了兼容,但是如果想要應用以最小的能耗、最高的效率運行在Intel x86平臺上,則還是要指定構建的so為x86平臺。因此,如果想要提高App的運行性能,則還需要編譯出x86平臺。類似于前面介紹的iOS平臺,如果不考慮模擬器的話,則僅需要構建armv7與arm64平臺架構,那么對于Android平臺呢?對于armv7-a,肯定是要編譯的;至于arm64-v8a這個平臺,其實已經占到了50%以上,最好也將其單獨編譯出來;同時armv5這個平臺的設備還是存在的,當然不同App在不同架構下的比例也不盡相同,讀者可以根據實際場景來決定編譯的平臺數目。這里需要注意的是,編譯arm64-v8a的時候使用的交叉工具編譯鏈與之前的armv7所在的目錄有比較大的差異,其目錄存在于:
  • ·$NDK_ROOT/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin
  • ·編譯過程中使用的編譯工具都存在于上述目錄下。
  • ·APP_STL:=gnustl_static,NDK構建系統提供了由Android系統給出的最小C++運行時庫(/system/lib/libstdc++.so)的C++頭文件。然而,NDK帶有另一個C++實現,開發者可以在自己的應用程序中使用或鏈接它,定義APP_STL可選擇它們中的一個,可選項包括:stlport_static、stlport_shared、gnustl_static。
  • ·APP_CPPFLAGS:=-std=gnu++11-fexceptions,指定編譯過程的flag,可以在該選項中開啟exception rtti等特性,但是為了效率考慮,最好關閉rtti。
  • ·NDK_TOOLCHAIN_VERSION=4.8,指定交叉工具編譯鏈里面的版本號,這里指定使用4.8。
  • ·APP_PLATFORM:=android-9,指定創建的動態庫的平臺。
  • ·APP_OPTIM:=release,該變量是可選的,用來定義“release”或“debug”,“release”模式是默認的,并且會生成高度優化的二進制代碼;“debug”模式生成的是未優化的二進制代碼,但是可以檢測出很多的BUG,經常用于調試階段,也相當于在ndk-build指令后邊直接加上參數NDK_DEBUG=1。

LAME的交叉編譯

在Android的編譯中,一般情況下會使用一個Shell腳本文件,指定好編譯器里面的各個工具,然后把對應的Configure的命令與選項開關配置好,最后執行該Shell腳本

#!/bin/bash NDK_ROOT=/Users/apple/soft/android/android-ndk-r9b PREBUILT=$NDK_ROOT/toolchains/arm-linux-androideabi-4.6/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=./armv7a make clean make -j8 make install

下面就來針對該腳本的每一行命令進行詳細解釋。
第一部分是設置NDK_ROOT,并且聲明platform和prebuilt,最終配置可在環境變量中查看。
第二部分主要是聲明CFLAGS與LDFLAGS,其目的是在編譯和鏈接階段找到正確的頭文件與鏈接到正確的庫文件。這里需要特別注意的是,在這兩個設置的后邊都加上了-march=armv7-a,這相當于是讓編譯器知道要編譯的目標平臺是armv7-a。
第三部分是聲明CC、AS、AR、LD、NM、STRIP等工具,具體每一個工具是做什么用的,前面都已經介紹過了,如果要編譯armv5、x86或者arm64-v8a,那么在代碼倉庫中會提供全量編譯的Shell腳本文件。
第四部分就是使用LAME本身的Configure進行編譯裁剪。
第五部分就是使用標準的編譯鏈接和安裝。
最終執行腳本成功之后,可以看到在指定的Prefix目錄下面,包含了lib和include目錄,里面分別是靜態庫文件和頭文件,這兩個目錄的作用在前面已經說過很多遍了,在此不再贅述。

使用LAME編碼MP3文件

首先新建兩個文件:mp3_encoder.h和mp3_encoder.cpp。

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 Destory(); }; 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]; unsigned char* mp3_buffer = new unsigned char[bufferSize]; size_t 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]; } } size_t wroteSize = lame_encode_buffer(lameClient,(short int *) leftBuffer,(short int *) rightBuffer, (int)(readBufferSize / 2),mp3_buffer,bufferSize); fwrite(mp3_buffer,1,wroteSize,mp3File); } delete[]buffer; delete[]leftBuffer; delete[]rightBuffer; delete[]mp3_buffer; }void Mp3Encoder:Destory() { if(pcmFile) { fclose(pcmFile); } if(mp3File) { fclose(mp3File); lame_close(lameClient); } }

?

?

總結

以上是生活随笔為你收集整理的lame库(iOS 和 Android)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。