☰
ijkplayer实用链接清单:编译、源码、问题排查一站式导航
2026/10/3 0:59:01 网站建设 项目流程

做移动端播放器这几年,ijkplayer的项目文档被我翻得比自家代码还频繁。刚打开GitHub仓库第一眼看到README,觉得文档少得可怜,然后去Stack Overflow搜一圈,到头来还是回到仓库的Issues列表里一篇翻,最后编译失败只能靠猜。实际上ijkplayer真正有用的链接都埋得很分散,仓库、Wiki、Issues、上游FFmpeg的源码、还有几个周边封装库,缺一块都会绕远路。这篇就是我整理了一阵子的实用链接清单,按场景分类,每个链接标清楚什么时候用、能解决什么问题,适合刚开始接ijkplayer的人,也适合做二次定制的人。

1. 上游仓库:GitHub主仓库不能只盯README

先说最核心的:https://github.com/Bilibili/ijkplayer。很多人只把它当“下载源码的地方”,其实这个README就是一份被低估的官方综合文档。我接手新项目时,第一步永远是打开README,看里面列了哪些目录、哪些脚本、哪些环境依赖。它有一段“Getting Started”会把Android和iOS的编译命令直接贴出来,还有最底部的“Directory Structure”,把android、ios、config、extra每一个目录的职责框出来了。这些信息虽然简单,但比第三方博客可靠得多,因为仓库代码更新时README是跟着改的。

跟主仓库配套的几个页面也要收藏:

链接用途什么时候用
https://github.com/Bilibili/ijkplayer/wiki官方Wiki遇到“不确定某个功能要不要开”“找不到某个option”时优先查这里
https://github.com/Bilibili/ijkplayer/issues官方Issues所有奇怪问题的最终归宿,编译失败、黑屏、播放不了RTMP,这里几乎都有迹可循
https://github.com/Bilibili/ijkplayer/releasesRelease列表想用稳定tag而不是master时,在这里挑版本
https://github.com/Bilibili/ijkplayer/branches分支列表确认自己fork时的基线分支,避免乱跟master

Wiki这个入口特别容易被人忽略。它不像GitBook那种结构,但也收录了不少关键结论,比如不同Android版本下MediaCodec的坑、编译时怎么处理math库、怎么开启OpenSSL。我建议搜索时直接在Wiki里过一遍,没有答案再去Issues。

再说版本选择的问题。ijkplayer的版本策略有点怪:master长期是开发主线,但很多人反馈某几个版本最稳。我自己的经验是,如果你不是要做新特性验证,优先找带tag的稳定版本,不要直接拉master。Releases页面其实很安静,更新不频繁,但每次发版都会把改了什么写清楚,方便在企业项目里固定版本。很多公司做二次开发时,会把“基于master某次commit”写进自己的工程说明,这个commit号就是从Branches页面看来的。

还有一个小技巧:GitHub如果连接不稳定,可以在代码托管平台上搜“ijkplayer”,会看到不少同步镜像。我一般只拿镜像看代码,真正要拉新版本或者发issue还是回上游仓库,因为镜像偶尔会停更,形成“看起来有提交、实际落后几个月”的错觉。

2. 编译工具链:这些前置工具比源码更早拦截你

ijkplayer的编译链路是我见过最容易绊倒新人的地方。很多问题根本不是ijkplayer源码本身的bug,而是工具链版本不对。这里把两端编译要依赖的工具链接整理成一张表,按“缺少它会报什么错”来记。

工具链接作用与典型报错
Android NDKhttps://developer.android.com/ndk/downloads/older_releases编译Android的.so,版本不匹配会出现unknown option之类
Android SDK / Gradlehttps://developer.android.com/studioijkplayer-example要用Android Studio打开
Homebrewhttps://brew.shiOS编译的基本环境,缺了它各种依赖装不上
gas-preprocessor在GitHub搜gas-preprocessorFFmpeg汇编代码需要它预处理,报错一般是“can't find gas-preprocessor”
yasmhttp://yasm.tortall.net/x86汇编编译器,报错yasm not found就是这里
FFmpeg官方源码https://github.com/FFmpeg/FFmpegijkplayer的内核上游,比对FFmpeg版本时用
OpenSSLhttps://github.com/openssl/openssl开启https/ssl播放时的依赖
libyuvhttps://chromium.googlesource.com/libyuv/libyuv/视频帧缩放、旋转、格式转换需要

