日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

iOS端

通過閱讀本文,您可以了解iOS端阿里云播放器SDK集成Native RTS SDK實現超低延時直播的方法。

前提條件

環境中已安裝CocoaPods。

SDK集成

使用pod方式添加阿里云播放器SDK和Native RTS SDK的依賴文件。

  1. 打開終端窗口。

  2. 進入項目所在路徑,創建Podfile文件。

    pod init

  3. 編輯Podfile文件,添加最新版本的依賴。

     pod 'RtsSDK'
     pod 'AliPlayerSDK_iOS'
     pod 'AliPlayerSDK_iOS_ARTC'
    說明
    • AliPlayerSDK_iOS_ARTCRtsSDK對應的依賴文件添加后,阿里云播放器SDK會自動將RTS SDK加載為插件。

    • 如果您需要添加指定版本的依賴,請自行補充版本號(例如:pod 'RtsSDK','2.1.0')。獲取最新的版本,阿里云播放器SDK請參見iOS播放器SDK超低延時直播SDK請參見SDK下載。

    • 集成阿里云播放器SDK和Native RTS SDK時需要滿足對應的配套關系,詳情請參見發布日志。

  4. 安裝SDK。執行之后,會生成*.xcworkspace文件,表示SDK集成完畢。

    pod install

阿里云播放器SDK接口使用

調用阿里云播放器SDK接口實現超低延時直播功能。更多阿里云播放器SDK功能,請參見進階功能API說明

