Android下用ijkPlayer播放rtsp视频流编译so文件

前言

这两天被这个ijkplayer、rtsp视频流搞的我甚至有点喜欢他们了。上一篇博客配置mac的环境变量,就是要在这篇编译so文件的时候使用NDK,所以没有配置好环境变量的可以去看一下上一篇博客

一、用什么去播放rtsp视频流

我在这里选用的是郭哥封装好的一个很棒的视频播放器GSYVideoPlayer,这是一款基于ijkplayer实现了多功能的视频播放器,感兴趣的可以去学习一下。
大家都知道bilibili出品的ijkplayer播放器吧。
没错,郭哥就是站在了巨人的肩膀上对它进行了封装,让我们更好的运用达到自己的要求。
无奈的是ijkplayer本身的使用环境也不是特别为这个实时输出而生的,所以需要我们自己去量身定做一下,那我们开始吧。

二、在构建之前我们要部署环境

  • 在构建之前我们要部署环境

    1
    2
    3
    4
    # install homebrew, git, yasm
    ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
    brew install git
    brew install yasm
  • 下载ijkplayer-android源码

    1
    git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-android

    下载完源码图片

  • 修改module-lite.sh文件

    1
    2
    3
    export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-protocol=rtp"
    export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-demuxer=rtsp"
    export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-protocol=tcp"

    记得那个rtp是将disable改成了enable,然后在后面添加下面的两个rtsp和tcp

  • 修改ff_ffplay.c文件

    ijkmedia -> ijkplayer -> ff_ffplay.c

将下列代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
static int packet_queue_get_or_buffering(FFPlayer *ffp, PacketQueue *q, AVPacket *pkt, int *serial, int *finished)
{
assert(finished);
if (!ffp->packet_buffering)
return packet_queue_get(q, pkt, 1, serial);
while (1) {
int new_packet = packet_queue_get(q, pkt, 0, serial);
if (new_packet < 0)
return -1;
else if (new_packet == 0) {
if (q->is_buffer_indicator && !*finished)
ffp_toggle_buffering(ffp, 1);
new_packet = packet_queue_get(q, pkt, 1, serial);
if (new_packet < 0)
return -1;
}
if (*finished == *serial) {
av_packet_unref(pkt);
continue;
}
else
break;
}
return 1;
}
修改为下面的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
static int packet_queue_get_or_buffering(FFPlayer *ffp, PacketQueue *q, AVPacket *pkt, int *serial, int finished)
{
while (1) {
int new_packet = packet_queue_get(q, pkt, 1, serial);
if (new_packet < 0)
{
new_packet = packet_queue_get(q, pkt, 0, serial);
if(new_packet < 0)
return -1;
} else if (new_packet == 0) {
if (!finished)
ffp_toggle_buffering(ffp, 1);
new_packet = packet_queue_get(q, pkt, 1, serial);
if (new_packet < 0)
return -1;
}
if (finished == *serial) {
av_free_packet(pkt);
continue;
}
else
break;
}
return 1;
}
  • 接下来就是在iTerm中操作了

我们切换到下载好的源码目录中,并且换分支,你也可以在master,当然这个latest是官方推荐的。

1
2
cd ijkplayer-android
git checkout -B latest k0.8.0
  • 编译前选择配置,一般我们都会选择size最小的
1
2
3
4
//If you prefer less codec/format for smaller binary size (include hevc function)
cd config
rm module.sh
ln -s module-lite-hevc.sh module.sh
  • 初始化FFmpeg,这里会下载源码,需要一段时间
1
2
cd ~/ijkplayer-android
./init-android.sh
  • 接下来就是编译
1
2
3
cd android/contrib
./compile-ffmpeg.sh clean //清除
./compile-ffmpeg.sh all //编译

编译需要同样也是很费时的,但是这里有一个要注意的点,当你输入指令去编译的时候,他
有时会提醒你找不到NDK或者让你去配置NDK的环境,但是你明明之前已经配过了,所以你不要慌,输入下面的指令

1
2
cd //切换到跟目录下,就像你刚打开iTerm那个目录一样
source .bash_profile //更新你的环境变量

然后呢,你在输入编译的指令,它就能很听话的编译了。

  • 生成so文件

这是最后一步了,坚持就是胜利。
切换到android目录下,执行命令生成so文件,就大功告成了

./compile-ijk.sh all

生成so文件之后,我们去对应的文件夹找到并把他们放在你项目的libs下,如下图:

so文件

  • gradle配置
1
2
3
4
5
sourceSets{
main{
jniLibs.srcDirs = ['libs']
}
}

参考:

IJKPlayer编译so支持HTTPS的踩坑历程

https://github.com/Bilibili/ijkplayer

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器