看到这些链接是不是有点慌?别急,大多数情况下你不需要手动装FFmpeg和OpenSSL,因为ijkplayer的init脚本会帮你拉对应版本的源码。拿Android举例,完整的编译路径是这样的:

git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-android cd ijkplayer-android ./init-android.sh ./compile-ffmpeg.sh clean ./compile-ffmpeg.sh armv7a ./compile-ijkplayer.sh armv7a

iOS侧更简单,换成init-ios.sh,然后compile-ffmpeg.sh按arm64、x86_64编译,最后compile-ijkplayer.sh打包framework。

但这些脚本有个共同的脾气:对NDK版本非常敏感。老版本的ijkplayer脚本用的还是NDK r10e这代,新一点的版本对r13b、r17也有依赖。如果你一上来装最新的NDK r25,编译多半会报一串奇奇怪怪的错误,比如gcc预编译头文件找不到、inline函数冲突。不要硬刚,优先看Issues里的“NDK”标题,解决思路一般就是“切回README里推荐的那版NDK”。

再说config/module.sh这个文件。它藏在config目录下,作用是控制FFmpeg编译了哪些模块、开启了哪些功能。很多人不知道,编译之前先打开module.sh看注释,里面写得很清楚:你要精简包体积就把不用的demuxer、decoder注释掉;你要支持rtmp,得确认开启了网络协议;你要https得把OpenSSL打开。这个文件的链接在 https://github.com/Bilibili/ijkplayer/blob/master/config/module.sh ,fork之后改它是最常见的二次开发起点。

实测下来,编译遇到问题的概率排序大概是:NDK版本 > 汇编工具缺失 > 脚本权限 > 网络拉源码失败。前两类靠上面的工具链接就能解决,脚本权限跑一下chmod +x *.sh,网络拉源码失败就多试几次或换镜像,这些都是老玩家见怪不怪的坑。

3. 源码即文档:Android与iOS侧最该收藏的代码链接

很多开发者把ijkplayer当黑盒用,实际上它的源码写得相当直白,注释也全。与其去各种博客猜API,还不如直接把源码当成文档读。Android侧我最常收藏的是:

  • https://github.com/Bilibili/ijkplayer/blob/master/android/ijkplayer-java/src/main/java/tv/danmaku/ijk/media/player/IjkMediaPlayer.java
  • https://github.com/Bilibili/ijkplayer/blob/master/android/ijkplayer-java/src/main/java/tv/danmaku/ijk/media/player/IjkMediaMeta.java
  • https://github.com/Bilibili/ijkplayer/blob/master/android/ijkplayer-java/src/main/java/tv/danmaku/ijk/media/player/IjkMediaCodecInfo.java

IjkMediaPlayer是所有Native调用的门面。你用到的setOption、setVolume、setSpeed、prepareAsync、setSurface全在这里。尤其是setOption的三个参数,第一参数用OPT_CATEGORY_PLAYER、OPT_CATEGORY_FORMAT还是OPT_CATEGORY_CODEC,很多人的困惑点,打开源码一看就全明白了。比如:

IjkMediaPlayer player = new IjkMediaPlayer(context); player.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 0); player.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "timeout", 20000000);

第一行让播放器不要自动进入准备完成状态,等你自己控制播放时机;第二行给底层连接设置20秒超时。这些option在README和Wiki里只零散提到一两个,但源码里能看到完整的分类和常量风格。

IjkMediaMeta则定义了播放信息里的常量。比如播放器通过getMediaInfo返回的键值对,meta里的MEDIA_KEY_CODEC_NAME、MEDIA_KEY_START_TIME等,都在这个文件里。排查“为什么拿到播放时长不对”“为什么拿不到分辨率”这类问题时,直接在这里搜key对应关系,比调试日志更快。

IjkMediaCodecInfo是硬解适配的核心。不同机型、不同GPU对MediaCodec的支持千差万别,这个类里保存了一套编解码器信息匹配逻辑。想搞明白为什么某台机器硬解黑屏、硬解不支持H.264高帧率,就认真看它。

