全部产品

移动端集成文档

本文为您介绍移动端RTS SDK与播放器引擎的集成方法,支持集成三类播放器引擎——为阿里云播放器SDK、依赖FFmpeg的其他播放器引擎、不依赖FFmpeg的播放器引擎。

1 产品输出形态

平台

输出形态

备注

Android

maven

只能配合阿里云播放器SDK使用。

so库和头文件

需要客户自己开发artc Demuxer,如果使用了FFmpeg可以基于rtsdec.c开发。

jar包

1.4.1 之后版本开始提供,选择so库方式集成需要放入jar包的依赖,使用maven方式集成不需要集成jar包。

-

rtsdec.c

FFmpeg的AVInputFormat插件。

IOS

pod

无论是否使用阿里云播放器SDK,都可以使用该形态。但是如果使用自有播放器的话,需要客户自己开发artc Demuxer;如果自有播放器使用了FFmpeg,可以基于rtsdec.c开发。

动态framework

2 集成方法介绍

使用低延迟直播(RTS),就需要有播放器引擎。播放器引擎可以分为阿里云播放器SDK、依赖FFmpeg的其他播放器引擎、不依赖FFmpeg的播放器引擎三类。

三类引擎对应的集成方法不同,大致步骤如下:

  • 配合阿里云播放器SDK

    1. 阿里云播放器SDK集成RTS SDK作为插件

    2. 客户工程集成阿里云播放器SDK和RTS SDK

    3. 调用阿里云播放器SDK的接口使用RTS服务

  • 配合依赖FFmpeg的其他播放器引擎

    1. FFmpeg集成RTS SDK作为插件

    2. 客户工程集成播放器引擎

    3. 调用播放器引擎的接口使用RTS服务

  • 配合不依赖FFmpeg的播放器引擎

    1. 集成RTS SDK作为插件

    2. 客户工程集成播放器引擎

    3. 调用播放器引擎的接口使用RTS服务

说明

结合自身播放器的情况,按照对应的步骤进行集成。

3 示例代码

ijkplayer-RTS是基于开源播放器ijkplayer进行拓展,使其播放器引擎支持RTS低延迟直播的示例。您可以借鉴该项目快速拓展自研的播放器引擎。

示例名称

下载地址

ijkplayer-RTS

点击下载

4 Android平台集成步骤

4.1 配合阿里云播放器SDK使用

如果使用的播放器是阿里云播放器SDK,那么集成方法将比较简单,因为集成工作已经在播放器SDK中内置了,只需要做一下依赖,就可以像正常使用RTMP协议一样使用ARTC协议。

step1 阿里云播放器SDK集成RTS SDK作为插件

需要将阿里云播放器SDK版本中ArtcDemuxer.aar依赖到App工程中,同时添加RtsSDK.aar到App工程中即可,maven或者本地依赖的方式都可以。在依赖了ArtcDemuxer.aar后,播放器SDK会自动将RTS SDK加载为插件。

  • maven依赖:

    名称

    版本号

    相关代码

    AliyunARTC

    5.2.0

    implementation 'com.aliyun.sdk.android:AliyunArtc:5.2.0'

    RTSSDK

    1.3.0

    implementation 'com.aliyun.rts.android:RtsSDK:+'
  • 本地依赖:

    如果使用本地依赖的方式,可以在SDK下载页面中获取。

step2 客户工程集成阿里云播放器SDK和RTS SDK

如果已经集成了阿里云播放器SDK可以忽略该部分,直接升级下版本号即可。播放器SDK的集成同样分为maven和本地依赖两种方式。

  • maven依赖:

    名称

    版本号

    相关代码

    阿里云播放器版本

    5.2.0

    implementation 'com.aliyun.sdk.android:AliyunPlayer:5.2.0-full'

    AlivcConan

    1.3.0

    implementation 'com.alivc.conan:AlivcConan:1.0.4'
  • 本地依赖:

    如果使用本地依赖的方式,可以通过官网中版本的zip包中手动获取:获取链接。播放器SDK集成文档请参见集成文档

