之前有分析過很多 vlc 源碼組成:
《vlc-添加自定義的demuxer解複用插件----播放h264裸文件》
《vlc源碼分析(1)--vlm.c 添加簡單推流器邏輯 》
《vlc源碼分析(2)--input.c mp4文件解複用,mp4模塊加載》
《vlc源碼分析(3)-decoder.c 使用vlm rtsp方式輸出流過程》
《vlc源碼分析(4)-stream_out/rtsp.c vlc中rtsp服務端》
《vlc源碼分析--播放速度控制原理,pts,dts》《使用vlc推流rtsp,同時本地播放和客戶端播放rtsp,延時控制》《vlc duplicate模塊》抽取部分功能分析:《vlc讀取rtsp流-源碼分析---時間戳dts的計算》 《vlc源碼分析-clock.c 時間戳模塊》
《vlc-源碼分析--rtsp服務端-單線程IO複用模型》《WireShark查看vlc播放rtsp流過程,抓包分離出h264流》《libvlc 使用mediaplayer 播放rtsp》 《使用libvlc 開發推流器 demo》
都是分析vlc 源碼部分功能,在ubuntu 編譯vlc 源碼,對於android上的vlc apk程序,也是使用上述vlc(源碼使用c)編譯出來的庫,打包到一起,添加jni調用,編譯成一個 aar(android studio 上用)的開發包,再基於這個包進行二次開發。vlc app即基於這個包二次開發而來,使用這個aar包的demo:《android使用libvlc開發推流的簡單demo_apk》 《android 基於vlc,rtsp推流器》 《Android基於libvlc 播發rtsp視頻流》《vlc-android 開啓硬件解碼》
《==============================================================================================正題分割線=======================================================================================》
分析這個aar包的組成,來源,使用。
要得到這個 aar 開發包,也可以自行編譯:《ubuntu 編譯vlc for android git 拉取vlc官方源碼》《ubuntu 編譯vlc-android》《vlc-android-源碼編譯-修改依賴的live555源碼文件》
組成:
將我們得到的這個libvlc-armv8-3.1.5.aar ,直接改名爲 libvlc-armv8-3.1.5.zip, 右鍵解壓。得到:
子目錄: jni/arm64-v8a : libc++_shared.so libvlc.so libvlcjni.so 和一個class.jar包。
把class.jar包也直接解壓,裏面很多的.class 字節碼文件,這些是vlc 包裝其核心功能,也就是上面的 libvlc.so 而編寫的java代碼,比如java classes\org\videolan\libvlc\LibVLC.class 對應源碼中 /libvlc/src/org/videolan/libvlc/LibVLC.java 其中也是對libvlc.so native層的裝,android 開發vlc的demo時會導入 import org.videolan.libvlc.LibVLC; 簡單分析下這個java文件:
public class LibVLC extends VLCObject<LibVLC.Event> {
...
public LibVLC(Context context, ArrayList<String> options) {
mAppContext = context.getApplicationContext();
loadLibraries();
....
131 private static boolean sLoaded = false;
132
133 public static synchronized void loadLibraries() {
134 if (sLoaded)
135 return;
136 sLoaded = true;
137
138 try {
139 System.loadLibrary("c++_shared");
140 System.loadLibrary("vlc");
141 System.loadLibrary("vlcjni");
142 } catch (UnsatisfiedLinkError ule) {
143 Log.e(TAG, "Can't load vlcjni library: " + ule);
144 /// FIXME Alert user
145 System.exit(1);
146 } catch (SecurityException se) {
147 Log.e(TAG, "Encountered a security issue when loading vlcjni library: " + se);
148 /// FIXME Alert user
149 System.exit(1);
150 }
151 }
}
在構造函數中就 載入了 libc++_shared.so libvlc.so libvlcjni.so 其中的libvlcjni.so ,在源碼 /libvlc/jni 目錄中,實現jni層。
核心功能都被打包成了libvlc.so,可以看到這個libvlc.so達到了35M.
aar包中libvlc.so 的構建: 分析源碼的編譯腳本,compile.sh -> compile-libvlc.sh ->
echo -e "ndk-build vlc"
$ANDROID_NDK/ndk-build$OSCMD -C libvlc \
APP_STL="c++_shared" \
APP_CPPFLAGS="-frtti -fexceptions" \
VLC_SRC_DIR="$VLC_SRC_DIR" \
VLC_BUILD_DIR="$VLC_BUILD_DIR" \
VLC_CONTRIB="$VLC_CONTRIB" \
VLC_CONTRIB_LDFLAGS="$VLC_CONTRIB_LDFLAGS" \
VLC_MODULES="$VLC_MODULES" \
VLC_LDFLAGS="$VLC_LDFLAGS" \
APP_BUILD_SCRIPT=jni/Android.mk \
APP_PLATFORM=android-${ANDROID_API} \
APP_ABI=${ANDROID_ABI} \
NDK_PROJECT_PATH=jni \
NDK_TOOLCHAIN_VERSION=clang \
NDK_DEBUG=${NDK_DEBUG}
調用ndk執行,到 /libvcl/jni/Android.mk ,!!!!!!!!!!!!!!!
# libvlc/jni/Android.mk 這裏編譯得到 aar包中的 libvlc.so libvlcjni.so
LOCAL_PATH := $(call my-dir)
# libvlcjni
include $(CLEAR_VARS)
LOCAL_MODULE := libvlcjni
LOCAL_SRC_FILES := libvlcjni.c
LOCAL_SRC_FILES += libvlcjni-mediaplayer.c
LOCAL_SRC_FILES += libvlcjni-vlcobject.c
LOCAL_SRC_FILES += libvlcjni-media.c libvlcjni-medialist.c libvlcjni-mediadiscoverer.c libvlcjni-rendererdiscoverer.c
LOCAL_SRC_FILES += libvlcjni-dialog.c
LOCAL_SRC_FILES += thumbnailer.c
LOCAL_SRC_FILES += std_logger.c
LOCAL_SRC_FILES += libvlcjni-wangBroadcat.c
LOCAL_C_INCLUDES := $(VLC_SRC_DIR)/include $(VLC_BUILD_DIR)/include $(MEDIALIBRARY_JNI_DIR)
LOCAL_CFLAGS := -std=c11
LOCAL_LDLIBS := -llog
LOCAL_SHARED_LIBRARIES := libvlc
include $(BUILD_SHARED_LIBRARY)
# libvlc
include $(CLEAR_VARS)
LOCAL_MODULE := libvlc
LOCAL_SRC_FILES := libvlcjni-modules.c libvlcjni-symbols.c dummy.cpp
LOCAL_LDFLAGS := -L$(VLC_CONTRIB)/lib
LOCAL_LDLIBS := \
$(VLC_MODULES) \
$(VLC_BUILD_DIR)/lib/.libs/libvlc.a \
$(VLC_BUILD_DIR)/src/.libs/libvlccore.a \
$(VLC_BUILD_DIR)/compat/.libs/libcompat.a \
$(VLC_CONTRIB_LDFLAGS) \
-ldl -lz -lm -llog \
-lliveMedia -lUsageEnvironment -lBasicUsageEnvironment -lgroupsock \
-la52 -ljpeg \
-lavcodec -lebml \
-llua \
-lgcrypt -lgpg-error \
$(VLC_LDFLAGS) \
-llog
LOCAL_CXXFLAGS := -std=c++11
include $(BUILD_SHARED_LIBRARY)
關於編譯libvlc.so , 很重要,其中的參數:LOCAL_LDLIBS := \
$(VLC_MODULES) \
$(VLC_BUILD_DIR)/lib/.libs/libvlc.a \
$(VLC_BUILD_DIR)/src/.libs/libvlccore.a \
$(VLC_BUILD_DIR)/compat/.libs/libcompat.a \
$(VLC_CONTRIB_LDFLAGS) \
-ldl -lz -lm -llog \
-lliveMedia -lUsageEnvironment -lBasicUsageEnvironment -lgroupsock \
-la52 -ljpeg \
-lavcodec -lebml \
-llua \
-lgcrypt -lgpg-error \
$(VLC_LDFLAGS) \
-llog
把$(VLC_MODULES) 展開後其實是所有的 插件lib*plugin.a ,後續有部分連接live555的庫,也是靜態庫,所以這個最終的libvlc.so,其實完全集全了vlc所需要的第三方的庫(比如讀rtsp流用的live555,解碼用的ffmeg)。 把多個.a靜態文件打包成了一個libvlc.so [關於.so .a ,需要好好整明白]