iOS侧的思路一样,重点是IJKMediaPlayback.h和IJKFFMoviePlayerController.h。这两个头文件在仓库里的位置相对隐蔽,我一般直接在主仓库的搜索框里输文件名定位。它们定义了iOS播放器的状态回调、prepareToPlay/play/pause/shutdown这些生命周期,以及player options怎么透传到底层。iOS侧封装的痛处主要在于ffmpeg库版本跟Xcode版本打架,头文件里能查的调用方式是最权威的。

官方Demo也别忘:

  • Android侧:https://github.com/Bilibili/ijkplayer/tree/master/android/ijkplayer-example
  • iOS侧:https://github.com/Bilibili/ijkplayer/tree/master/ios/IJKMediaDemo

这两个demo不是花架子,它们把ijkplayer的option配置、硬解软解切换、音频通道选择、外挂字幕都展示了一遍。我做过不少从demo往自己项目里“搬家”的操作,比如把demo里的列表播放结构抄到自己的播放器壳子里,再改成真正的业务逻辑。强烈建议新同学先跑通demo,再动手改自己的胶水代码。

4. 二次定制的常用起点:封装库与上游依赖链接

如果你不是要改内核,而是要赶业务上线,建议直接站在封装库的肩膀上。ijkplayer生态里最活跃的一个封装库是GSYVideoPlayer:https://github.com/CarGuo/GSYVideoPlayer。

GSYVideoPlayer严格说是个播放器框架,它把ijkplayer、ExoPlayer、系统MediaPlayer三种内核做成可切换模式,抽出了手势、清晰度切换、列表播放、缓存这些通用能力。很多公司项目里看到“基于GSY改的视频SDK”,就是因为省事。我在实际项目中用这个库解决过“播放器UI和进度条逻辑重复造轮子”的问题,它的SampleActivity几乎能当半个产品原型。不过要提醒一下,GSY对ijkplayer的版本选择有自己的逻辑,你最终打出来的so不一定跟官方README完全一致,所以真要深挖问题,还是得回到上游源码里对照。

同类里还可以收藏:

项目链接定位
DKVideoPlayerhttps://github.com/Doikki/DKVideoPlayer轻量级播放器封装,适合快速集成UI
JiaoZiVideoPlayerhttps://github.com/lipangit/JiaoZiVideoPlayer老牌的全屏播放器,历史代码多,可参考但不推荐新项目直接用
ExoPlayer / Media3https://github.com/androidx/media谷歌官方的现代播放方案,不是ijkplayer,但经常被拿来对比选型
DanmakuFlameMasterhttps://github.com/bilibili/DanmakuFlameMaster哔哩哔哩自家的弹幕库,经常和ijkplayer一起出现在视频播放器SDK里

这里我加一句个人看法:封装库的代码质量参差不齐,有的封装库只改了UI层,底层ijkplayer还停留在三年前的commit。你把它当黑盒接入时很爽,一旦出了诡异问题,排查成本非常高。所以我一般建议:如果业务要求不高,接GSY这种活跃项目;如果要对播放内核做深度控制,不如直接从官方ijkplayer fork一条线,自己维护一个薄薄的UI壳。链接收藏再多,都不如真正纠结过一次编译和一次黑屏问题来得深刻。

还有一个方向是上游依赖的代码查看方式。你在ijkplayer的init脚本里会看到它会clone一份FFmpeg源码到extra/ffmpeg目录。这本来是个隐藏的“源码文档”——你在播放器里遇到的解封装、解码、滤镜问题,最终都要去FFmpeg源码里挖。把FFmpeg官方仓库收藏起来,按ijkplayer使用的版本tag对照看得更准。OpenSSL和libyuv同理,都是底层依赖,平时不碰,碰到https播放黑屏、视频画面旋转不对时就知道它们多重要了。

5. 问题定位直接搜Issues:这个检索入口就是官方教案

ijkplayer最大的文档其实是Issues。这话不是说它文档烂,恰恰相反,Issues里每一类问题都有前人在里面贴日志、贴命令、贴结论。问题是我发现很多新人不会搜。

推荐几个可以直接点击的搜索入口:

  • 硬解相关:https://github.com/Bilibili/ijkplayer/issues?q=is%3Aissue+mediacodec
  • 音频延迟:https://github.com/Bilibili/ijkplayer/issues?q=is%3Aissue+audio+delay
  • 编译失败:https://github.com/Bilibili/ijkplayer/issues?q=is%3Aissue+fail+ndk
  • RTMP直播:https://github.com/Bilibili/ijkplayer/issues?q=is%3Aissue+rtmp
  • HTTPS证书:https://github.com/Bilibili/ijkplayer/issues?q=is%3Aissue+openssl

