全部产品
Search
文档中心

:iOS

更新时间:Dec 30, 2025

Topik ini menjelaskan cara mengintegrasikan Native RTS SDK ke dalam pemain pihak ketiga berbasis FFmpeg untuk mengimplementasikan Real-Time Streaming (RTS) pada klien iOS. Topik ini menggunakan pemain pihak ketiga ijkplayer versi k0.8.8.

Prasyarat

Kode sumber ijkplayer telah dikompilasi. Untuk informasi lebih lanjut, lihat file README.md dari ijkplayer.

Prosedur

  1. Unduh dan ekstrak kode sumber ijkplayer. Untuk mendapatkan tautan unduhan, kunjungi halaman ijkplayer.

  2. Unduh dan ekstrak paket Native RTS SDK. Untuk informasi lebih lanjut tentang tautan unduhan, lihat Unduhan SDK dan catatan rilis.

  3. Integrasikan Native RTS SDK sebagai plugin ke dalam ijkplayer. Tabel berikut menjelaskan dua metode integrasi.

    Metode Integrasi

    Deskripsi

    Keuntungan

    Kerugian

    Perluas FFmpeg.

    Perluas FFmpeg dengan menambahkan plugin demuxer.

    Metode ini menyederhanakan pengembangan. Anda tidak perlu mengembangkan logika tambahan untuk URL berbasis Alibaba Real-Time Communication (ARTC).

    Anda harus mengompilasi ulang FFmpeg.

    Perluas ijkplayer.

    Perluas ijkplayer dengan menambahkan struct AVInputFormat.

    Anda tidak perlu mengompilasi FFmpeg.

    Anda harus menambahkan kode logika ke file ff_ffplay.c.

    Perluas FFmpeg

    1. Di direktori root ijkplayer, jalankan perintah ./init-ios.sh untuk inisialisasi.

      Catatan bahwa Xcode 14 tidak lagi mendukung arsitektur seperti ARMv7, i386, dan x86_64. Anda harus menghapus kode arsitektur ini dari file init-ios.sh.

      Skrip kompilasi berikut memberikan contoh saat menggunakan Xcode 14:

      # FF_ALL_ARCHS_IOS8_SDK="armv7 arm64 i386 x86_64"
      FF_ALL_ARCHS_IOS11_SDK="arm64"
      FF_ALL_ARCHS=$FF_ALL_ARCHS_IOS11_SDK
    2. Buka direktori iOS ijkplayer. Jika Anda mengompilasi perintah untuk FFmpeg dan folder ffmpeg-$arch dari direktori build muncul di direktori iOS, jalankan perintah ./compile-ffmpeg.sh clean untuk membersihkan direktori iOS.

    3. Salin file rtsdec.c di Native RTS SDK ke direktori ijkplayer/ios/ffmpeg-$arch/libavformat.

    4. Modifikasi file Makefile dan kompilasi file rtsdec.c.914

    5. Modifikasi file allformats.c.

      Modifikasi file ijkplayer/ios/ffmpeg-$arch/libavformat/allformats.c. Secara default, protokol Alibaba Real-Time Communication (ARTC) didukung.

      016

    6. Modifikasi skrip kompilasi FFmpeg ijkplayer/config/module-lite.sh untuk mendukung decoding pulse-code modulation (PCM). Operasi ini diperlukan karena Native RTS SDK mengekspor data PCM.

      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"

      Opsional: Jika Anda ingin mendukung aliran melalui protokol HTTPS, tambahkan kode berikut ke file untuk mengaktifkan dukungan OpenSSL.

      export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-openssl"
    7. Kompilasi FFmpeg.

      Jalankan perintah ./compile-ffmpeg.sh all di direktori ijkplayer/ios. Pada saat yang sama, hapus kode arsitektur yang tidak didukung dari skrip, mirip dengan Langkah a. Setelah Anda mengompilasi FFmpeg, pastikan file output kompilasi FFmpeg ada di direktori ijkplayer/ios/build/universal.

      Opsional: Jika Anda ingin mendukung aliran melalui protokol HTTPS, jalankan perintah ./compile-openssl.sh all terlebih dahulu. Pada saat yang sama, hapus kode arsitektur yang tidak didukung dari skrip, mirip dengan Langkah a. Setelah Anda mengompilasi FFmpeg, file libssl.a dan libcrypto.a dibuat di direktori ijkplayer/ios/build/universal/lib. Kemudian, kompilasi ./compile-ffmpeg.sh all.

    8. Salin file RtsSDK.framework di Native RTS SDK ke direktori ijkplayer/ios/IJKMediaDemo/IJKMediaDemo.

    9. Buka ios/IJKMediaDemo/IJKMediaDemo.xcodeproj di Xcode.

    10. Tambahkan RtsSDK.framework sebagai dependensi.264

    11. Tambahkan framework dinamis Native RTS SDK.

      Impor file header rts_api.h dan rts_messages.h dari Native RTS SDK ke direktori ijkplayer/ios/build/universal/lib.

      rts_api.h

    12. Tambahkan kode logika RTS ke file ff_ffplay.c.

      Impor file header rts_api.h.

      #include "rts_api.h"

      Modifikasi file ijkplayer/ijkmedia/ijkplayer/ff_ffplay.c dengan mengonfigurasi pointer fungsi AVInputFormat untuk ARTC.AVInputFormat

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

    Perluas ijkplayer

    1. Di direktori root ijkplayer, jalankan perintah ./init-ios.sh untuk inisialisasi.

      Catatan bahwa Xcode 14 tidak lagi mendukung arsitektur seperti ARMv7, i386, dan x86_64. Anda harus menghapus kode arsitektur ini dari file init-ios.sh.

      Skrip kompilasi berikut memberikan contoh saat menggunakan Xcode 14:

      # FF_ALL_ARCHS_IOS8_SDK="armv7 arm64 i386 x86_64"
      FF_ALL_ARCHS_IOS11_SDK="arm64"
      FF_ALL_ARCHS=$FF_ALL_ARCHS_IOS11_SDK
    2. Buka direktori iOS ijkplayer. Jika Anda mengompilasi perintah untuk FFmpeg dan folder ffmpeg-$arch dari direktori build muncul di direktori iOS, jalankan perintah ./compile-ffmpeg.sh clean untuk membersihkan direktori iOS.

    3. Jalankan skrip kompilasi FFmpeg ijkplayer/config/module-lite.sh untuk mendukung decoding PCM. Operasi ini diperlukan karena Native RTS SDK mengekspor data PCM.

      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"

      Opsional: Jika Anda ingin mendukung aliran melalui protokol HTTPS, tambahkan kode berikut ke file untuk mengaktifkan dukungan OpenSSL.

      export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-openssl"
    4. Kompilasi FFmpeg.

      Jalankan perintah ./compile-ffmpeg.sh all di direktori ijkplayer/ios. Pada saat yang sama, hapus kode arsitektur yang tidak didukung dari skrip, mirip dengan Langkah a. Setelah Anda mengompilasi FFmpeg, pastikan file output kompilasi FFmpeg ada di direktori ijkplayer/ios/build/universal.

      Opsional: Jika Anda ingin mendukung aliran melalui protokol HTTPS, jalankan perintah ./compile-openssl.sh all terlebih dahulu. Pada saat yang sama, hapus kode arsitektur yang tidak didukung dari skrip, mirip dengan Langkah a. Setelah Anda mengompilasi FFmpeg, file libssl.a dan libcrypto.a dibuat di direktori ijkplayer/ios/build/universal/lib. Kemudian, kompilasi ./compile-ffmpeg.sh all.

    5. Salin file RtsSDK.framework di Native RTS SDK ke direktori ijkplayer/ios/IJKMediaDemo/IJKMediaDemo.

    6. Impor file rtsdec.c di Native RTS SDK ke dalam proyek Anda.270

      Impor file header rts_api.h dan rts_messages.h dari Native RTS SDK ke direktori ijkplayer/ios/build/universal/lib.

      rts_api.h

    7. Tambahkan kode logika RTS ke file ff_ffplay.c.

      Impor file header rts_api.h.

      #include "rts_api.h"

      Modifikasi file ijkplayer/ijkmedia/ijkplayer/ff_ffplay.c dengan mengonfigurasi pointer fungsi AVInputFormat untuk ARTC.AVInputFormat

      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. Kompilasi proyek IJKMediaPlayer.

    Setelah Anda memperluas FFmpeg atau memperluas ijkplayer, gunakan kompiler Archive untuk menjalankan proyek ijkplayer/ios/IJKMediaPlayer/IJKMediaPlayer.xcodeproj. File IJKMediaFramework.framework dibuat di direktori Products.

    Opsional: Jika Anda ingin mendukung aliran melalui protokol HTTPS, sebelum Anda menjalankan kompilasi, pilih Build Phases > Link Binary With Libraries untuk proyek di Xcode dan impor file libssl.a dan libcrypto.a di direktori ijkplayer/ios/build/universal/lib yang dibuat pada langkah-langkah sebelumnya.

    IJKMediaPlayer

  5. Impor file RtsSDK.framework di Native RTS SDK dan file IJKMediaFramework.framework di ijkplayer ke dalam proyek.

    273

  6. Panggil metode yang disediakan oleh ijkplayer untuk menggunakan fitur RTS.

    • Buat ijkplayer

      // Hasilkan URL melalui protokol ARTC.
      _url = @"artc://xxxx";
      
      // Buat custom playerView.
      [self.view addSubview:self.playerView];
      ...
      
      IJKFFOptions *options = [IJKFFOptions optionsByDefault];
      // Konfigurasikan decoding perangkat keras.
      [options setPlayerOptionIntValue:1 forKey:@"videotoolbox"];
      // Konfigurasikan decoding perangkat lunak.
      //[options setPlayerOptionIntValue:0 forKey:@"videotoolbox"];
      
      _ijkPlayer = [[IJKFFMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:_url] withOptions:options];
      _ijkPlayer.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
      _ijkPlayer.view.frame = self.playerView.bounds;
      _ijkPlayer.scalingMode = IJKMPMovieScalingModeAspectFit; // Tentukan mode penskalaan.
      _ijkPlayer.shouldAutoplay = YES; // Aktifkan putar otomatis.
      [self.playerView addSubview:_ijkPlayer.view];
    • Atur kontrol pemutaran

      • Mulai pemutaran.

        Anda harus memanggil metode ini di utas utama. Kami sarankan Anda menghentikan pemutaran dan melepaskan pemain sebelum Anda memulai pemutaran setiap kali.

        dispatch_async(dispatch_get_main_queue(), ^{
            [_ijkPlayer prepareToPlay];
            [_ijkPlayer play];
        });
      • Hentikan pemutaran dan lepaskan pemain.

        // Hentikan pemutaran.
        [_ijkPlayer stop];
        
        // Lepaskan pemain.
        [_ijkPlayer shutdown];
        _ijkPlayer = nil;