集成步骤:

  1. 先选择好依赖方式,再开始工程集成。

  2. 新建工程:新建工程2

  3. 创建完成后,项目目录结构如图所示:项目结构

  4. 在根目录的build.gradle中添加如下代码:gradle

    //MPChart maven 仓库地址,如果不需要曲线图,可以删除
    maven { url 'https://jitpack.io' }
    //阿里云相关SDK maven 仓库地址,如果使用 IJKPlayer 可以删除
    maven { url "http://maven.aliyun.com/nexus/content/repositories/releases" }
    //RTS 网络库 SDK maven 仓库地址,如果使用 IJKPlayer 可以删除,RTSDemo中IJK的动态库已包含
    maven { url 'http://mvnrepo.alibaba-inc.com/nexus/content/groups/public' }

    ext {
        compileSdkVersion = 25
        buildToolsVersion = "25.0.3"
        minSdkVersion = 21
        targetSdkVersion = 25
    
        versionCode = 800800
        versionName = "0.8.8"
        appVersionCode = 1
        appVersionName = "1.0"
    
        externalRecyclerView = 'com.android.support:recyclerview-v7:25.4.0'
        externalMPAndroidChart = 'com.github.PhilJay:MPAndroidChart:v3.1.0'
        externalSupportAppCompat = 'com.android.support:appcompat-v7:25.4.0'
    
        //ARTC直播播放器
        externalAlivcConan = 'com.alivc.conan:AlivcConan:1.0.4'
        externalAliyunARTCNet = 'com.aliyun.rts.android:RtsSDK:+'
        externalAliyunARTC = 'com.aliyun.sdk.android:AliyunArtc:5.2.0'
        externalAliyunPlayer = 'com.aliyun.sdk.android:AliyunPlayer:5.2.0-full'
    
        //required, enough for most devices.
    //    implementation 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
    //    implementation 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.8'
    }
    

step3 调用阿里云播放器SDK的接口使用RTS服务