这种issues?q=is:issue+关键词的链接我保存了很多个,比全网搜索要精准,因为里面说话的确实都是实际编译、实际跑过播放器的人。比如hardware decode和black screen经常是连在一起的,搜“black”就能看到一堆不同Android机型的结论:有的是因为TextureView时序,有的是因为MediaCodec不支持某个profile,有的是因为外部rotation没有处理。这些结论通常还附带还原现场的方法,直接照做验证就行。

我自己排查播放问题的标准流程是:拿到问题描述,先在Issues里搜大分类关键词(黑屏、音画不同步、rtmp、ssl、seek),再组合“机型/分辨率/ffmpeg版本”这些条件缩小范围。如果搜不到完全一样的,就搜底层关键字,比如播放出错时把IjkMediaMeta里的codec name捞出来,搜那个codec名。

另外一个容易被忽视的是发issue的模板。你在 https://github.com/Bilibili/ijkplayer/issues/new 这个页面新建issue时,仓库维护者其实希望你把环境信息写全:操作系统、NDK版本、ijkplayer的commit、播放地址、完整日志。很多人进来直接说“xx播放失败”,基本得不到有用反馈。我后来养成的习惯是,准备发issue前自己先做一轮信息整理,日志截全,播放地址带上,这样即使最后没等到官方答复,整理过程本身也会把问题定位到更细。

这里再分享一个实用技巧:把ffplay或ffprobe(FFmpeg自带的命令行工具)作为“对照实验”。播放器出问题时,先用ffplay在PC上播放同样的地址,如果ffplay也播不了,问题大概率在FFmpeg解析/网络层;如果ffplay能播,那就聚焦在ijkplayer的硬解分支或Java层状态。这条思路帮我快速砍掉过一半的无效排查。

6. 一串链接的真实使用顺序:实际项目里我这样走

链接整理完了,但如果直接丢给你,效果也就比收藏吃灰好一点。最后按自己的使用顺序把上面这些链接串一遍。

场景一,新项目要接ijkplayer:

  1. 打开主仓库README,把编译命令复制下来。
  2. 跑init脚本前,先打开config/module.sh,看清楚要开哪些功能。
  3. 用官方android/ijkplayer-example跑demo,确认你的环境能正常拉到FFmpeg源码。
  4. demo成功后,再对照IjkMediaPlayer.java源码做自己的接口封装。
  5. 需要UI和手势就直接评估GSYVideoPlayer,不需要就自己写壳。
  6. 任何一步卡住,按编译错误去Issues搜,不要憋着。
  7. 编译完,把NDK版本、编译命令、module.sh的diff记录到自己的工程文档里。

场景二,线上播放出了诡异问题:

  1. 先复现,把出错时间和播放地址记下来。
  2. 去Issues搜现象关键词:黑屏、卡顿、音画不同步、rtmp中断。
  3. 如果现象集中在某个机型,去IjkMediaCodecInfo.java和IjkMediaMeta.java看codec匹配信息。
  4. 把硬解切换成软解,确认是不是硬解分支的问题。
  5. 回到播放器option设置,调整超时、缓存和自动播放策略。
  6. 还解决不了,用ffplay做对照,缩小到FFmpeg内核还是Java层。
  7. 最后实在不行再开issue,附完整环境信息和日志。

这些步骤里的每一个锚点都对应前面提到的链接,跑完一轮,你对ijkplayer的熟悉程度会比看十篇博客都强。

最后一组链接建议:把上面这些网址按“源码、编译、API、封装库、排查”五个分类放在浏览器书签里,或者存成一份本地Markdown。ijkplayer本身更新不快,但它的生态周边变化很快,尤其是GSY这类库,半年不看可能API都变了一轮。所以每次启动项目前,先快速刷新一下相关仓库的releases页,再看自己fork的基线commit是否落后太多。

我在实际项目里踩过最深的坑,就是盯着三年前的编译笔记,拿新版NDK硬编,结果花了整整一个下午在“unknown option”和“undefined symbol”中间转圈。后来养成了“先看工具链、再动代码”的习惯,这类低级问题基本绝迹。这份链接清单不是什么黑科技,就是把本该是常识的资源整理顺了,希望它能让你少走几个小时弯路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询