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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java lame_音视频编解码——LAME

發布時間:2023/12/16 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java lame_音视频编解码——LAME 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、LAME簡介

LAME是目前非常優秀的一種MP3編碼引擎,在業界,轉碼成Mp3格式的音頻文件時,最常用的就是LAME庫。當達到320Kbit/s時,LAME編碼出來的音頻質量幾乎可以和CD的音質相媲美,并且還能保證整個音頻文件的體積非常小,因此若要在移動端平臺上編碼MP3文件,使用LAME便成為唯一的選擇。

二、使用場景

操作系統:Android。

場景:

1.錄音時保存Mp3格式的文件

2. 將wav無損音頻文件轉碼成mp3這種體積相對較小的音頻文件。

3.可以將獲取到的音頻流進行錄制保存為mp3格式。

三、開發準備

LAME的源碼是托管到sourceforge.net上的,我們開發一個基于LAME的項目,就不得不下載其源碼用于編譯。

如果需要集成到Android系統上,就需要開發者具備一些NDK開發的能力。

四、開發過程

下面針對Android使用Lame做了基本的封裝,供實際開發過程中進行參考:

首先,在java類中定義native方法。

private static native long nInit(int inSampleRate, int inChannels, int outSampleRate, int outBitrate, int model, intquality);private static native int nGetVersion(longlamePtr);private static native int mGetMp3bufferSize(longlamePtr);private static native int mGetMp3bufferSizeWithSamples(long lamePtr, intsamples);private static native int nEncodeShortInterleaved(long lamePtr, short[] bufLR, int samples, byte[] outMp3buf);private static native int nEncodeShort(long lamePtr, short[] bufL, short[] bufR, int samples, byte[] outMp3buf);private static native int nFlush(long lamePtr, byte[] outBuf);private static native void nClose(long lamePtr);

生成相應的.h的頭文件,并實現該頭文件,完成整體邏輯的編寫。

#include #include#include#include"com_renhui_lame_Lame.h"#include"libmp3lame/lame.h"

extern "C"JNIEXPORT jlong JNICALL Java_com_renhui_lame_Lame_nInit(JNIEnv*env, jclass type, jint inSampleRate, jint inChannels,

jint outSampleRate, jint outBitrate, jint model, jint quality) {

lame_global_flags*lameFlags;

lameFlags=lame_init();

lame_set_in_samplerate(lameFlags, inSampleRate);

lame_set_num_channels(lameFlags, inChannels);

lame_set_out_samplerate(lameFlags, outSampleRate);

lame_set_brate(lameFlags, outBitrate);

lame_set_mode(lameFlags, (MPEG_mode) model);

lame_set_quality(lameFlags, quality);int code =lame_init_params(lameFlags);if (code != 0) {

lame_close(lameFlags);returncode;

}return (long) lameFlags;

}

JNIEXPORT jint JNICALL Java_com_renhui_lame_Lame_nGetVersion(JNIEnv*env, jclass type, jlong lamePtr) {

lame_global_flags*lameFlags;

lameFlags= (lame_global_flags *) lamePtr;returnlame_get_version(lameFlags);

}

JNIEXPORT jint JNICALL Java_com_renhui_lame_Lame_mGetMp3bufferSize(JNIEnv*env, jclass type, jlong lamePtr) {

lame_global_flags*lameFlags;

lameFlags= (lame_global_flags *) lamePtr;returnlame_get_size_mp3buffer(lameFlags);

}

JNIEXPORT jint JNICALL Java_com_renhui_lame_Lame_mGetMp3bufferSizeWithSamples(JNIEnv*env, jclass type, jlong lamePtr, jint samples) {

lame_global_flags*lameFlags;

lameFlags= (lame_global_flags *) lamePtr;int version =lame_get_version(lameFlags);int bitrate =lame_get_brate(lameFlags);int sampleRate =lame_get_out_samplerate(lameFlags);float p = (bitrate / 8.0f) /sampleRate;if (version == 0) {//MPEG2: num_samples*(bitrate/8)/samplerate + 4*576*(bitrate/8)/samplerate + 256

return (jint) ceil(samples * p + 4 * 576 * p + 256);

}else if (version == 1) {//MPEG1: num_samples*(bitrate/8)/samplerate + 4*1152*(bitrate/8)/samplerate + 512

return (jint) ceil(samples * p + 4 * 1152 * p + 512);

}else{return (jint) ceil((1.25 * samples + 7200));

}

}

JNIEXPORT jint JNICALL Java_com_renhui_lame_Lame_nEncodeShortInterleaved(JNIEnv*env, jclass type, jlong lamePtr,

jshortArray bufLR_, jint samples, jbyteArray outMp3buf_) {

lame_global_flags*lameFlags;

lameFlags= (lame_global_flags *) lamePtr;

jshort*bufLR = env->GetShortArrayElements(bufLR_, NULL);

jbyte*outMp3buf = env->GetByteArrayElements(outMp3buf_, NULL);const jsize outMp3bufSize = env->GetArrayLength(outMp3buf_);int result =lame_encode_buffer_interleaved(lameFlags, bufLR, samples,

(u_char*) outMp3buf, outMp3bufSize);

env->ReleaseShortArrayElements(bufLR_, bufLR, 0);

env->ReleaseByteArrayElements(outMp3buf_, outMp3buf, 0);returnresult;

}

JNIEXPORT jint JNICALL