說明
  • 以下為示例代碼,詳情代碼請參見開源項目MONE_demo_opensource_iOS工程中的AUILiveRtsPlay組件下的AUILiveRtsPlayPullViewController類。

  • 基于阿里云播放器實現RTS拉流時,不能調用pause暫停直播流。您可以先調用stop停止播放,再調用prapare重新播放。

  • 不支持seek(拖動)。

  • 初始化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;
    }
  • 設置播放URL

    AVPUrlSource *source = [[AVPUrlSource alloc] urlWithString:_url];
    [self.aliPlayer setUrlSource:source];
  • 播放參數配置

    配置播放參數,提升超低延時直播效果。播放器參數配置需要在調用prepare之前才能生效。

    AVPConfig *config = self.aliPlayer.getConfig;
    //直播最大延時
    [config setMaxDelayTime:1000];
    //卡頓恢復時長
    [config setHighBufferDuration:10];
    //起播最大延時
    [config setStartBufferDuration:10];
    [_aliPlayer setConfig:config];
    //默認為硬解,如播放器在準備過程中發現硬解失敗,會自動切換到軟解
     _aliPlayer.enableHardwareDecoder = YES;
  • 日志開關

    // 開啟日志
    [AliPlayer setEnableLog:YES];
    [AliPlayer setLogCallbackInfo:LOG_LEVEL_TRACE callbackBlock:nil];
    
    // 關閉日志
    [AliPlayer setEnableLog:NO];
    [AliPlayer setLogCallbackInfo:LOG_LEVEL_NONE callbackBlock:nil];
    說明

    若URL降級RTMP協議,真機調試時,不建議打開日志。

  • 播放控制

    [self.aliPlayer prepare];
    [self.aliPlayer stop];
    [self.aliPlayer destroy];
    [self.aliPlayer reload];
  • 起播前注冊回調

    -(void)createAliPlayer {
        // 1。創建播放器實例
        AliPlayer *aliPlayer = [[AliPlayer alloc] init];
        AVPConfig *config = [aliPlayer getConfig];
        config.maxDelayTime = 1000;
        config.highBufferDuration = 10;
        config.startBufferDuration = 10;
        // 2.注冊delegate
        aliPlayer.delegate = self;
        [aliPlayer setConfig:config];
        aliPlayer.autoPlay = YES;
        NSString *url = "artc://xxxx";
        AVPUrlSource *source = [[AVPUrlSource alloc] urlWithString:self.url];
        [aliPlayer setUrlSource:source];
        [aliPlayer prepare];
    }
    
    // 3.監聽播放器回調事件
     -(void)onPlayerEvent:(AliPlayer*)player eventWithString:(AVPEventWithString )eventWithString description:(NSString *)description {
    
     }
                        
  • 直播降級

    直播降級是將前綴為artc://的播放器URL源字符串直接修改為http-flv形式,然后更新播放器UrlSource,并開始播放的策略。

    self.playUrl = @"artc://xxxx";
    
    // 停止播放
    [self.aliplayer stop];
    
    // 獲取當前的播放url,截取url的前綴
    NSArray *urlSeparated = [self.playUrl componentsSeparatedByString:@"://"];
    NSString *urlPrefix = urlSeparated.firstObject;
    // 判斷url前綴是否是artc,如果是的話就降級為http-flv形式的傳統直播
    if ([urlPrefix isEqualToString:@"artc"]) {
        self.playUrl = @"http://xxxx.flv"; // http-flv具體url格式參照直播地址生成時的http-flv樣式
    
        // 重新設置播放源,進行準備播放
        AVPConfig *config = [self.player getConfig];
        config.maxDelayTime = 10000;
        config.highBufferDuration = 100;
        config.startBufferDuration = 100;
        [self.aliplayer setConfig:config];
        AVPUrlSource *source = [[AVPUrlSource alloc] urlWithString:self.playUrl];
        [self.aliplayer setUrlSource:source];
    
        // 開始播放
        [self.aliplayer prepare];
    }
                        

    啟播或者直播過程中,播放器事件回調收到播放組件中透傳輸出的消息時,解析播放器事件說明JSON字符串,得到的code是RtsSDK中的message。

    收到E_DNS_FAIL、E_AUTH_FAIL、E_CONN_TIMEOUT、E_SUB_TIMEOUT、E_SUB_NO_STREAM時,需要直播降級;

    收到E_STREAM_BROKEN時,需要先重新播放一次,然后如果之后再次收到時就直播降級;

    收到E_RECV_STOP_SIGNAL時,直接停止播放,不需要直播降級。

    需要提前導入RtsSDK的API:

    #import <RtsSDK/rts_messages.h>

    然后處理播放器事件回調:

    self.retryStartPlay = YES;
    ......
    
    /**
     @brief 播放器事件回調
     @param player 播放器player指針
     @param eventWithString 播放器事件類型
     @param description 播放器事件說明
     @see AVPEventType
     */
    - (void)onPlayerEvent:(AliPlayer*)player eventWithString:(AVPEventWithString)eventWithString description:(NSString *)description {
        switch (eventWithString) {
            case EVENT_PLAYER_DIRECT_COMPONENT_MSG:
                {
                    NSDictionary *descriptionDic = [[description rts_toDictionary] copy];
                    NSString *contentStr = [descriptionDic objectForKey:@"content"];
                    NSDictionary *kv = [contentStr rts_paramsToDictionaryWithSeparator:@"="];
                    NSNumber *type = [kv objectForKey:@"code"];
                    switch (type.intValue) {
                    case E_DNS_FAIL: // DNS解析失敗
                    case E_AUTH_FAIL: // 鑒權失敗
                    case E_CONN_TIMEOUT: // 建聯信令超時
                    case E_SUB_TIMEOUT:  // 訂閱信令返回錯誤,或者超時
                    case E_SUB_NO_STREAM: // 訂閱流不存在
                        {
                            // 直播降級處理邏輯
                        }
                            break;
                    case E_STREAM_BROKEN: // 媒體超時,沒有收到音頻包和視頻包
                        {
                            // 第一次收到RTS媒體超時先重試播放一次,然后如果再次收到就直接降級播放
                            if (self.retryStartPlay) {
                                [self onStartPlay];
                                self.retryStartPlay = NO;
                            } else {
                                // 直播降級處理邏輯
                            }
                        }
                            break;
                    case E_RECV_STOP_SIGNAL:
                        {
                            // 停止播放
                           [self.aliplayer stop];
                        }
                            break;
                    default:
                        break;
                    }
                }
                    break;
                default:
                    break;
        }
    }
    ......
    
    #pragma mark -- 對NSString進行category(分類),抽出公共方法,解析json字符串
    - (NSDictionary *)rts_toDictionary {
        if (self == nil) {
            return nil;
        }
    
        NSData *jsonData = [self dataUsingEncoding:NSUTF8StringEncoding];
        NSError *err;
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
                                                            options:NSJSONReadingMutableContainers
                                                              error:&err];
        if(err) {
            NSLog(@"json解析失?。?@",err);
            return nil;
        }
        return dic;
    }
    
    - (NSDictionary *)rts_paramsToDictionaryWithSeparator:(NSString*)split {
        if (self == nil) {
            return nil;
        }
        NSMutableDictionary *multiDic = @{}.mutableCopy;
        NSString *content = [self stringByReplacingOccurrencesOfString:@"\"" withString:@""];
        NSArray *arr = [content componentsSeparatedByString:@","];
        if (arr.count>0) {
            for (NSString *str in arr) {
                NSArray *kvArr = [str componentsSeparatedByString:split];
                if (kvArr.count==2) {
                    [multiDic setValue:kvArr[1] forKey:kvArr[0]];
                }
    
            }
        }
        return multiDic;
    }
  • 獲取TraceId

    播放器事件回調收到播放組件中透傳輸出的消息時,解析播放器事件說明JSON字符串,得到的code是RtsSDK中的message,收到E_HELP_SUPPORT_ID_SUBSCRIBE時,解析字符串中"-sub-"后的字符串得到TraceId。

    - (void)onPlayerEvent:(AliPlayer*)player eventWithString:(AVPEventWithString)eventWithString description:(NSString *)description {
        switch (eventWithString) {
            case EVENT_PLAYER_DIRECT_COMPONENT_MSG:
                {
                    NSDictionary *descriptionDic = [[description rts_toDictionary] copy];
                    NSString *contentStr = [descriptionDic objectForKey:@"content"];
                    NSDictionary *kv = [contentStr rts_paramsToDictionaryWithSeparator:@"="];
                    NSNumber *type = [kv objectForKey:@"code"];
                    switch (type.intValue) {
                    case E_HELP_SUPPORT_ID_SUBSCRIBE: // 獲取traceId
                        {
                            NSString *desc = [kv objectForKey:@"desc"];
                            if ([desc containsString:@"-sub-"]) {
                                NSString *traceId = [desc componentsSeparatedByString:@"-sub-"].lastObject;
                                self.traceId = traceId;
                            }
                        }
                        break;
                    default:
                        break;
                    }
                }
                    break;
                default:
                    break;
        }
    }