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

Posted 音视频开发老马

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何复用ijkplayer库实现ffmpeg的功能相关的知识,希望对你有一定的参考价值。

ijkplayer库介绍

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

jeffmony@JeffMonydeMacBook-Pro arm64-v8a % ls -hl
total 21240
-rwxr-xr-x  1 jeffmony  staff   9.6M  4 30 00:25 libijkffmpeg.so
-rwxr-xr-x  1 jeffmony  staff   348K  4 30 00:25 libijkplayer.so
-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如下:

#!/bin/bash
export NDK_ROOT=/Users/jeffmony/tools/android-ndk-r14b # 修改自己本地的ndk路径
​
build() 
API=24
ARCH=$1
PLATFORM=$2
SYSROOT=$NDK_ROOT/platforms/android-$API/arch-$ARCH/
CROSS_PREFIX=$NDK_ROOT/toolchains/$PLATFORM-4.9/prebuilt/darwin-x86_64/bin/$PLATFORM-
PREFIX=$(pwd)/android/$ARCH #自己指定一个输出目录
rm -rf $(pwd)/android/$ARCH
​
echo "开始编译ffmpeg $ARCH so"
./configure \\
--prefix=$PREFIX \\
--disable-doc \\
--enable-shared \\
--disable-static \\
--disable-x86asm \\
--disable-asm \\
--disable-symver \\
--disable-devices \\
--disable-avdevice \\
--enable-gpl \\
--disable-ffmpeg \\
--disable-ffplay \\
--disable-ffprobe \\
--enable-small \\
--enable-cross-compile \\
--cross-prefix=$CROSS_PREFIX \\
--target-os=android \\
--arch=$ARCH \\
--sysroot=$SYSROOT

​
# build armv7a
build arm arm-linux-androideabi
make clean
make -j4
make install
​
echo "完成ffmpeg $ARCH 编译..."
​
​
# build armv8a
build arm64 aarch64-linux-android
make clean
make -j4
make install
​
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修改如下:

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
​
# Sets the minimum version of CMake required to build the native library.
​
cmake_minimum_required(VERSION 3.4.1)
​
## libijkffmpeg.so
add_library(ffmpeg SHARED IMPORTED)
set_target_properties(ffmpeg PROPERTIES IMPORTED_LOCATION $PROJECT_SOURCE_DIR/../jniLibs/$ANDROID_ABI/libijkffmpeg.so)
​
include_directories(./include)
​
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
​
add_library( # Sets the name of the library.
        jeffmony
​
        # Sets the library as a shared library.
        SHARED
​
        # Provides a relative path to your source file(s).
        jeffmony.cpp)
​
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
​
find_library( # Sets the name of the path variable.
        log-lib
​
        # Specifies the name of the NDK library that
        # you want CMake to locate.
        log)
​
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
​
target_link_libraries( # Specifies the target library.
        jeffmony
        ffmpeg
        # Links the target library to the log library
        # included in the NDK.
        $log-lib)

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

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

