【從零衝擊音視頻開發】FFmpeg的介紹和基本使用

前言

這篇文章寫了有一下子了,可是我手頭做業要寫不完了,下週三以前估計最多也就更新一下個人面經了,由於今天晚上還要抖音的三面,阿里的下週一估計也要到hr面了。週六周天的時間,個人計組和電路學做業都還沒開動,再不學我就要涼了,時間真的太緊了,見諒見諒。java

文章內容參考書目《音視頻開發進階指南 -- 基於 Android 與 iOS 平臺的實踐》git

GitHub傳送門

目錄

【1】【從零衝擊音視頻開發】音視頻開發必備知識基礎github

【2】【從零衝擊音視頻開發】移動環境搭建面試

【3】【從零衝擊音視頻開發】FFmpeg的介紹和基本使用json

FFmpeg的環境搭建

材料清單:
1. 10.15.2的OSX系統
2. HomeBrew(安裝姿式:/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)")
3. ffmpeg的依賴(安裝姿式: brew install ffmpeg;文件路徑: /usr/local/Cellar)
4. ffmpeg-4.2.2的源碼(官網下)
5. NDK-r20
複製代碼

這是一個用於本地使用的環境,裏面放置有很多的樣例,可是不建議使用在開發。ruby

我使用過了不少次,.a的靜態庫在XCode上能直接玩,在AS上就直接整不起來。因此這裏要推一個交叉編譯詳解的文章。bash

FFmpeg模塊介紹

bin

命令行工具所在的位置,ffplayffmpegffprobe等等。工具

// ffprobe各類命令
> ffprobe 文件 // 顯示文件頭信息
> ffprobe -show_format 文件 // 顯示輸出格式、時間長度、文件大小、比特率等信息
> ffprobe -pirnt_format json -show_streams 文件 // 以json格式輸出具體每個流的信息
> ffprobe -show_frames 文件 // 顯示幀信息
> ffprobe -show_packets 文件 // 顯示包信息
//。。。。。

// ffplay
> ffplay 文件 // 播放
> ffplay 文件 -loop 10 // 循環播放10次
> ffplay 文件 -ast 0 // 播放第0路音頻流,其餘路沒有流的話會靜音
> ffplay 文件 -vst 0 // 播放第0路視頻流,其餘路沒有流的話會黑屏
> ffplay 文件.pcm -f s16le -channels 2 -ar 44100 // 播放pcm格式文件的方式,須要設置格式(-f),聲道數(-channels),採樣率(-ar)
> ffplay -f rawvideo -pixel_format yuv420p -s 480*480 文件.yuv(文件.rgb) // 查看一幀的視頻幀(這個沒有調試經過)
> ffplay 文件 -sync audio // 以音頻爲基準進行音視頻同步(默認方案)
> ffplay 文件 -sync video // 以視頻爲基準進行音視頻同步
> ffplay 文件 -sync ext // 之外部時鐘爲基準進行音視頻同步
> ffplay 文件 -ss 50 // 跳過50s的內容
//。。。。。

// ffmpeg
// 會有不少的經過參數以圖片給出,具體使用後期會慢慢看到,就再也不演示
複製代碼

inlcude -> 8大模塊

存放的是已經編譯結束的靜態庫文件的頭文件

  1. AVCodec: 用於編碼解碼
  2. AVDevice: 輸入輸出設備
  3. AVFilter: 音視頻濾鏡庫,提供音視頻特效的處理。
  4. AVFormat: 文件格式和協議庫。封裝了Protocol層和DemuxerMuxer層。
  5. AVResample: 用於音頻重採樣 (書上說老版本纔會編譯出來,已經廢棄,可是個人版本是最新的,有待考察)
  6. AVUtil: 核心工具
  7. PostProc: 用於後期處理,是使用AVFilter時要開啓的模塊。
  8. SwResample: 用於音頻重採樣,對音頻進行聲道數、數據格式、採樣率等基本信息轉化。
  9. SWScale: 將圖像進行格式轉換,好比YUV -> RGB

lib

存放的是已經編譯完成的靜態庫文件,在連接階段會使用到。

share

其實就是一個 example的位置,用於講解 FFmpeg各個工具的使用方法,還有使用樣例等等。

FFmpeg的使用

前面講了不少東西,可是咱們真正要在Java代碼中如何進行使用卻徹底尚未進行過,因此這裏就要進行的是Java代碼中的測試了。

第一步:導包和引用

而後 CMakeList.txt中導入咱們須要加載的 so

cmake_minimum_required(VERSION 3.4.1)

# 定義變量
set(ffmpeg_lib_dir ${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})
set(ffmpeg_head_dir ${CMAKE_SOURCE_DIR}/ffmpeg)

add_library( # Sets the name of the library.
        audioencoder
        SHARED
        # 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
        # mine
        audioencoder/audioencoder.cpp
        audioencoder/mp3_encoder.cpp)

# 添加ffmpeg相關的so庫
add_library( avutil
        SHARED
        IMPORTED )
set_target_properties( avutil
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libavutil.so )

add_library( swresample
        SHARED
        IMPORTED )
set_target_properties( swresample
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libswresample.so )

add_library( avcodec
        SHARED
        IMPORTED )
set_target_properties( avcodec
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libavcodec.so )

add_library( avfilter
        SHARED
        IMPORTED)
set_target_properties( avfilter
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libavfilter.so )

add_library( swscale
        SHARED
        IMPORTED)
set_target_properties( swscale
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libswscale.so )

add_library( avformat
        SHARED
        IMPORTED)
set_target_properties( avformat
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libavformat.so )

add_library( avdevice
        SHARED
        IMPORTED)
set_target_properties( avdevice
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libavdevice.so )


find_library( # Sets the name of the path variable.
        log-lib
        log)

# 引入頭文件
include_directories(${ffmpeg_head_dir}/include)

target_link_libraries( # Specifies the target library.
        audioencoder
        # ffmpeg
        avutil
        swresample
        avcodec
        avfilter
        swscale
        avformat
        avdevice

        ${log-lib})
複製代碼

第二步:使用

固然使用方案上來講仍是同樣的,可是這裏咱們存在須要注意的地方,由於FFmpeg是由C編寫而成的,而咱們去編譯的倒是使用的C++,因此套上一層extern "C"是必需要作的事情。

這裏的源碼直接抄的貓哥的,作一個示範。

Github中帶了一個用FFmpeg去解碼mp3->pcm的樣例,固然裏面有不少功能感受也沒用到吧,主要作了一個解釋,詳細看關注點,固然我也在源碼中提了一些問題,你要是知道怎麼解決,或者有什麼新的問題,發評論啊、發郵件之類的,我會繼續探索的。

以後理解的差很少了就會本身再開一個項目動手開發的,但願這個學習項目大家也能star,嘿嘿嘿。

以上就是個人學習成果,若是有什麼我沒有思考到的地方或是文章內存在錯誤,歡迎與我分享。


相關文章推薦:

【從零衝擊音視頻開發】移動環境搭建

面試官問我:「泛型擦除是什麼,會帶來什麼問題?」

【從零衝擊音視頻開發】音視頻開發必備知識基礎

相關文章
相關標籤/搜索