系列文章目录

  1. 根据 FFmpeg 的跨渠道视频播映器简明教程(一):FFMPEG + Conan 环境集成
  2. 根据 FFmpeg 的跨渠道视频播映器简明教程(二):根底常识宽和封装(demux)
  3. 根据 FFmpeg 的跨渠道视频播映器简明教程(三):视频解码
  4. 根据 FFmpeg 的跨渠道视频播映器简明教程(四):像素格局与格局转换
  5. 根据 FFmpeg 的跨渠道视频播映器简明教程(五):运用 SDL 播映视频
  6. 根据 FFmpeg 的跨渠道视频播映器简明教程(六):运用 SDL 播映音频和视频
  7. 根据 FFmpeg 的跨渠道视频播映器简明教程(七):运用多线程解码视频和音频
  8. 根据 FFmpeg 的跨渠道视频播映器简明教程(八):音画同步
  9. 根据 FFmpeg 的跨渠道视频播映器简明教程(九):Seek 战略

前言

在前九章的学习中,咱们已经成功地实现了一个根底的播映器,它拥有视频播映、音画同步、快进/快退等基本功用。当然,这个简易的示例还有许多能够优化的地方,比方添加更漂亮的用户界面,或许增加字幕功用等。然而,这并不是本教程的主要关注点。本系列文章更关注于跨渠道播映器结构的构建,特别是在移动端。因此,从本章开端,咱们将把要点转向 Android 端播映器的开发。

前置常识包括一些 Android 的基本开发,以及 JNI 开发等。这些前置常识默许你有所了解,本文不会涉及。关于 JNI 能够参阅笔者之前写的 JNI 简明教程之手把手教你入门

本文代码在 android/tutorial01

FFmpeg Android 编译

FFmpeg 的跨端编译也是陈词滥调的话题了,本文不去评论那些细节问题,只想供给一种最快捷的编译方法。在 CompilationGuide/Android 中给出了一些指导意见,例如直接运用已经编译好的 so,或许运用别人写好的脚本。对比了这几个方法,ffmpeg-android-maker 比较适宜,优势包括:

  1. 网上那些已经编译好的 ffmpeg so,ffmepg 版别或许太老了。ffmpeg-android-maker 则是从源码直接编译
  2. ffmpeg-android-maker 能够自动拉取 ffmpeg 源码,只需求设置少量的变量就能开端编译
  3. ffmpeg-android-maker 功用、文档写的比较清楚,用起来没有卡点。

那么根据 ffmpeg-android-maker 要怎么编译 android ffmpeg 呢?十分简单,步骤如下。

  1. 下载 ffmpeg-android-marker 仓库
git clone git@github.com:Javernaut/ffmpeg-android-maker.git
cd ffmpeg-android-maker
  1. 设置环境变量
export ANDROID_SDK_HOME=/Users/user/Library/Android/sdk
export ANDROID_NDK_HOME=/Users/user/Library/Android/sdk/ndk/25.2.9519653
  1. 运转脚本
./ffmpeg-android-maker.sh

编译成功后,你能够在当前文件夹的 build 目录下找到各个架构的 ffmpeg 库:

build
└── ffmpeg
    ├── arm64-v8a
    │   ├── bin
    │   ├── include
    │   ├── lib
    │   └── share
    ├── armeabi-v7a
    │   ├── bin
    │   ├── include
    │   ├── lib
    │   └── share
    ├── x86
    │   ├── bin
    │   ├── include
    │   ├── lib
    │   └── share
    └── x86_64
        ├── bin
        ├── include
        ├── lib
        └── share

其间 include 和 lib 是咱们需求的。

FFmpeg so 导入 Android 项目

将 so 文件放置在正确的方位

第一步当然是将编译好的 ffmpeg so 文件和头文件复制到咱们的项目中。在编译产物中,咱们只需求 include 和 lib 文件夹即可,将它们复制至 3rdparty/ffmpeg/android 目录下。当然你也能够挑选其他地方,这仅仅我个人的挑选。

android
├── arm64-v8a
│   ├── include
│   └── lib
├── armeabi-v7a
│   ├── include
│   └── lib
├── x86
│   ├── include
│   └── lib
└── x86_64
    ├── include
    └── lib

写 CMake 将 FFmpeg so 引入项目

ffmpeg 有多个 so 文件,在编译项目的过程中,假如一个一个地去写 link 指令有点费事。一般的做法是,创建一个新的 library,例如叫 ffmpeg_libs,让 ffmpeg_libs 去 link 这些 so 文件,然后其他模块 link ffmpeg_libs 就能够链式地将所有依靠都带上了。

这部分属于 CMake 的常识领域,不细说了,能够参阅笔者之前写的 现代 CMake 简明教程(一)- CMake 根底。具体 CMake 源码在 CMakeLists.txt 大家自己看。

Kotlin 和 JNI 调用 FFmpeg API

Android app 想要调用 C/C++ 的接口就必须通过 JNI 接口来实现。首先,在应用层界说一个 native method 叫 stringFromFFMPEG

external fun stringFromFFMPEG(): String

接着界说 JNI 层接口,新建 src/cpp/native-lib.cpp 文件,并完成 JNI 层代码:

#include <jni.h>
#include <string>
extern "C"
{
#include <libavutil/avutil.h>
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_test_tutorial01_MainActivity_stringFromFFMPEG(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from ffmpeg: " + std::string(av_version_info());
    return env->NewStringUTF(hello.c_str());
}

最后,咱们将 UI 上的 TextView 中的字符串内容修改为这个函数的返回值即可:

binding.sampleText.text = stringFromFFMPEG()

终究呈现的效果如下图:

根据 FFmpeg 的跨渠道视频播映器简明教程(十):在 Android 运转 FFmpeg

总结

本文介绍了一种十分快捷的编译 android ffmpeg 的方法:ffmpeg-android-maker。阐明怎么将 ffmpeg so 库导入至 android 项目中,并供给了实例代码(代码地址这儿

参阅