通过阅读本文,您可以了解iOS端依赖FFmpeg的其他播放器(本文以ijkplayer tag k0.8.8为例)集成Native RTS SDK实现超低延时直播的方法。

前提条件

您已完成ijkplayer源码的编译。具体操作,请参见ijkplayer中README.md介绍。

操作步骤

  1. 下载并解压ijkplayer源码。下载地址,请参见ijkplayer
  2. 下载并解压Native RTS SDK。下载地址,请参见SDK下载
  3. ijkplayer集成Native RTS SDK作为插件。

    ijkplayer集成Native RTS SDK有以下两种方式:

    集成方式 描述 优点 缺点
    拓展FFmpeg 拓展ijk中FFmpeg的demuxer。 使用更加简单,不需要根据ARTC的URL做逻辑区分。 需要重新编译FFmpeg库。
    拓展ijk ijkplayer中添AVInputFormat。 不需要编译FFmpeg。 ff_ffplay.c中需要添加部分逻辑代码。

    拓展FFmpeg

    1. 在ijkplayer根目录下,执行./init-ios.sh进行初始化。
    2. 复制Native RTS SDK中的rtsdec.c文件至ijkplayer/ios/ffmpeg-$arch/libavformat目录。
    3. 修改Makefile文件并编译rtsdec.c文件。

      修改ijkplayer/ios/ffmpeg-$arch/libavformat/Makefile,并编辑rtsdec.c文件。

      914
    4. 修改allformats.c文件。

      修改ijkplayer/ios/ffmpeg-$arch/libavformat/allformats.c,默认支持ARTC协议。

      016
          extern AVInputFormat ff_rtc_demuxer;
          av_register_input_format(&ff_rtc_demuxer);
    5. 编译。

      ijkplayer/ios目录下,执行./compile-ffmpeg.sh all运行该脚本。编译完成之后,检查并确保ijkplayer/ios/build/universal目录下有对应的FFmpeg编译输出文件。

    6. 复制Native RTS SDK中的RtsSDK.framework文件至ijkplayer/ios/IJKMediaDemo/IJKMediaDemo目录中。
    7. 使用Xcode打开ios/IJKMediaDemo/IJKMediaDemo.xcodeproj
    8. 添加RtsSDK.framework的依赖。264
    9. 在ff_ffplay.c中添加RTS逻辑。

      修改ijkplayer/ijkmedia/ijkplayer/ff_ffplay.c文件,设置ARTC的AVInputFormat函数指针。

      021
          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");

    拓展ijk

    1. 运行FFmpeg编译脚本ijkplayer/config/module-lite.sh
    2. 复制Native RTS SDK中的RtsSDK.framework文件至ijkplayer/ios/IJKMediaDemo/IJKMediaDemo目录中。
    3. 工程中导入Native RTS SDK中的rtsdec.c文件。270
    4. 在ff_ffplay.c中添加RTS逻辑。

      修改ijkplayer/ijkmedia/ijkplayer/ff_ffplay.c文件,设置ARTC的AVInputFormat函数指针。

      053
      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. 导入Native RTS SDK中RtsSDK.framework和ijkplayer中IJKMediaFramework.framework文件至工程中。
    273
  5. 调用ijkplayer接口实现超低延时直播功能。
    • 创建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; //开启自动播放
    • 播放控制
      - (void)prepareToPlay;
      - (void)play;
      - (void)pause;
      - (void)stop;