吾的最終目的在移動端。但爲了方便對FFmpeg的
認知和調試
,先在桌面
把它消化一下,畢竟在Android中修改、調試都比較費事。知識異曲同工,重要的不是它在哪裏,而是它能幹嗎,你想拿他幹嗎
。
FFmpeg是c寫的,在使用時須要動態連接到相應的庫上。雖然用文本編輯器和命令行也能手撕代碼,但IDE能讓人少調些頭髮。這裏記錄一下Xcode 和 CLion 桌面、Android集成FFmpeg的方式。本篇的目標只有一個:跑起來
html
brew能夠安裝ffmpeg,它是全副武裝的ffmpeg,enable了不少東西,因此下載起來比較耗時間。你也能夠在ffmpeg官方下載,本身根據需求來編譯。ios
---[· brew install ffmpeg
複製代碼
brew info ffmpeg
查看一下當前信息,會看到安裝的文件夾git
---[· brew info ffmpeg
ffmpeg: stable 4.2.1 (bottled), HEAD
Play, record, convert, and stream audio and video
https://ffmpeg.org/
/usr/local/Cellar/ffmpeg/4.2.1_2 (287 files, 56.6MB) *
Poured from bottle on 2019-11-26 at 09:16:29
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/ffmpeg.rb
==> Dependencies
Build: nasm ✔, pkg-config ✔, texi2html ✘
Required: aom ✔, fontconfig ✔, freetype ✔, frei0r ✔, gnutls ✔, lame ✔, libass ✔, libbluray ✔, libsoxr ✔, libvidstab ✔, libvorbis ✔, libvpx ✔, opencore-amr ✔, openjpeg ✔, opus ✔, rtmpdump ✔, rubberband ✔, sdl2 ✔, snappy ✔, speex ✔, tesseract ✔, theora ✔, x264 ✔, x265 ✔, xvid ✔, xz ✔
==> Options
--HEAD
Install HEAD version
複製代碼
在環境變量文件中添加對應的bin路徑,方便全局訪問內部可自行文件。github
export PATH=$PATH:/usr/local/Cellar/ffmpeg/4.2.1_2/bin
複製代碼
在環境變量文件中添加對應的bin路徑,方便全局訪問內部可自行文件。shell
---[· ffmpeg
ffmpeg version 4.2.1 Copyright (c) 2000-2019 the FFmpeg developers
built with Apple clang version 11.0.0 (clang-1100.0.33.8)
configuration: --prefix=/usr/local/Cellar/ffmpeg/4.2.1_2 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags='-I/Library/Java/JavaVirtualMachines/adoptopenjdk-13.jdk/Contents/Home/include -I/Library/Java/JavaVirtualMachines/adoptopenjdk-13.jdk/Contents/Home/include/darwin -fno-stack-check' --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libmp3lame --enable-libopus --enable-librubberband --enable-libsnappy --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-libsoxr --enable-videotoolbox --disable-libjack --disable-indev=jack
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
Hyper fast Audio and Video encoder
usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...
複製代碼
---[· cd /usr/local/Cellar/ffmpeg/4.2.1_2
---[· ls
Changelog README.md lib
INSTALL_RECEIPT.json bin share
LICENSE.md include
複製代碼
這裏盛放着動態連接庫,也就是ffmpeg的靈魂編程
---[· cd lib
---[· ls
libavcodec.58.54.100.dylib libavresample.dylib
libavcodec.58.dylib libavutil.56.31.100.dylib
libavcodec.a libavutil.56.dylib
libavcodec.dylib libavutil.a
libavdevice.58.8.100.dylib libavutil.dylib
libavdevice.58.dylib libpostproc.55.5.100.dylib
libavdevice.a libpostproc.55.dylib
libavdevice.dylib libpostproc.a
libavfilter.7.57.100.dylib libpostproc.dylib
libavfilter.7.dylib libswresample.3.5.100.dylib
libavfilter.a libswresample.3.dylib
libavfilter.dylib libswresample.a
libavformat.58.29.100.dylib libswresample.dylib
libavformat.58.dylib libswscale.5.5.100.dylib
libavformat.a libswscale.5.dylib
libavformat.dylib libswscale.a
libavresample.4.0.0.dylib libswscale.dylib
libavresample.4.dylib pkgconfig
libavresample.a
複製代碼
頭文件,也就是全部功能的索引,使用時須要引入相關頭文件json
---[· cd ..
---[· cd include
---[· ls
libavcodec libavfilter libavresample libpostproc libswscale
libavdevice libavformat libavutil libswresample
---[· cd libavutil
---[· ls
adler32.h hwcontext_vaapi.h
aes.h hwcontext_vdpau.h
aes_ctr.h hwcontext_videotoolbox.h
attributes.h imgutils.h
audio_fifo.h intfloat.h
略...
複製代碼
能夠直接經過
ffmpeg
經過命令行操做音視頻,ffplay
播放音視頻api
---[· 4.2.1_2 % cd /usr/local/Cellar/ffmpeg/4.2.1_2/bin
---[· bin % ls
略...
ffmpeg normalize.py zmqshell.py
ffplay patcheck
複製代碼
另外share文件夾有一些小demo,很具備參考價值。bash
選擇C++ 和C都無所謂,若是想用C++ 的特性就選C++,不然直接寫C也能夠。app
注意替對應的ffmpeg目錄。在target_link_libraries中添加須要的連接庫,一共有八根大蔥,能夠根據需求本身添加。八蔥住在上面的lib文件夾裏,食用時掐頭去尾,以保健康。
----[CMakeLists.txt]----
cmake_minimum_required(VERSION 3.15)
project(TolyFF)
set(CMAKE_CXX_STANDARD 14)
set(FFMPEG_DIR /usr/local/Cellar/ffmpeg/4.2.1_2) # FFmpeg的安裝目錄
include_directories(${FFMPEG_DIR}/include/) # 頭文件路徑
link_directories(${FFMPEG_DIR}/lib/) # 連接庫路徑
add_executable(TolyFF main.cpp)
target_link_libraries(TolyFF
avutil # 連接 avutil
avcodec # 連接 avcodec
)
複製代碼
這裏用C++玩,引用時須要
extern "C"
來安照C規範引入頭文件
ffmpeg有本身的日誌系統,在libavutil#log.h中定義,使用以下。
這裏經過avcodec_configuration()能夠查看編譯時的配置參數
#include <iostream>
extern "C" { //C++中特殊處理
#include "libavutil/log.h"
#include "libavcodec/avcodec.h"
}
int main() {
std::cout << "Hello, World!" << std::endl;
av_log_set_level(AV_LOG_DEBUG);//設置日誌級別
av_log(nullptr,AV_LOG_INFO,"hello ffmpeg\n");//打印日誌
auto info=avcodec_configuration();//avcodec配置信息
av_log(nullptr,AV_LOG_DEBUG,"配置:%s",info);
return 0;
}
複製代碼
OK,就這麼簡單,地獄的大門已經打開,進去吧,孩子。
可能你比較習慣使用Xcode,這裏也介紹一下
以下分別配置Build Settings和Build Phases
#include <iostream>
extern "C" { //C++中特殊處理
#include "libavutil/log.h"
#include "libavcodec/avcodec.h"
}
int main() {
std::cout << "Hello, World!" << std::endl;
av_log_set_level(AV_LOG_DEBUG);//設置日誌級別
av_log(nullptr,AV_LOG_INFO,"hello ffmpeg\n");//打印日誌
auto info=avcodec_configuration();//avcodec配置信息
av_log(nullptr,AV_LOG_DEBUG,"配置:%s",info);
return 0;
}
複製代碼
不出意外會崩掉:找不到庫,看日誌顯示,是簽名的鍋。
4.4 對庫進行簽名
在
鑰匙串
裏查看你的證書(沒有可新建)
---[· codesign -f -s "Apple Development: 1981462002@qq.com" /usr/local/Cellar/ffmpeg/4.2.1_2/lib/*.dylib
---[· codesign -f -s "Apple Development: 1981462002@qq.com" /usr/local/opt/*/lib/*.dylib
複製代碼
OK,地獄之門已打開,盡情玩耍吧。
編譯什麼的,網上一堆,之後有機會單寫一篇C/C++庫編譯相關的文章
一步步建立就不廢話了
我只編譯了v7a的,將include頭文件和so拷貝到相應的位置
CMakeLists.txt
和CLion中的是相似的,輔助構建,進行連接到動態庫。網上基本上都是把一堆全配置上,但要知道每一個庫都有各自的功能,打個蚊子是不須要拿出洲際導彈的。這裏只使用avcodec看一下編譯的配置信息。其餘庫須要的時候能夠依葫蘆畫瓢添加。
----[CMakeLists.txt]----
cmake_minimum_required(VERSION 3.4.1)
include_directories(include)#引入頭文件
add_library(TolyFF SHARED native-lib.cpp)
set(distribution_DIR ${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})
add_library(avcodec SHARED IMPORTED)
set_target_properties(avcodec PROPERTIES IMPORTED_LOCATION ${distribution_DIR}/libavcodec.so)
find_library(log-lib log)
target_link_libraries(
TolyFF
avcodec
${log-lib})
複製代碼
初始有個helloworld方法,把
avcodec_configuration
返回看看
#include <jni.h>
#include <string>
extern "C"{
#include <libavcodec/avcodec.h>
}
extern "C"
JNIEXPORT jstring JNICALL
Java_com_toly1994_tolyff_TolyFF_getConfiguration(JNIEnv *env, jclass clazz) {
return env->NewStringUTF(avcodec_configuration());
}
複製代碼
因此
知識異曲同工,重要的不是它在哪裏,而是它能幹嗎,你想拿他幹嗎
,桌面上的功能能夠很容易移植到移動端,它們是一通百通的。平臺上面的都是紙老虎,重點和難點是對流程和音視頻本質的理解。
@張風捷特烈 2019.11.26 未允禁轉
個人公衆號:編程之王
~ END ~