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

歡迎訪問 生活随笔!

生活随笔

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

Android

android生成预处理文件,FFmpeg:Android利用Filter进行音频数据预处理

發布時間:2024/9/30 Android 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android生成预处理文件,FFmpeg:Android利用Filter进行音频数据预处理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

這篇文件簡單介紹下移動端Android系統下利用FFmpeg的Filter進行音頻數據預處理的方法。

按照慣例先上一份源碼 AndroidFFmpegFilter。

項目實現了:

FFmepg編譯須知

由于需要用到Filter模塊,

所以在FFmpeg編譯腳本中需要開啟相關編譯選項。

否則會出現 avfilter_get_by_name(filter_name) 找不到對應的處理器。

--enable-filters

#or

--enable-filter=name #name 指定需要使用到的filter name

如果不想自己編譯,可以使用項目編譯好的 動態庫。

使用FFmpeg相關動態庫

接下來要將ffmpeg的動態庫鏈接到我們的工程上面。

Filter相關只需要使用到libavfilter.so、libavformat.so、libavutil.so這三個動態庫。

參考代碼如下(提供CMake實現,Android.mk請自己轉換):

set(LIB_DIR ${PROJECT_SOURCE_DIR}/libs)

#設置ffmpeg的頭文件目錄位置

include_directories(${LIB_DIR}/include/ffmpeg)

#導入avfilter動態庫

add_library( avfilter

SHARED

IMPORTED )

set_target_properties( avfilter

PROPERTIES

IMPORTED_LOCATION

${LIB_DIR}/${ANDROID_ABI}/libavfilter-6.so )

#導入avformat動態庫

add_library( avformat

SHARED

IMPORTED )

set_target_properties( avformat

PROPERTIES

IMPORTED_LOCATION

${LIB_DIR}/${ANDROID_ABI}/libavformat-57.so )

#導入avutil動態庫

add_library( avutil

SHARED

IMPORTED )

set_target_properties( avutil

PROPERTIES

IMPORTED_LOCATION

${LIB_DIR}/${ANDROID_ABI}/libavutil-55.so )

#連接動態庫

target_link_libraries(

your-lib

avfilter

avutil

avformat

)

FFmpeg Filter初始化流程

導入頭文件

extern "C" {

#include

#include

#include

};

注冊相關filter

avfilter_register_all();

獲取一個AVFilterGraph

利用這個Graph可以對后續的AVFilter進行管理。

AVFilterGraph *graph = avfilter_graph_alloc();

對于AVFilter的處理

一般步驟都是:

1、通過filter_name獲取到需要使用的AVFilter。

AVFilter filter = avfilter_get_by_name(filter_name);

2、利用AVFilter從AVFilterGraph獲取到相應的上下文環境。

AVFilterContext filter_ctx = avfilter_graph_alloc_filter(graph, filter, NULL);

3、構造初始化參數配置(多種方式)

方式一

char options_str[1024];

snprintf(options_str, sizeof(options_str),

"sample_fmt=%s:sample_rate=%d:channel_layout=0x%" PRIx64 ,

av_get_sample_fmt_name(sample_format),

sample_rate,

sample_channel);

avfilter_init_str(filter_ctx, options_str);

方式二

char ch_layout[64];

av_get_channel_layout_string(ch_layout, sizeof(ch_layout), 0, sample_channel);

av_opt_set(filter_ctx, "channel_layout", ch_layout, AV_OPT_SEARCH_CHILDREN);

av_opt_set(filter_ctx, "sample_fmt", av_get_sample_fmt_name(sample_format), AV_OPT_SEARCH_CHILDREN);

av_opt_set_int(filter_ctx, "sample_rate", sample_rate, AV_OPT_SEARCH_CHILDREN);

avfilter_init_str(filter_ctx, NULL);

方式三

AVDictionary *options_dict = NULL;

char ch_layout[64];

av_get_channel_layout_string(ch_layout, sizeof(ch_layout), 0, sample_channel);