完成以上配置之后,播放器SDK已经可以支持artc://协议流了。

  1. 创建播放器

    创建播放器通过AliPlayerFactory类创建播放器。可以创建两种播放器:AliPlayer和AliListPlayer。单个播放功能使用AliPlayer。

    创建方法如下:

    AliPlayer aliyunVodPlayer;
    .....
    aliyunVodPlayer = AliPlayerFactory.createAliPlayer(getApplicationContext());
  2. 设置播放器监听事件

    播放器提供了多种监听事件,比如:onPrepared,onCompletion等事件。

    设置方法如下:

    aliyunVodPlayer.setOnCompletionListener(new IPlayer.OnCompletionListener() {
        @Override
        public void onCompletion() {
            //播放完成事件
        }
    });
    aliyunVodPlayer.setOnErrorListener(new IPlayer.OnErrorListener() {
        @Override
        public void onError(ErrorInfo errorInfo) {
            //出错事件
        }
    });
    aliyunVodPlayer.setOnPreparedListener(new IPlayer.OnPreparedListener() {
        @Override
        public void onPrepared() {
            //准备成功事件
        }
    });
    aliyunVodPlayer.setOnVideoSizeChangedListener(new IPlayer.OnVideoSizeChangedListener() {
        @Override
        public void onVideoSizeChanged(int width, int height) {
            //视频分辨率变化回调
        }
    });
    aliyunVodPlayer.setOnRenderingStartListener(new IPlayer.OnRenderingStartListener() {
        @Override
        public void onRenderingStart() {
            //首帧渲染显示事件
        }
    });
    aliyunVodPlayer.setOnInfoListener(new IPlayer.OnInfoListener() {
        @Override
        public void onInfo(int type, long extra) {
            //其他信息的事件,type包括了:循环播放开始,缓冲位置,当前播放位置,自动播放开始等
        }
    });
    aliyunVodPlayer.setOnLoadingStatusListener(new IPlayer.OnLoadingStatusListener() {
        @Override
        public void onLoadingBegin() {
            //缓冲开始。
        }
        @Override
        public void onLoadingProgress(int percent, float kbps) {
            //缓冲进度
        }
        @Override
        public void onLoadingEnd() {
            //缓冲结束
        }
    });
    aliyunVodPlayer.setOnSeekCompleteListener(new IPlayer.OnSeekCompleteListener() {
        @Override
        public void onSeekComplete() {
            //拖动结束
        }
    });
    aliyunVodPlayer.setOnSubtitleDisplayListener(new IPlayer.OnSubtitleDisplayListener() {
        @Override
        public void onSubtitleShow(long id, String data) {
            //显示字幕
        }
        @Override
        public void onSubtitleHide(long id) {
            //隐藏字幕
        }
    });
    aliyunVodPlayer.setOnTrackChangedListener(new IPlayer.OnTrackChangedListener() {
        @Override
        public void onChangedSuccess(TrackInfo trackInfo) {
            //切换音视频流或者清晰度成功
        }
        @Override
        public void onChangedFail(TrackInfo trackInfo, ErrorInfo errorInfo) {
            //切换音视频流或者清晰度失败
        }
    });
    aliyunVodPlayer.setOnStateChangedListener(new IPlayer.OnStateChangedListener() {
        @Override
        public void onStateChanged(int newState) {
            //播放器状态改变事件
        }
    });
    aliyunVodPlayer.setOnSnapShotListener(new IPlayer.OnSnapShotListener() {
        @Override
        public void onSnapShot(Bitmap bm, int with, int height) {
            //截图事件
        }
    });
  3. 创建DataSource,准备播放

    播放器支持4种播放源:VidSts,VidAuth,VidMps,UrlSource。其中UrlSource是直接的url播放,需要将URL设置为artc://协议的,就可以使用RTS服务了。

    UrlSource urlSource = new UrlSource();
    urlSource.setUri("artc://xxxx");
    aliyunVodPlayer.setDataSource(urlSource);
  4. 设置显示的view

    如果源有画面,那么需要设置显示的view到播放器中,用来显示画面。支持SurfaceView和TextureView。

    以SurfaceView举例:

    surfaceView = (SurfaceView) findViewById(R.id.playview);
    surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            aliyunVodPlayer.setDisplay(holder);
        }
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            aliyunVodPlayer.redraw();
        }
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            aliyunVodPlayer.setDisplay(null);
        }
    });
  5. 播放控制

    用户自行创建播放器的播放控制按钮,在按钮事件里面实现播放器控制接口。基本控制功能有播放、停止、暂停、拖动(seek),其中Seek功能仅对点播有效,直播使用暂停功能时会使画面停留在当前画面,使用恢复后会开始播放当前画面。

    使用示例如下:

    // 开始播放。
    aliyunVodPlayer.start();
    //暂停播放
    aliyunVodPlayer.pause();
    //停止播放
    aliyunVodPlayer.stop();
    // 跳转到。不精准。
    aliyunVodPlayer.seekTo(long position);
    // 重置
    aliyunVodPlayer.reset();
    //释放。释放后播放器将不可再被使用。
    aliyunVodPlayer.release();

    播放器SDK更多功能请参见:播放器SDK接口说明播放器SDK功能说明

  6. 参数配置

    另外建议如下参数设置,可以更好发挥低延迟优势:

    //先获取配置
    PlayerConfig config = mAliyunVodPlayer.getConfig();
    //设置最大延迟为1s,延迟控制交由artc控制
    config.mMaxDelayTime = 1000;
    //设置播放器启播缓存为10ms,数据控制由artc控制。
    config.mHighBufferDuration = 10;
    config.mStartBufferDuration = 10;
    ....//其他设置
    //设置配置给播放器
    mAliyunVodPlayer.setConfig(config);
  7. loadlibrary

    需要在合适的Activity内加入System.loadLibrary("RtsSDK")

    static {
        System.loadLibrary("RtsSDK");
    }

4.2 配合依赖FFmpeg的其他播放器使用(ijk为例)

使用其他播放器引擎的话,将RTS SDK集成为插件拓展支持artc协议将会有部分的开发工作。为了降低客户成本,ffmpeg作为比较常见的播放器引擎,我们提供了rtsdec.c 源码,该代码可以将RTS SDK对接到ffmpeg 中作为一个Demuxer 插件。下面是详细的集成步骤

step1 ijkplayer集成RTS SDK作为插件

提供两种集成办法:

集成方法

优点

缺点

拓展ijk中FFmpeg的demuxer(简称:拓展FFmpeg)

