之前有分析过很多 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 ,需要好好整明白]