Dengarkan event RTS

  • Dengarkan callback pesan Native RTS SDK di ijkplayer

    Buka proyek ijkplayer/ios/IJKMediaPlayer/IJKMediaPlayer.xcodeproj dan tambahkan metode yang sesuai ke file-file terkait.

    1. Modifikasi file ff_ffplay.c dengan menyisipkan blok kode berikut setelah metode static int audio_open(FFPlayer *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params){}.

      extern int artcDemuxerMessage(struct AVFormatContext *s, int type, void *data, size_t data_size);
      //aliyun rts:menerima pesan artc
      int onArtcDemuxerMessage(struct AVFormatContext *s, int type, void *data, size_t data_size)
      {
          return artcDemuxerMessage(s, type, data, data_size);
      }
      
      int artcDemuxerMessage(struct AVFormatContext *s, int type, void *data, size_t data_size)
      {
          //aliyun rts:kirim pesan ke aplikasi
          FFPlayer *ffp = (FFPlayer *)s->opaque;
          const char *data_msg = (const char *)data;
          ffp_notify_msg4(ffp,FFP_MSG_ARTC_DIRECTCOMPONENTMSG,type,0,data_msg,data_size);
          return 0;
      }
    2. Modifikasi file ff_ffplay.c dengan menyisipkan blok kode RTS berikut ke dalam metode static int is_realtime(AVFormatContext *s){}.

      static int is_realtime(AVFormatContext *s)
      {
          if(   !strcmp(s->iformat->name, "rtp")
             || !strcmp(s->iformat->name, "rtsp")
             || !strcmp(s->iformat->name, "sdp")
             // *** Awal blok kode RTS ***
             || !strcmp(s->iformat->name, "artc")
             // *** Akhir blok kode RTS ***
          )
              return 1;
      
          if(s->pb && (   !strncmp(s->filename, "rtp:", 4)
                       || !strncmp(s->filename, "udp:", 4)
                      )
          )
              return 1;
          return 0;
       }                           
    3. Modifikasi file ff_ffplay.c dengan menyisipkan blok kode RTS berikut ke dalam metode static int read_thread(void *arg){}.

      static int read_thread(void *arg)
      {
        ......
        ic = avformat_alloc_context();
        if (!ic) {
          av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n");
          ret = AVERROR(ENOMEM);
          goto fail;
        }
      
        // *** Awal blok kode RTS ***
        ic->opaque = ffp;
        ic->control_message_cb = onArtcDemuxerMessage;
        // *** Akhir blok kode RTS ***
      
        ......
        if (ffp->skip_calc_frame_rate) {
           av_dict_set_int(&ic->metadata, "skip-calc-frame-rate", ffp->skip_calc_frame_rate, 0);
           av_dict_set_int(&ffp->format_opts, "skip-calc-frame-rate", ffp->skip_calc_frame_rate, 0);
        }
      
        // *** Awal blok kode RTS ***
        if(strncmp(is->filename, "artc://", 7) == 0) {
           extern AVInputFormat ff_rtc_demuxer;
           is->iformat = &ff_rtc_demuxer;
        } else {
           if(ffp->iformat_name)
             is->iformat = av_find_input_format(ffp->iformat_name);
         }
        // *** Akhir blok kode RTS ***
        ......
        pkt->flags = 0;
        // *** Awal blok kode RTS ***
        if(strncmp(is->filename, "artc://", 7) == 0) {
            bool videoExist = is->video_stream >= 0;
          bool audioExist = is->audio_stream >= 0;
          // av_log(NULL, AV_LOG_INFO, "videoDuration %lld audioDuration %lld rate %f videoframeQue %d audioFrameque %d\n",
          // is->videoq.duration, is->audioq.duration, ffp->pf_playback_rate,
          // frame_queue_nb_remaining(&is->pictq), frame_queue_nb_remaining(&is->sampq));
          if(!videoExist) {
             if(is->audioq.duration > 300 ) { // percepat
                 if(ffp->pf_playback_rate <= 1.0) {
                     ffp->pf_playback_rate = 1.3;
                     ffp->pf_playback_rate_changed = 1;
                     av_log(NULL, AV_LOG_INFO, "aliyun rts set rate to %f\n", ffp->pf_playback_rate);
                 }
             }
             else if(is->audioq.duration < 200) { // pulihkan kecepatan
                 if(ffp->pf_playback_rate > 1.0) {
                     ffp->pf_playback_rate = 1.0;
                     ffp->pf_playback_rate_changed = 1;
                     av_log(NULL, AV_LOG_INFO, "aliyun rts restore rate 1.0\n");
                  }
             }
          }
          else if((!videoExist || (videoExist && is->videoq.duration > 300)) && (!audioExist || (audioExist && is->audioq.duration > 300))) {
             if(ffp->pf_playback_rate <= 1) {
                 ffp->pf_playback_rate = 1.3;
                 ffp->pf_playback_rate_changed = 1;
                 av_log(NULL, AV_LOG_INFO, "aliyun rts set rate 1.1\n");
             }
          } else if((videoExist && is->videoq.duration <= 100) ||  (audioExist && is->audioq.duration <= 100)){
             if(ffp->pf_playback_rate > 1) {
                 ffp->pf_playback_rate = 1;
                 ffp->pf_playback_rate_changed = 1;
                 av_log(NULL, AV_LOG_INFO, "aliyun rts set rate 1\n");
              }
          }
        }
        // *** Akhir blok kode RTS ***
        ......
      }
    4. Modifikasi file ff_ffmsg.h dengan menambahkan deklarasi metode untuk pesan RTS.

      #define FFP_MSG_ARTC_DIRECTCOMPONENTMSG     3000
    5. Kirim pesan RTS ke lapisan atas.

      • Modifikasi file IJKMediaPlayback.h dengan menambahkan deklarasi listener yang mendengarkan panggilan eksternal pesan RTS.

        IJK_EXTERN NSString *const IJKMPMoviePlayerRtsMsgNotification;
      • Modifikasi file IJKMediaPlayback.m dengan menambahkan definisi listener yang mendengarkan panggilan eksternal pesan RTS.

        NSString *const IJKMPMoviePlayerRtsMsgNotification = @"IJKMPMoviePlayerRtsMsgNotification";
      • Modifikasi file IJKFFMoviePlayerController.m agar Anda dapat memanggil metode postEvent: untuk memproses pesan RTS yang dikembalikan oleh listener.

        - (void)postEvent: (IJKFFMoviePlayerMessage *)msg
        {
            ......
          case FFP_MSG_ARTC_DIRECTCOMPONENTMSG:{
             NSString *rtsMsg= [[NSString alloc] initWithUTF8String:avmsg->obj];
             int type = avmsg->arg1;
             if (!rtsMsg) {
                rtsMsg = @"";
             }
             NSDictionary *dic = @{@"type":@(type),@"msg":rtsMsg};
             [[NSNotificationCenter defaultCenter] postNotificationName:IJKMPMoviePlayerRtsMsgNotification
                            object:dic];
             break;
            }
           default:
             // NSLog(@"unknown FFP_MSG_xxx(%d)\n", avmsg->what);
             break;
        }
      • Gunakan kompiler Archive untuk menjalankan proyek IJKMediaPlayer.xcodeproj untuk mendapatkan file IJKMediaFramework.framework terbaru.

  • Tambahkan metode yang digunakan untuk melakukan percobaan ulang untuk Native RTS SDK di ijkplayer

    1. Modifikasi file ff_ffplay.h dengan menambahkan definisi variabel rts_reload_flag.

      int       rts_reload_flag;
    2. Modifikasi file ff_ffplay.c dengan menyisipkan blok kode berikut setelah metode static int audio_open(FFPlayer *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params){}.

      extern int artc_reload(AVFormatContext *ctx);
      
      void ffp_rts_reload(FFPlayer *ffp){
         if(rts_reload_flag == 0)
         {
            rts_reload_flag = 1;
         }
      }
    3. Modifikasi file ff_ffplay.c dengan menyisipkan blok kode RTS berikut ke dalam metode static int read_thread(void *arg){}.

      static int read_thread(void *arg)
      {
           ......
      #ifdef FFP_MERGE
         if (is->paused != is->last_paused) {
            is->last_paused = is->paused;
            if (is->paused)
               is->read_pause_return = av_read_pause(ic);
             else
                av_read_play(ic);
         }
      #endif
         // *** Awal blok kode RTS ***
         if(rts_reload_flag){
              rts_reload_flag = 0;
              av_log(ffp, AV_LOG_ERROR, "param  == ffp_rts_reload\n");
              VideoState *is = ffp->is;
              AVFormatContext *ic = is->ic;
              artc_reload(ic);
          }
         // *** Akhir blok kode RTS ***
         ......
      }
    4. Modifikasi file ijkplayer.h dengan menambahkan definisi metode ijkmp_rts_reload.

      void            ijkmp_rts_reload(IjkMediaPlayer *mp);
    5. Modifikasi file ijkplayer.c untuk mengimplementasikan metode ijkmp_rts_reload.

      void ijkmp_rts_reload(IjkMediaPlayer *mp)
      {
          ffp_rts_reload(mp->ffplayer);
      }
    6. Tambahkan metode rtsReload ke lapisan atas.

      • Modifikasi file IJKFFMoviePlayerController.h dengan menambahkan deklarasi panggilan eksternal metode rtsReload.

        - (void)rtsReload;
      • Modifikasi file IJKFFMoviePlayerController.m untuk mengimplementasikan panggilan eksternal metode rtsReload.

        - (void)rtsReload {
            ijkmp_rts_reload(_mediaPlayer);
        }
      • Gunakan kompiler Archive untuk menjalankan proyek IJKMediaPlayer.xcodeproj untuk mendapatkan file IJKMediaFramework.framework terbaru.

  • Panggil metode untuk mendengarkan callback pesan RTS untuk streaming langsung melalui protokol degradasi

    • Dengarkan callback pesan RTS.

      [[NSNotificationCenter defaultCenter] addObserver:self
                                               selector:@selector(reviceMsg:)
                                                   name:IJKMPMoviePlayerRtsMsgNotification
                                                 object:nil];
    • Implementasikan logika degradasi di metode yang digunakan untuk mendengarkan callback pesan RTS.

      Anda dapat mengubah prefiks URL sumber dari artc:// menjadi rtmp:// atau mengonversi URL ke format http://xxxx.flv, lalu memperbarui UrlSource di Pemutar Video Apsara. Dengan cara ini, Anda dapat menggunakan protokol degradasi untuk memainkan streaming langsung.

      // Gunakan protokol degradasi, seperti http://xxx.flv atau rtmp://xxx, untuk streaming langsung.
      - (void)convertArtcToRtmpPlay {
          // Dapatkan URL streaming dan potong prefiks URL.
          NSArray *urlSeparated = [self.url componentsSeparatedByString:@"://"];
          NSString *urlPrefix = urlSeparated.firstObject;
          // Periksa apakah prefiks URL adalah artc. Jika prefiksnya adalah artc, Anda dapat menggunakan protokol degradasi untuk streaming standar.
          if ([urlPrefix isEqualToString:@"artc"]) {
              // http://xxx.flv (direkomendasikan)
              _url = [[@"http://" stringByAppendingString:urlSeparated.lastObject] stringByAppendingString:@".flv"];
              // rtmp://xxx
              // _url = [@"rtmp://" stringByAppendingString:urlSeparated.lastObject];
      
                  // Hentikan pemutaran dan hancurkan pemain.
            [_ijkPlayer stop];
            [_ijkPlayer shutdown];
            _ijkPlayer = nil;
      
            // Atur ulang sumber pemutaran.
            _ijkPlayer = [[IJKFFMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:_url] withOptions:options];
            ......
                  // Mulai pemutaran.
            dispatch_async(dispatch_get_main_queue(), ^{
                      [_ijkPlayer prepareToPlay];
                      [_ijkPlayer play];
                  });
          }
      }

      Anda harus mengimpor API RtsSDK terlebih dahulu.

      #import <RtsSDK/rts_messages.h>

      Kemudian proses callback event pemain.

      -(void)reviceMsg:(NSNotification*)notification{
          NSDictionary *dic = [notification object];
        NSNumber *type = dic[@"type"];
        switch (type.intValue) {
          case E_DNS_FAIL:
          case E_AUTH_FAIL:
          case E_CONN_TIMEOUT:
          case E_SUB_TIMEOUT:
          case E_SUB_NO_STREAM:
          {
            // Lakukan degradasi.
            [self convertArtcToRtmpPlay];
          }
              break;
          case E_STREAM_BROKEN:
          {
             static BOOL retryStartPlay = YES;
             // Pertama kali media RTS timeout, coba putar ulang sekali. Jika media RTS masih timeout, gunakan protokol degradasi untuk pemutaran.
             if (retryStartPlay) {
                 dispatch_async(dispatch_get_main_queue(), ^{
                   [_ijkPlayer rtsReload];
                   });
                 retryStartPlay = NO;
              } else {
                 // Lakukan degradasi.
                 [self convertArtcToRtmpPlay];
              }
           }
            break;
          case E_RECV_STOP_SIGNAL:
                  {
                // Hentikan pemutaran dan hancurkan pemain.
                [_ijkPlayer stop];
              [_ijkPlayer shutdown];
              _ijkPlayer = nil;
            }
            break;
          default:
            break;
        }
      }