使用更加简单,不需要根据ARTC的URL做逻辑区分。

需要重新编译FFmpeg库

ijkplayer中添AVInputFormat(简称:拓展ijk)

不需要编译FFmpeg

ff_player.c中需要添加部分逻辑代码

注意
  1. 目前RTS Android 平台只提供arm64、armv7a的动态库

  2. 请先阅读并完成ijk的编译:ijkPlayer Github

  3. 以下步骤基于ijk tag:k0.8.8

拓展FFmpeg的方法:

  1. 修改ijkplayer/init-android.shpull_fork只保留armv7a和arm64, 并执行该脚本。

    说明

    目前rts只提供armv7a和arm64的动态库。

    ijk-图1

  2. 修改ijkplayer/Android/contrib/compile-ffmpeg.shFF_ACT_ARCHS_64,只保留armv7a和 arm64。c2

  3. 将RTS输出的rtsdec.c拷贝到ijkplayer/android/contrib/ffmpeg-arm64/libavformatijkplayer/android/contrib/ffmpeg-armv7a/libavformat目录下。

  4. 修改Makefile,编译rtsdec.c。

    修改ijkplayer/android/contrib/ffmpeg-arm64/libavformat/Makefileijkplayer/android/contrib/ffmpeg-arm64/libavformat/Makefile,如下图:1

  5. 修改allformat.c 默认支持ARTC协议。

    修改ijkplayer/android/contrib/ffmpeg-arm64/libavformat/allformats.cijkplayer/android/contrib/ffmpeg-arm64/libavformat/allformats.c,如下图:c6

        extern AVInputFormat ff_rtc_demuxer;
        av_register_input_format(&ff_rtc_demuxer);
  6. 修改ffmpeg编译脚本支持PCM解码(RTS SDK输出的是PCM数据)。/config/module-lite.sh 脚本中加入:

    # aliyun rts
    export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=pcm_s16be_planar"
    export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=pcm_s16le"
    export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=pcm_s16le_planar"
  7. 编译。

    添加ANDROID_NDK环境变量,文档使用的是r12b。在ijkplayer/android/contrib/目录下执行:./compile-ffmpeg.sh all

  8. 检查。

    检查ijkplayer/android/contrib/build目录下是否有对应的FFmpeg编译输出文件。

  9. ijkplayer 依赖 rts。

    修改ijkplayer/Android/compile-ijk.sh,ACT_ABI_64中只保留armv7a和arm64 。如下图:c7

  10. 放入RTS的动态库。

    将RTS对应架构的动态库放入到ijkplayer/android/contrib/build/ffmpeg-arm64/output 和ijkplayer/android/contrib/build/ffmpeg-armv7a/output中,将头文件rts_api.hrts_messages.h拷贝到ijkplayer/android/contrib/build/ffmpeg-arm64/output/includeijkplayer/android/contrib/build/ffmpeg-armv7a/output/include中。

  11. 引入RTS的动态库。

    修改ijkplayer/android/ijkplayer/ijkplayer-armv7a/src/main/jni/ffmpeg/Android.mkijkplayer/android/ijkplayer/ijkplayer-arm64/src/main/jni/ffmpeg/Android.mk。如下图:c8

    include $(CLEAR_VARS)
    LOCAL_MODULE := rtssdk
    LOCAL_SRC_FILES := $(MY_APP_FFMPEG_OUTPUT_PATH)/libRtsSDK.so
    include $(PREBUILT_SHARED_LIBRARY)
  12. ijkplayer依赖RTS动态库。

    修改ijkplayer/ijkmedia/ijkplayer/Android.m。如下图:c9

  13. ff_fflay.c中加入RTS逻辑。

    设置给artc的AVInputFormat函数指针。修改ijkplayer/ijkmedia/ijkplayer/ff_ffplay.c。如下图:c10

        extern AVInputFormat ff_rtc_demuxer;
        extern int artc_reload(AVFormatContext *ctx);
        extern void av_set_rts_demuxer_funcs(const struct rts_glue_funcs *funcs);
        extern void artc_set_rts_param(char* key, char* value);
        extern long long artc_get_state(AVFormatContext *ctx, int key);
    
        int version = 2;
        const struct rts_glue_funcs* rts_funcs = get_rts_funcs(version);
        // set to ffmpeg plugin
        av_set_rts_demuxer_funcs(rts_funcs);
        artc_set_rts_param((char*)"AutoReconnect", (char*)"false");
  14. 编译。

    ijkplayer/android目录下执行./compile-ijk.sh all

