• 如何复用ijkplayer库实现ffmpeg的功能


    ijkplayer库介绍

    现在ijkplayer播放器应用的非常广泛,很多播放器基本上都是基于ijkplayer二次迭代开发的,众所周知,ijkplayer是基于ffplay的,所以要使用ijkplayer,就必须使用三个so库。

    1. jeffmony@JeffMonydeMacBook-Pro arm64-v8a % ls -hl
    2. total 21240
    3. -rwxr-xr-x 1 jeffmony staff   9.6M 4 30 00:25 libijkffmpeg.so
    4. -rwxr-xr-x 1 jeffmony staff   348K 4 30 00:25 libijkplayer.so
    5. -rwxr-xr-x 1 jeffmony staff   474K 4 30 00:25 libijksdl.so

    其中一个libijkffmpeg.so库非常大,有近9.6M,这个非常吓人了,当然你可以裁剪一些不用的库。

    但是ijkplayer毕竟只是播放视频才用到的。但是ijkplayer底层是基于ffmpeg的ffplay播放框架,也就是说ffmpeg也集成到了libijkffmpeg.so中了。

    这就有点意思了,那我们需要引用ffmpeg中的一些方法就不用额外的编译库了,直接使用libijkffmpeg.so中的文件就可以的。

    • 1.节省了空间大小,防止重复编译ffmpeg导致的包体积增大。

    • 2.native接口不用和ijkplayer的上层写在一起,可以单独写,完全不影响。

    看一下这个提交: github.com/JeffMony/Pl…

    • 1.复用libijkffmpeg.so

    • 2.引入ffmpeg头文件

    • 3.编译生成新的so

    利用ijkplayer中ffmpeg代码生成头文件

     

    具体的build_ffmpeg.sh如下:

    1. #!/bin/bash
    2. export NDK_ROOT=/Users/jeffmony/tools/android-ndk-r14b # 修改自己本地的ndk路径
    3. build() {
    4. API=24
    5. ARCH=$1
    6. PLATFORM=$2
    7. SYSROOT=$NDK_ROOT/platforms/android-$API/arch-$ARCH/
    8. CROSS_PREFIX=$NDK_ROOT/toolchains/$PLATFORM-4.9/prebuilt/darwin-x86_64/bin/$PLATFORM-
    9. PREFIX=$(pwd)/android/$ARCH #自己指定一个输出目录
    10. rm -rf $(pwd)/android/$ARCH
    11. echo "开始编译ffmpeg $ARCH so"
    12. ./configure \
    13. --prefix=$PREFIX \
    14. --disable-doc \
    15. --enable-shared \
    16. --disable-static \
    17. --disable-x86asm \
    18. --disable-asm \
    19. --disable-symver \
    20. --disable-devices \
    21. --disable-avdevice \
    22. --enable-gpl \
    23. --disable-ffmpeg \
    24. --disable-ffplay \
    25. --disable-ffprobe \
    26. --enable-small \
    27. --enable-cross-compile \
    28. --cross-prefix=$CROSS_PREFIX \
    29. --target-os=android \
    30. --arch=$ARCH \
    31. --sysroot=$SYSROOT
    32. }
    33. # build armv7a
    34. build arm arm-linux-androideabi
    35. make clean
    36. make -j4
    37. make install
    38. echo "完成ffmpeg $ARCH 编译..."
    39. # build armv8a
    40. build arm64 aarch64-linux-android
    41. make clean
    42. make -j4
    43. make install
    44. echo "完成ffmpeg $ARCH 编译..."

    文末名片免费领取音视频开发学习资料,内容包括(C/C++,Linux 服务器开发,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)以及音视频学习路线图等等。

    生成的目录中./android/arm/include 就是头文件

    复用ijkplayer中的ffmpeg库

    如果项目中使用到了ijkplayer库,也恰好需要使用ffmpeg库的功能,这时候不需要额外引入ffmpeg库了,可以直接使用ijkplayer提供的ffmpeg库,那就需要我们在编译的时候简单改造一下,使得libijkffmpeg.so可以被开发者复用。

     

     主要的操作步骤如下:

    • 新建一个cpp文件夹,将include文件夹拷贝到cpp下面

    • 新建CMakeLists.txt和jeffmony.cpp,jeffmony.cpp就是自定义的native方法

    • 修改build.gradle编译

    build.gradle修改如下:

     

    CMakeLists.txt修改如下:

    1. # For more information about using CMake with Android Studio, read the
    2. # documentation: https://d.android.com/studio/projects/add-native-code.html
    3. # Sets the minimum version of CMake required to build the native library.
    4. cmake_minimum_required(VERSION 3.4.1)
    5. ## libijkffmpeg.so
    6. add_library(ffmpeg SHARED IMPORTED)
    7. set_target_properties(ffmpeg PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI}/libijkffmpeg.so)
    8. include_directories(./include)
    9. # Creates and names a library, sets it as either STATIC
    10. # or SHARED, and provides the relative paths to its source code.
    11. # You can define multiple libraries, and CMake builds them for you.
    12. # Gradle automatically packages shared libraries with your APK.
    13. add_library( # Sets the name of the library.
    14.       jeffmony
    15.        # Sets the library as a shared library.
    16.       SHARED
    17.        # Provides a relative path to your source file(s).
    18.       jeffmony.cpp)
    19. # Searches for a specified prebuilt library and stores the path as a
    20. # variable. Because CMake includes system libraries in the search path by
    21. # default, you only need to specify the name of the public NDK library
    22. # you want to add. CMake verifies that the library exists before
    23. # completing its build.
    24. find_library( # Sets the name of the path variable.
    25.       log-lib
    26.        # Specifies the name of the NDK library that
    27.        # you want CMake to locate.
    28.       log)
    29. # Specifies libraries CMake should link to your target library. You
    30. # can link multiple libraries, such as libraries you define in this
    31. # build script, prebuilt third-party libraries, or system libraries.
    32. target_link_libraries( # Specifies the target library.
    33.       jeffmony
    34.       ffmpeg
    35.        # Links the target library to the log library
    36.        # included in the NDK.
    37.        ${log-lib})

    编译运行,生成了一个libjeffmony.so库。

    具体的项目代码见:github.com/JeffMony/Pl…

    1. ln -s $FF_PREFIX/include $FF_PREFIX/shared/include
    2. ln -s $FF_PREFIX/libijkffmpeg.so $FF_PREFIX/shared/lib/libijkffmpeg.so
    3. cp $FF_PREFIX/lib/pkgconfig/*.pc $FF_PREFIX/shared/lib/pkgconfig
    4. for f in $FF_PREFIX/lib/pkgconfig/*.pc; do
    5.    # in case empty dir
    6.    if [ ! -f $f ]; then
    7.       continue
    8.    fi
    9.    cp $f $FF_PREFIX/shared/lib/pkgconfig
    10.    f=$FF_PREFIX/shared/lib/pkgconfig/`basename $f`
    11.    # OSX sed doesn't have in-place(-i)
    12.   mysedi $f 's/\/output/\/output\/shared/g'
    13.   mysedi $f 's/-lavcodec/-lijkffmpeg/g'
    14.   mysedi $f 's/-lavfilter/-lijkffmpeg/g'
    15.   mysedi $f 's/-lavformat/-lijkffmpeg/g'
    16.   mysedi $f 's/-lavutil/-lijkffmpeg/g'
    17.   mysedi $f 's/-lswresample/-lijkffmpeg/g'
    18.   mysedi $f 's/-lswscale/-lijkffmpeg/g'
    19. done

    可以保证libijkffmpeg的链接顺序是正确的。

    音视频开发中使用ffmpeg的地方非常多, 播放场景/音视频编辑场景, 其中使用到ffmpeg核心模块是共通的, 本文的介绍就是告诉大家, 我们可以将不同的功能模块封在同一个ffmpeg库中, 帮我们节省空间。

  • 相关阅读:
    学习笔记-.net安全之XmlSerializer反序列化
    el-upload 上传附件(拆解步骤)
    TSRFormer: Table Structure Recognition with Transformers ----论文阅读
    Spring Security 在登录时如何添加图形验证码
    记一次生产问题的排查,让我领略了算法的重要性
    按关键字搜索商品详情销量的步骤教学
    Vue中使用组件的三大步骤
    导航 实验【微机原理】【实验】
    【蜂鸟E203内核解析】Chap.2 E203内核中指令执行的过程-为什么E203是两级流水线?
    LeetCode 630. 课程表 III - 优先队列&贪心
  • 原文地址:https://blog.csdn.net/yinshipin007/article/details/128007203