Skip to content

IJKPlayer Concat #58

Open
Open
@alwaystest

Description

@alwaystest

IJKPlayer Concat

标签(空格分隔): Android IJKPlayer


网上搜索IJKPlayer的相关资料,发现很难找到Android上的IJKPlayer完整的集成文档,连Github的Repo中都找不到详细的描述,大家都说用法和MediaPlayer相似,直接上手用就可以了。然后就花了好多时间来研究这个Lib。

首先,IJKPlayer和ExoPlayer简单对比一下,IJKPlayer基于FFmpeg,ExoPlayer依赖的是Android中的Low Level Media APIs(API Level 16+)。两个Lib都提供了简单的Demo介绍使用方法。ExoPlayer提供的文档信息更为详细一些,还有API Docs提供,ExoPlayer的API使用我个人感觉更为方便简单。

粗略了瞄了一下ExoPlayer的代码,看起来是蛮简单易懂的,但是如果要实现Customize,还是有点难度,比如我不想用他提供的ConcatenatingMediaSource,想自己实现一个的时候,就感到有困难了,主要是我水平姿势不够,里面有DataSource,MediaSource,TrackSelector,LoadControl各种概念要想搞明白还是需要精读代码的。

ExoPlayer的源码解析文章好多都是基于1.x版本的,目前ExoPlayer已经到了2.x版本,感觉用的人不是很多的样子,国内使用的开源方案大部分还是IJKPlayer,但是文档什么的,真的是噩梦一样啊。

说一说IJKPlayer使用FFmpeg的concat功能。

首先ffmpeg.org给出了使用concat功能的一些知识点,首先,我们需要知道

‘ffconcat’
Generate an ffconcat file for the created segments. The resulting file can be read using the FFmpeg concat demuxer.

A list file with the suffix ".ffcat" or ".ffconcat" will auto-select this format.

要使用concat这个demuxer,我们需要一个.ffcator.ffconcat结尾的文件。文件内容需要符合知识点里面的Syntax部分。所以我们大概就有了这么一个文件。

lalala.ffcat

ffconcat version 1.0

file file-1.wav
duration 20.0

file subdir/file-2.wav

这里给出的是ffmpeg官方的Example。当然如果是用在Android里面,鬼知道相对路径会在什么地方(反正我是不知道),所以路径上我选择使用绝对路径。至于那个duration,根据官方文档,说是所有的file段都加了以后可以实现整个concat之后视频文件的seek功能,这不重要,我们现在的目标是让它能运行起来。

绝对路径eg:

file '/storage/emulated/0/Download/PrisonBreakS05E04.mp4'

为什么说目的是让它运行起来呢,因为现在还不能运行起来啊。

根据文档,ffconcat version 1.0的效果

It also sets the safe option to 1 if it was -1.

至于为什么要加ffconcat version 1.0,因为我看大家写的文章都加了,所以我也加了,具体作用官方知识点有说明,因为急于搞定播放这个事情,make FFmpeg recognize the format automatically这里我就先跳过了,视频format的东西,不知道跳进坑里面爬出来需要多久,之前折腾PotPlayer的时候就看过那些巨复杂的设置,妈蛋你看个视频而已,折腾那么半天,各种参数调啊调,累不累?反正我是近视加散光。。。没有蓝光播放器什么的,暂时也用不着那么挑剔。反正目测是个大坑,先不跳了。

safe

If set to 1, reject unsafe file paths. A file path is considered safe if it does not contain a protocol specification and is relative and all components only contain characters from the portable character set (letters, digits, period, underscore and hyphen) and have no period at the beginning of a component.

If set to 0, any file name is accepted.

The default is 1.

-1 is equivalent to 1 if the format was automatically probed and 0 otherwise.

所以我们用了绝对路径,就要想办法让safe这个参数为0。

这里有个家伙简单粗暴的通过修改源码的办法解决了这件事情。简书

通过Google,翻阅Issue,终于找到了优雅的方式,其实IJKPlayer是提供了API来修改这个参数的。

首先IJKPlayer提供的Example中VideoActivity使用了tv.danmaku.ijk.media.example.widget.media.IjkVideoView这么是个自定义View来播放,简单是简单,就是太简单了,不适合自定义。

所以我查到了这个用法。使用Player和SurfaceView结合来播放视频。至于这里的依赖呢,我偷懒直接Gradle添加Compile就好了,只是播放的话省的自己去编译了。

然后player.setDataSource把上面lalala.ffconcat文件的绝对路径传进去,当然要注意需要申请对应的读取权限哈。

根据Issue 211Issue 1925在读取concat文件出错Operation not permitted的时候,在初始化Player的时候需要这样处理

  1. add file to protocol_whitelist

ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "protocol_whitelist", "rtmp,concat,ffconcat,file,subfile,http,https,tls,rtp,tcp,udp,crypto");

  1. set format option "safe" = "0"

ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT,"safe",0);

这样子,就应该没有什么问题了。

测试的时候要多关注Logcat的输出信息,Option设置有没有生效在Log中是有Log的。

写完才发现IJKPlayer的源码中是有完善的方法注释的。现在知道为什么Example中为什么要依赖别的Module了,这样就能看到方法的说明了。

为什么没有source级别的jar包提供啊。。。

Activity

coolryze

coolryze commented on Jul 8, 2019

@coolryze

请问,使用 IJKPlayer concat 来做多个视频连播时,如何知道从第x个视频播到了下一个视频呢?
我目前没有找到它的回调,暂时只能监听它的播放时长来做,不过不太准确 😢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @alwaystest@coolryze

        Issue actions

          IJKPlayer Concat · Issue #58 · alwaystest/Blog