av_dict_set(&options_dict, "channel_layout", ch_layout, AV_OPT_SEARCH_CHILDREN);

av_dict_set(&options_dict, "sample_fmt", av_get_sample_fmt_name(sample_format), AV_OPT_SEARCH_CHILDREN);

av_dict_set(&options_dict, "sample_rate", sample_rate, AV_OPT_SEARCH_CHILDREN);

avfilter_init_dict(volume_ctx, &options_dict);

PS:以上三種方式的實現效果是一致的。

對各個Filter進行鏈接

連接情況一(例如音量調節):

//abuffersrc_ctx -> volume_ctx -> abuffersink_ctx

avfilter_link(abuffersrc_ctx, 0, volume_ctx, 0);

avfilter_link(volume_ctx, 0, abuffersink_ctx, 0);

連接情況二 (例如混音):

//abuffersrc1_ctx

// -> amix_ctx -> abuffersink_ctx

//abuffersrc2_ctx

avfilter_link(abuffersrc1_ctx, 0, amix_ctx, 0);

avfilter_link(abuffersrc2_ctx, 0, amix_ctx, 1);

avfilter_link(amix_ctx, 0, abuffersink_ctx, 0);

初始化整個filters鏈

avfilter_graph_config(graph, NULL);

以上的流程就是整個FFmpeg Filter的初始化過程。

FFmpeg Filter使用流程

源音頻數據輸入

1、構造一個AVFrame:

//獲取一個AVFrame實例

AVFrame *avframe = av_frame_alloc();

//配置輸入音頻的格式、采樣率、聲道和采樣數

avframe->sample_rate = sample_rate;

avframe->format = sample_format;

avframe->channel_layout = sample_channel;

avframe->nb_samples = nb_sample;

//根據上面設置的情況,申請音頻數據緩沖區

av_frame_get_buffer(avframe, 1);

2、將源音頻輸入送入Filter鏈中:

av_buffersrc_add_frame(abuffersrc_ctx, avframe);

3、銷毀AVFrame相關資源

av_frame_free(&avframe);

處理后音頻數據輸出

1、申請一個AVFrame實例,值得提醒的是我們不需要對這個AVFrame做任何配置

AVFrame *avframe = av_frame_alloc();

2、從Filters鏈中獲取處理后的數據包

av_buffersink_get_frame(abuffersink_ctx, avframe);

3、提取完畢AVFrame的數據后,我們需要將其銷毀

av_frame_free(&avframe);

最后說幾句

對于FFmpeg Filter的使用,基本都是遵循上述流程。

注冊Filters

獲取一個AVFilterGraph

獲取多個AVFilter和AVFilterContext并進行參數配置

連接各個AVFilterContext

初始化整個Filters鏈

將源數據AVFrame輸入Filters鏈接收端

從Filters鏈輸出端獲取處理后數據AVFrame

對于音量調節,我們需要獲取如下幾個filter:

abuffer:提供了音頻數據的輸入端。

volume:提供了音頻數據音量調節的模塊。

aformat:提供了轉換成我們期望輸出格式的模塊,是因為Graph會在abuffer和volume之間自動做了格式轉換。

abuffersink:提供了音頻數據的輸出端。

對于混音,我們需要獲取如下幾個filter:

abuffer:提供了音頻數據的輸入端,我們需要獲取兩個,因為有兩路輸入。

amix:提供了多路音頻數據混合的模塊。

aformat:提供了轉換成我們期望輸出格式的模塊,是因為Graph會在abuffer和amix之間自動做了格式轉換。

abuffersink:提供了音頻數據的輸出端。

播放PCM文件可以利用Audacity這個工具可以導入pcm原始文件,并且提供了波形圖查看和播放功能。

本文同步發布于簡書、CSDN。

End!

總結

以上是生活随笔為你收集整理的android生成预处理文件,FFmpeg:Android利用Filter进行音频数据预处理的全部內容,希望文章能夠幫你解決所遇到的問題。

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