码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 基于 FFmpeg 的跨平台视频播放器简明教程(十):在 Android 运行 FFmpeg


    系列文章目录

    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
    • 2
    1. 设置环境变量
    export ANDROID_SDK_HOME=/Users/user/Library/Android/sdk
    export ANDROID_NDK_HOME=/Users/user/Library/Android/sdk/ndk/25.2.9519653
    
    • 1
    • 2
    1. 运行脚本
    ./ffmpeg-android-maker.sh
    
    • 1

    编译成功后,你可以在当前文件夹的 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    其中 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    写 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
    
    • 1

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

    #include 
    #include 
    extern "C"
    {
    #include 
    }
    
    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());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

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

    binding.sampleText.text = stringFromFFMPEG()
    
    • 1

    最终呈现的效果如下图:
    在这里插入图片描述

    总结

    本文介绍了一种非常便捷的编译 android ffmpeg 的方法:ffmpeg-android-maker。说明如何将 ffmpeg so 库导入至 android 项目中,并提供了实例代码(代码地址:这里)

    参考

    • JNI 简明教程之手把手教你入门
    • CompilationGuide/Android
    • 现代 CMake 简明教程(一)- CMake 基础
  • 相关阅读:
    学习c++的第十天
    【LeetCode】54、螺旋矩阵
    从Spring源码探究IOC初始化流程
    Exoplayer异常:4003, MediaCodecAudioRenderer error,format_supported=YES
    2023/10/7 -- ARM
    Hi3861 OpenHarmony嵌入式应用入门--点灯
    易基因|DNA甲基化揭示应激反应影响婴儿免疫相关基因的表观遗传调控机制 | 表观发育
    【Java面向对象】封装的认识与实现
    52.seata分布式事务
    国外芯片,为什么有中文资料和网页?
  • 原文地址:https://blog.csdn.net/weiwei9363/article/details/134027655
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号