拓展ijk的方法(参考示例代码):

  1. 编译FFmpeg。

    修改FFmpeg编译脚本支持PCM解码(RTS SDK输出的是PCM数据)。/config/module-lite.sh 脚本中加入:

    # aliyun rts
    export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=pcm_s16be_planar"
    export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=pcm_s16le"
    export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=pcm_s16le_planar"

    之后正常编译FFmpeg,不需要将RTS SDK依赖进去,参考ijk的编译步骤。

  2. ijkplayer依赖RTS

    需要将RTS SDK库文件放入工程,修改Android.mk 等操作。参考拓展ffmpeg方法中的该步骤的详细介绍。

  3. ff_fflay.c中加入RTS逻辑

    区分ARTC协议头,使用指定的AVInputFormat。如下图:c11

    if(strncmp(is->filename, "artc://", 7) == 0) {
            extern AVInputFormat ff_rtc_demuxer;
            extern int artc_reload(AVFormatContext *ctx);
            extern void av_set_rts_demuxer_funcs(const struct rts_glue_funcs *funcs);
            extern void artc_set_rts_param(char* key, char* value);
            extern long long artc_get_state(AVFormatContext *ctx, int key);
    
            int version = 2;
            const struct rts_glue_funcs* rts_funcs = get_rts_funcs(version);
            // set to ffmpeg plugin
            av_set_rts_demuxer_funcs(rts_funcs);
            artc_set_rts_param((char*)"AutoReconnect", (char*)"false");
            is->iformat = &ff_rtc_demuxer;
        }
        else {
            if(ffp->iformat_name)
                is->iformat = av_find_input_format(ffp->iformat_name);
        }
  4. 将rtsdec.c放入到ijkplayer/ijkmedia/ijkplayer目录下,并且编写该目录下android.mk添加该文件的编译:

    LOCAL_SRC_FILES += rtsdec.c

经过上面的步骤,播放器引擎已经添加了RTS SDK作为插件了,接下来是集成该播放器引擎。

step2 客户工程集成ijkplayer

1、将RtsNetSDK.jar 包导入到工程中。

2、需要在使用rts 播放的Activity内加入System.loadLibrary("RtsSDK")

static {
    System.loadLibrary("RtsSDK");
}

导入模块。

需要导入以下模块:ijkplayer-arm64、ijkplayer-armv7a、ijkplayer-java。

如图所示:j1