Java_com_renhui_lame_Lame_nEncodeShort(JNIEnv*env, jclass type, jlong lamePtr, jshortArray bufL_,

jshortArray bufR_, jint samples, jbyteArray outMp3buf_) {

lame_global_flags*lameFlags;

lameFlags= (lame_global_flags *) lamePtr;

jshort*bufL = env->GetShortArrayElements(bufL_, NULL);

jshort*bufR = env->GetShortArrayElements(bufR_, NULL);

jbyte*outMp3buf = env->GetByteArrayElements(outMp3buf_, NULL);const jsize outMp3bufSize = env->GetArrayLength(outMp3buf_);int result =lame_encode_buffer(lameFlags, bufL, bufR, samples,

(u_char*) outMp3buf, outMp3bufSize);

env->ReleaseShortArrayElements(bufL_, bufL, 0);

env->ReleaseShortArrayElements(bufR_, bufR, 0);

env->ReleaseByteArrayElements(outMp3buf_, outMp3buf, 0);returnresult;

}

JNIEXPORT jint JNICALL

Java_com_renhui_lame_Lame_nFlush(JNIEnv*env, jclass type, jlong lamePtr, jbyteArray outBuf_) {

lame_global_flags*lameFlags;

lameFlags= (lame_global_flags *) lamePtr;

jbyte*outBuf = env->GetByteArrayElements(outBuf_, NULL);const jsize outBufSize = env->GetArrayLength(outBuf_);int result = lame_encode_flush(lameFlags, (u_char *) outBuf, outBufSize);

env->ReleaseByteArrayElements(outBuf_, outBuf, 0);returnresult;

}

JNIEXPORTvoidJNICALL

Java_com_renhui_lame_Lame_nClose(JNIEnv*env, jclass type, jlong lamePtr) {

lame_global_flags*lameFlags;

lameFlags= (lame_global_flags *) lamePtr;

lame_close(lameFlags);

}

編寫Android.mk和Application.mk,為ndk-build打包做準備。

Android.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE :=mp3lame

LAME_LIBMP3_DIR :=libmp3lame

LOCAL_SRC_FILES :=\

$(LAME_LIBMP3_DIR)/bitstream.c \

$(LAME_LIBMP3_DIR)/fft.c \

$(LAME_LIBMP3_DIR)/id3tag.c \

$(LAME_LIBMP3_DIR)/mpglib_interface.c \

$(LAME_LIBMP3_DIR)/presets.c \

$(LAME_LIBMP3_DIR)/quantize.c \

$(LAME_LIBMP3_DIR)/reservoir.c \

$(LAME_LIBMP3_DIR)/tables.c \

$(LAME_LIBMP3_DIR)/util.c \

$(LAME_LIBMP3_DIR)/VbrTag.c \

$(LAME_LIBMP3_DIR)/encoder.c \

$(LAME_LIBMP3_DIR)/gain_analysis.c \

$(LAME_LIBMP3_DIR)/lame.c \

$(LAME_LIBMP3_DIR)/newmdct.c \

$(LAME_LIBMP3_DIR)/psymodel.c \

$(LAME_LIBMP3_DIR)/quantize_pvt.c \

$(LAME_LIBMP3_DIR)/set_get.c \

$(LAME_LIBMP3_DIR)/takehiro.c \

$(LAME_LIBMP3_DIR)/vbrquantize.c \

$(LAME_LIBMP3_DIR)/version.c \

com_renhui_lame_Lame.cpp

LOCAL_C_INCLUDES += $(LOCAL_PATH)/mp3lame

LOCAL_LDLIBS := -llog -lz

include $(BUILD_SHARED_LIBRARY)

Application.mk:

APP_ABI := all

#APP_ABI := armeabi armeabi-v7a x86

# APP_ABI :=armeabi

APP_PLATFORM := android-14

五、Lame重點API說明

1. lame_init()

lame_init() 用于初始化lame引擎,初始化完成后可以設置輸入的相關參數:比特率、通道數。

注意:這些參數需要了解清楚需求后進行設置,否則轉碼出來的音頻可能出現時長或者播放的問題。

glf =lame_init();

lame_set_in_samplerate(glf, inSampleRate);

lame_set_num_channels(glf, outChannel);

lame_set_out_samplerate(glf, outSampleRate);

lame_set_brate(glf, outBitrate);

lame_set_quality(glf, quality);

lame_init_params(glf);

2. lame_encode_buffer()和?lame_encode_buffer_interleaved()

if (channels == 2) {

write= lame_encode_buffer_interleaved(gfp, input_buffer, read, mp3_buffer,MP3BUFSIZE);//立體聲用此方法編碼

} else if (channels == 1) {

write= lame_encode_buffer(gfp, input_buffer, input_buffer, read,mp3_buffer, MP3BUFSIZE);//單聲道

}

3. lame_mp3_tags_fid(gfp,outfp)

在lame_encode_flush(gfp,mp3_buffer, sizeof(mp3_buffer))方法之后,lame_close(gfp)之前調用lame_mp3_tags_fid(gfp,outfp)方法為MP3文件添加vbr頭,播放器才能正讀取時間。

六、思維拓展

實戰:

1. 錄音為Mp3格式:(代碼已轉private)

2. 將wav格式的音頻文件轉碼為Mp3格式:(代碼已轉private)

推薦資料:

總結

以上是生活随笔為你收集整理的java lame_音视频编解码——LAME的全部內容,希望文章能夠幫你解決所遇到的問題。

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