ln -s $FF_PREFIX/include $FF_PREFIX/shared/include
ln -s $FF_PREFIX/libijkffmpeg.so $FF_PREFIX/shared/lib/libijkffmpeg.so
cp $FF_PREFIX/lib/pkgconfig/*.pc $FF_PREFIX/shared/lib/pkgconfig
for f in $FF_PREFIX/lib/pkgconfig/*.pc; do
    # in case empty dir
    if [ ! -f $f ]; then
        continue
    fi
    cp $f $FF_PREFIX/shared/lib/pkgconfig
    f=$FF_PREFIX/shared/lib/pkgconfig/`basename $f`
    # OSX sed doesn't have in-place(-i)
    mysedi $f 's/\\/output/\\/output\\/shared/g'
    mysedi $f 's/-lavcodec/-lijkffmpeg/g'
    mysedi $f 's/-lavfilter/-lijkffmpeg/g'
    mysedi $f 's/-lavformat/-lijkffmpeg/g'
    mysedi $f 's/-lavutil/-lijkffmpeg/g'
    mysedi $f 's/-lswresample/-lijkffmpeg/g'
    mysedi $f 's/-lswscale/-lijkffmpeg/g'
done

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

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

直播技术总结ijkplayer的编译到Android平台并测试解码库

转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/55670380

前言:ijkplayer,是b站工程师开源的播放器框架,基于FFmpeg及MediaCodec,内部实现软解及硬解的功能,对于没有自研底层播放器的公司,用它确实是比较合适了。关于介绍可以直接看:https://github.com/Bilibili/ijkplayer,今天主要是对ijkplayer进行编译在Android平台上运行。

首先看下效果图:
gif图如下:


这里写图片描述

编译过程:在mac上进行编译这个库
先clone一份源码到本地:

git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-android
cd ijkplayer-android
git checkout -B latest k0.7.7.1 #最新分支

这里写图片描述

这里写图片描述

编译ffmpeg

./init-android.sh  # 初始化ijkplayer中和android相关,如果是在iOS,这是就是./init-ios.sh

cd android/contrib
./compile-ffmpeg.sh clean
./compile-ffmpeg.sh all #编译ffmpeg

这里写图片描述

囧,发现pro上没有配置ndk环境。

这里写图片描述

下载ndk,还好在《手把手图文并茂教你用Android Studio编译FFmpeg库并移植》中,我把ndk-10e存到云盘中。

  • 供参考下载地址见本文最下面,也可自行下载。
  • 用命令 ./android-ndk-r10e-mac-x86_64.bin,就可进行进行解压,如下图:

这里写图片描述

不过并没有这么顺利, 在解压过程中出现Permission denied。
这时要改下权限,执行命令 chmod a+x ./android-ndk-r10e-mac-x86_64.bin

这里写图片描述

配置ndk环境

  • 启动终端Terminal
  • 进入当前用户的home目录
    • 输入cd ~ 或 /Users/YourUserName
  • 创建.bash_profile
  • 输入touch .bash_profile
  • 编辑.bash_profile文件

  • 输入open -e .bash_profile
    因为是为了配置NDK开发环境,输入Android NDK下目录,前面是android sdk的,可以不用动它,最终.bash_profile文件如下:

export PATH=$PATH:/Users/hejunlin/Documents/local/apache-tomcat-7.0.72/bin

export PATH=${PATH}:/Users/hejunlin/Library/Android/sdk/tools
export PATH=${PATH}:/Users/hejunlin/Library/Android/sdk/platform-tools

export NDK_ROOT=/Users/hejunlin/AndroidStudioProjects/android-ndk-r10e
export PATH=$PATH:$NDK_ROOT

#for ijkplayer
export ANDROID_SDK=${PATH}:/Users/hejunlin/Library/Android/sdk
export ANDROID_NDK=${PATH}:/Users/hejunlin/AndroidStudioProjects/android-ndk-r10e

这里写图片描述

  • 保存文件,关闭.bash_profile
  • 更新刚配置的环境变量
    • 输入source .bash_profile,让刚长配置生效

ndk-build测试

  • 找到ndk-10e中sample目录,cd hello-jni中,执扫命令ndk-build。就会出现如下所示:

这里写图片描述

重新回到编译ffmpeg的过程:
依旧执行:./compile-ffmpeg.sh all,得到如下所示
这里写图片描述
本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/55670380

编译结束时如下:

这里写图片描述

最终,在crontrib目录下,会出现编译so所需要的各平台文件,如arm,x86。也可以指定平台,编译。

这里写图片描述

最后执行如下命令,让ijkplayer和ffmpeg打成so库及demo工程:

cd ..
./compile-ijk.sh all

这里写图片描述

执行完毕后,就会出现一个ijkplayer文件夹,为studio工程,里面包含各平台so库。导入android studio,就可以运行demo工程。

这里写图片描述

导入Android Studio,example工程运行到模拟器上:

这里写图片描述

点击Sample,进入播放测试

这里写图片描述

最后我们编译它,不是用来看看demo就完了的。我们可以改c代码,并且按如上方式重新编译成so库,如果要在其他工程中使用的话。xml中引用如下:

<tv.danmaku.ijk.media.example.widget.media.IjkVideoView
            android:id="@+id/video_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center"/>

在你的Java代码中加入如下一些初始化条件就可以啦。

 videoView = (IjkVideoView) findViewById(R.id.videoview);
        // init player
IjkMediaPlayer.loadLibrariesOnce(null);
        IjkMediaPlayer.native_profileBegin("libijkplayer.so");
videoView.setVideoURI(Uri.parse(mUrl));

videoView.setOnPreparedListener(new IMediaPlayer.OnPreparedListener() {
      @Override
      public void onPrepared(IMediaPlayer mp) {
           videoView.start();
      }
});

第一时间获得博客更新提醒,以及更多android干货,源码分析,欢迎关注我的微信公众号,扫一扫下方二维码或者长按识别二维码,即可关注。

这里写图片描述
如果你觉得好,随手点赞,也是对笔者的肯定,也可以分享此公众号给你更多的人,原创不易

以上是关于如何复用ijkplayer库实现ffmpeg的功能的主要内容,如果未能解决你的问题,请参考以下文章

IJKPlayer集成直播拉流播放

Ubuntu编译ijkplayer so库并播放本地raw/assets文件

Ubuntu编译ijkplayer so库并播放本地raw/assets文件

Ubuntu编译ijkplayer so库并播放本地raw/assets文件

ijkplayer编译 Android 版本的 ijkplayer ④ ( 安装 make yasm 软件 | 执行 compile-ffmpeg.sh all 命令编译 ffmpeg )

ijkplayer编译 Android 版本的 ijkplayer ③ ( 执行 compile-ffmpeg.sh clean 命令 | 下载并配置 android-ndk-r10e )