step3 调用ijkplayer 接口

  1. 创建ijkplayer。

    mIjkPlayer = new IjkMediaPlayer();
  2. 设置回调。

    mIjkPlayer.setOnPreparedListener(new IMediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(IMediaPlayer iMediaPlayer) {
            
        }
    });
    
    mIjkPlayer.setOnInfoListener(new IMediaPlayer.OnInfoListener() {
        @Override
        public boolean onInfo(IMediaPlayer iMediaPlayer, int arg1, int arg2) {
            
    });
    
    mIjkPlayer.setOnVideoSizeChangedListener(new IMediaPlayer.OnVideoSizeChangedListener() {
        @Override
        public void onVideoSizeChanged(IMediaPlayer iMediaPlayer, int width, int height, int sarNum, int sarDen) {
           
        }
    });
    
    mIjkPlayer.setOnErrorListener(new IMediaPlayer.OnErrorListener() {
        @Override
        public boolean onError(IMediaPlayer iMediaPlayer, int framework_err, int impl_err) {
            
            return false;
        }
    });
    
  3. 设置显示窗口。

    mIjkPlayer.setSurface(surface);
  4. 设置播放源。

    mIjkPlayer.setDataSource("artc://xxx");
  5. 状态控制。

    public void prepare() {
        if(mIjkPlayer != null){
            mIjkPlayer.prepareAsync();
        }
    }
    
    @Override
    public void start() {
        if(mIjkPlayer != null){
            mIjkPlayer.start();
        }
    }
    
    public void pause() {
        if(mIjkPlayer != null){
            mIjkPlayer.pause();
        }
    }
    
    public void stop() {
        if(mIjkPlayer != null){
            mIjkPlayer.stop();
        }
    }
    public void release() {
        if(mIjkPlayer != null){
            mIjkPlayer.release();
        }
    }

4.3 使用不依赖FFmpeg的播放器引擎

适合于拥有完全自研的播放器引擎的客户。需要参看RTS SDK编程手册,将动态库和头文件放入到工程中,参考rtsdec.c完成 demuxer的开发。

5 iOS平台

5.1 配合阿里云播放器SDK使用

step1 阿里云播放器SDK集成RTS SDK作为插件

App依赖阿里云播放器SDK的同时依赖RRS SDK和AliPlayerSDK_iOS_ARTC,播放器SDK将自动将RTS SDK加载为插件。

  • 最新版本pod依赖:

    名称

    版本号

    相关代码

    AliPlayerSDK_iOS_ARTC

    5.2.1

    pod 'AliPlayerSDK_iOS_ARTC'

    RtsSDK

    1.3.0

    pod 'RtsSDK'
  • 本地依赖:

    如果使用本地依赖的方式,可以在SDK下载页面中获取framework。

step2 客户工程集成阿里云播放器SDK和RTS SDK

  • pod依赖最新版本播放器:

    名称

    版本号

    相关代码

    阿里云播放器SDK

    5.2.1

      pod 'AliPlayerSDK_iOS'
  • 本地依赖:

    如果使用本地依赖的方式,可以通过官网中版本的zip包中手动获取:获取链接。播放器SDK集成文档请参见集成文档

先选择好依赖方式,再开始工程集成。

  • 如果使用pod方式打开终端,进入工程根目录运行pod init,在生成的podfile文件中输入如下文本(如需指定版本,请自行带上版本号)。运行pod install。(如您尚未安装pod,请自行安装。)

     pod 'RtsSDK'
     pod 'AliPlayerSDK_iOS'
     pod 'AliPlayerSDK_iOS_ARTC'
     ```

  • 如果采用本地依赖方式,则将如下库文件拖到项目中,并在target的Gennel栏将framework设置为Embed & Sign。

    j2j3

step3、调用阿里云播放器SDK接口

  1. 初始化Aliplayer。

    - (AliPlayer *)aliPlayer{
        if (!_aliPlayer) {
            _aliPlayer = [[AliPlayer alloc] init];
            _aliPlayer.scalingMode =  AVP_SCALINGMODE_SCALEASPECTFIT;
            _aliPlayer.rate = 1;
        //如需实现AVPDelegate代理,添加此行
            _aliPlayer.delegate = self;
        //设置播放的视图,将您的播放视图赋值给aliplayer
            _aliPlayer.playerView = self.basePlayerView.playerView;
            _aliPlayer.autoPlay = YES;
        }
        return _aliPlayer;
    }
  2. 设置播放URL。

    AVPUrlSource *source = [[AVPUrlSource alloc] urlWithString:_url];
    [self.aliPlayer setUrlSource:source];
  3. 设置播放参数。 使用阿里云播放器播放 artc 直播流,推荐配置如下:

    注意

    播放器参数配置需要在调用prepare之前才能生效。

    AVPConfig *config = self.aliPlayer.getConfig;
    //直播最大延迟
    [config setMaxDelayTime:1000];
    //卡顿恢复时长
    [config setHighBufferDuration:10];
    //起播最大延迟
    [config setStartBufferDuration:10];
    //重连次数
    [config setNetworkRetryCount:2];
    //重连时长  
    [config setNetworkTimeout:15000];
     [_aliPlayer setConfig:config];
    //默认为硬解,如播放器在准备过程中发现硬解失败,会自动切换到软解
     _aliPlayer.enableHardwareDecoder = YES;
  4. 打开日志。

    [AliPlayer setEnableLog:YES];
    [AliPlayer setLogCallbackInfo:LOG_LEVEL_DEBUG callbackBlock:nil];
  5. 播放控制。

    [self.aliPlayer prepare];
    [self.aliPlayer stop];
    [self.aliPlayer destroy];
    [self.aliPlayer reload];

5.2 配合依赖ffmpeg的其他播放器使用(ijk为例)

使用其他播放器引擎的话,将RTS SDK集成为插件拓展支持artc协议将会有部分的开发工作。为了降低客户成本,ffmpeg作为比较常见的播放器引擎,我们提供了rtsdec.c 源码,该代码可以将RTS SDK对接到ffmpeg 中作为一个Demuxer 插件。下面是详细的集成步骤

step1 ijkplayer集成RTS SDK作为插件

提供两种集成办法:

集成方法

优点

缺点

拓展ijk中ffmpeg的demuxer(简称:拓展FFmpeg

使用更加简单,不需要根据artc的url做逻辑区分。

需要重新编译FFmpeg库。

ijkplayer中添AVInputFormat(简称:拓展ijk

不需要编译FFmpeg。

ff_player.c中需要添加部分逻辑代码。

注意
  1. 请先阅读并完成ijk的编译:ijkPlayer Github

  2. 以下步骤基于ijk tag:k0.8.8

拓展ffmpeg的方法:

  1. ijkplayer目录下,执行init-ios.sh

  2. 进入ijkplayer/ios目录,将rtsdec.c拷贝到ffmpeg-$arch/libavformat中,修改libavformat/Makefileallformat.c。参考Android方法一中的该步骤。

  3. 编译。

    ijkplayer/ios目录下,执行./compile-ffmpeg.sh all

  4. 检查。

    查看ijkplayer/ios/build/universal/目录下是否有输出的FFmpeg库。

  5. RtsSDK.framework放入到ijkplayer//ios/IJKMediaDemo/IJKMediaDemo目录下。

  6. 使用xcode打开ios/IJKMediaDemo/IJKMediaDemo.xcodeproj

  7. IJKMediaPlayer.xcodeproj添加RtsSDK.framework的依赖。j4

  8. ff_fflay.c中加入RTS逻辑。参考Android平台该方法中的实现。

拓展ijkplayer方法:

  1. 编译FFmpeg。

    按照ijk的官方引导来进行编译,不需要依赖RTS SDK拓展FFmpeg。

  2. ijkplayer依赖rts。

    参考ios平台拓展FFmpeg方法中的该步骤。

  3. 将rtsdec.c 拖入到工程中。j5

  4. 修改ff_ffplay.c代码。参考Android中该方法的步骤实现。

step2、客户工程集成播放器引擎和RTS SDK

将ijkplayer输出的引擎framework和RTS SDK的framework拖入工程

j6

step3、调用播放器引擎的接口

  1. 创建ijkplayer

    _ijkPlayer = [[IJKFFMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:_url] withOptions:options];
    _ijkPlayer.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
    _ijkPlayer.view.frame = self.basePlayerView.playerView.bounds;
    _ijkPlayer.scalingMode = IJKMPMovieScalingModeAspectFit; //缩放模式
    _ijkPlayer.shouldAutoplay = YES; //开启自动播放
  2. 播放控制

    - (void)prepareToPlay;
    - (void)play;
    - (void)pause;
    - (void)stop;

5.3 使用不依赖FFmpeg的播放器

适合于拥有完全自研的播放器引擎的客户。需要参见RTS SDK编程手册,将动态库和头文件放入到工程中,参考rtsdec.c完成 demuxer的开发。

六、常见问题

  • Q:播放器artc://流报timeout。

    A:常见原因:未开通RTS服务。判断方法:使用h5 播放器测试。

  • Q:使用阿里云播放器sdk,按照步骤执行后报不支持artc协议。

    A:常见原因:项目中未包含了AlivcArtc.aar和RtsSDK.aar。

  • Q: 播放卡顿。

    1. 视频交错是否符合要求。判断方法:ffmpeg命令行保存RTMP流,ffprobe查看packet交错情况。

    2. 网络环境差。判断方法: 使用RTMP播放。

    3. 是否正确设置了播放器SDK的参数。判断方法:参考阿里云播放器的文档。

  • Q:使用其他播放器引擎拉流没有声音。

    A:检查FFmpeg是否支持pcm decoder。判断方法:音频decoder是否创建成功。