本节主要为Link Visual iOS版本的音视频模块使用说明,包含视频播放、语音对讲的功能。

依赖SDK 概述
API 通道 提供API通道能力
长连通道 P2P需要长连接通道

配置工程

  • 通过CocoaPods工具配置工程
    1. podfile中添加引用源。
      source 'https://github.com/aliyun/aliyun-specs.git'
    2. 添加库依赖。
      //如遇IMS***版本冲突,请按照pod提示修改podfile对应sdk版本
      //如podfile中没有的sdk库,请查看podfile.lock对应修改podfile
      pod 'IMSLinkVisualMedia', '1.2.0'
    3. 执行pod update,则库安装完毕。
  • 通过引入本地库项目配置工程(本地包请使用该方式集成,例如本地包为podspec)
    1. podfile中添加本地路径。
      pod 'IMSLinkVisualMedia', :path => 'LocalPods/IMSLinkVisualMedia.podspec'
    2. 拷贝以下SDK文件至项目的LocalPods目录下。SDK路径
    3. 将podspec拷贝以下文件至项目内LocalPods目录下。
      IMSLinkVisualMedia.podspec
      IMSLinkVisualMedia 
      //文件夹 IMSLinkVisualMedia文件夹内包含以下framework
      IMSLinkVisualMedia.framework
      LibRtmp.framework
      LinkVisualClientSDK.framework
      FFmpeg.framework
    4. 执行pod update,则库安装完毕。

使用说明

播放器按功能分为三种,提供了以下功能。

  • 直播播放器

    用于RTMP直播源,具有时延低的特点,支持P2P(需使用接入LinkVisual设备端SDK的摄像头)。

  • 点播播放器

    用于设备录像回放,可调整播放进度,支持P2P(需使用接入LinkVisual设备端SDK的摄像头)。

  • HLS播放器

    用于基于HLS的云端录像回放的播放,支持MPEG-TS和FMP4容器,AES-128加密方式。

功能 直播播放器 设备录像播放器 HLS播放器
视频播放
音频播放
暂停/恢复 x
跳至指定位置播放 X
总时长 x
当前播放进度 x
播放器状态变更通知
静音
变速播放 x x
循环播放 x x
画面缩放模式设置
播放器截图
边播边录 x

使用指南(播放器)

  1. 引入框架。
    //框架引入
    #import <IMSLinkVisualMedia/IMSLinkVisualMedia.h>
  2. 引入播放器。
    • 直播播放器
           //创建播放器
          IMSLinkVisualPlayerViewController *player = [[IMSLinkVisualPlayerViewController alloc] init];
          //因为播放器为viewController,所以addChildViewController
          [self addChildViewController:player];
          //打开播放器日志  默认为 IMSLinkVisualMediaLogInfo 
          [IMSLinkVisualPlayerViewController setLogLevel:IMSLinkVisualMediaLogInfo];
          //设置播放器frame
          player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
          player.view.frame = self.view.bounds;
          //添加播放器view到指定位置
          [self.view insertSubview:player.view atIndex:0];
          //播放器代理
          player.delegate = self;
          //设置播放器参数
          [player setDataSource:self.iotId streamType:IMSLinkVisualPlayerLiveStreamTypeMain encryptType:0 needForceIFrame:true];
          //开始播放
          [player start];
          //停止播放 ,释放播放器,
          [player stop];
    • 点播播放器
      //创建播放器
          IMSLinkVisualPlayerViewController *player = [[IMSLinkVisualPlayerViewController alloc] init];
      //因为播放器为viewController,所以addChildViewController
          [self addChildViewController:player];
          //设置播放器frame
          player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
          player.view.frame = self.view.bounds;
          //添加播放器view到指定位置
          [self.view insertSubview:player.view atIndex:0];
          //播放器代理
          player.delegate = self;
          //设置播放器参数 vodStartTime为当天0点时间戳,vodEndTime为当天24点-1秒时间戳 seekTime为本次播放的起始时间(秒)
          [player setDataSource:iotId vodStartTime:timestamp vodEndTime:timestamp + dayOfSecond encryptType:0 seekTime:time];
          //开始播放
          [player start];
          //录像时间跳转 seekTime 为本天需要跳转的秒数
          [player seekToDuration:seekTime];
          //暂停播放
          [player pause];
          //暂停之后恢复播放
          [player restore];
          //停止播放 ,释放播放器,
          [player stop];
  3. 查看播放器状态。
    • 查看直播与点播的播放器状态
      /// 播放器状态
      typedef NS_ENUM(NSUInteger,IMSLinkVisualPlayerState){
              /// 空闲
          IMSLinkVisualPlayerStateIdle = 0,
          /// 缓冲中
          IMSLinkVisualPlayerStateBuffering = 2,
          /// 开始播放
          IMSLinkVisualPlayerStateStartPlay = 4,
          /// 暂停播放
          IMSLinkVisualPlayerStatePausePlay = 8,
          /// 切换到后台
          IMSLinkVisualPlayerStateBackground = 16,
      };
    • 查看HLS的播放器状态
      typedef NS_ENUM(NSInteger, IMSLinkVisualHLSPlayerStatus) {
          /// 空闲
          IMSLinkVisualHLSPlayerIdle,
          /// 加载中
          IMSLinkVisualHLSPlayerLoading,
          /// 加载完毕
          IMSLinkVisualHLSPlayerReady,
          /// 播放中
          IMSLinkVisualHLSPlayerPlaying,
          /// 暂停
          IMSLinkVisualHLSPlayerPause,
          /// 播放结束
          IMSLinkVisualHLSPlayerFinished,
      };
      								

接口说明

  • 直播与卡录像点播
    1. 设置数据源
      • 设置URL的数据源
        /**
         设置RTMP数据源、默认不加密
        
         @see IMSLinkVisualPlayerSourceType
         @param rtmpUrl RTMP格式的url
         @param sourceType 播放器类型
         @return 数据源是否设置成功
         */
        
        - (BOOL)setDataSource:(NSString *_Nullable)rtmpUrl
                   sourceType:(IMSLinkVisualPlayerSourceType)sourceType;
        									
      • 设置直播业务的数据源
        /**
             * 设置IPC直播数据源.
             *
             * @param iotId                    IPC设备的iotId
             * @param streamType               流的类型: 0-主码流,1-辅码流
             * @param encryptType              云转加密类型: 0-AES128
             * @param needForceIFrame          是否需要强制I帧
             */
        [self.player setDataSource:self.iotId streamType:IMSLinkVisualPlayerLiveStreamTypeMain];
        
        - (BOOL)setDataSource:(NSString *)iotId
                   streamType:(IMSLinkVisualPlayerLiveStreamType)streamType
                  encryptType:(NSInteger)encryptType
              needForceIFrame:(BOOL)needForceIFrame;
      • 设置录播业务的数据源
        /**
             * 设置播放源为IPC录像(按录像文件名)
             *
             * @param iotId                 IPC设备的iotId
             * @param vodFileName           请求录像的文件名称
             */
        [self.player setDataSource:self.iotId vodFileName:record.fileName];
        /**
             * 设置播放地址为已接入生活物联网的IPC设备指定录像时间段的本地录像文件地址.
             *
             * @param iotId                 IPC设备的iotId
             * @param vodStartTime          录像开始时间,1970年1月1日开始的秒数
             * @param vodEndTime            录像结束时间,1970年1月1日开始的秒数
             * @param encrypted             是否流需要加密, 强烈建议开启,对于出海产品,务必保持开启
             * @param encryptType           云转加密类型: 目前只支持0(AES-128)加密
             * @param seekTime              相对于beginTime的起始播放偏移量,单位为秒
             */
        [player  setDataSource:iotId
                       vodStartTime:self.record.beginTime
                          vodEndTime:self.record.endTime
                          needEncrypt:NO
                          encryptType:0
                               seekTime:seekTime];
    2. 设置播放器缓存
      #import <IMSLinkVisualMedia/IMSLinkVisualMedia.h>
      /**
       //设置播放器缓存 缓存越大,延迟越高 一帧缓存延迟40ms 默认为5帧
       @param buffer 缓存大小 0 -- 16
       */
      [self.player setDisplyBuffer:10];
    3. 开始播放
      #import <IMSLinkVisualMedia/IMSLinkVisualMedia.h>
      
      // 开始播放
      [self.player start];
    4. 静音播放器
      #import <IMSLinkVisualMedia/IMSLinkVisualMedia.h>
      
      //播放器静音,对讲不播放接收到的声音通过mute实现
      self.player.mute = true;
    5. 停止播放
      #import <IMSLinkVisualMedia/IMSLinkVisualMedia.h>
      
      // 停止播放,结束播放器
      [self.player stop];
      							
    6. 暂停播放(仅录播)
      #import <IMSLinkVisualMedia/IMSLinkVisualMedia.h>
      
      // 暂停播放
      [self.player pause];
    7. 恢复播放(仅录播)
      #import <IMSLinkVisualMedia/IMSLinkVisualMedia.h>
      
      // 恢复播放
      [self.player restore];
  • 云端播放器设置

    设置播放地址为IPC云存录像(按文件名,如hls)

    #import <IMSLinkVisualMedia/IMSLinkVisualMedia.h>
    
    // 设置播放路径为云端获得fileName, 设备iotId
     [hlsPlayer playWithFileName:file.fileName iotId:iotId];

    设置播放URL路径

    #import <IMSLinkVisualMedia/IMSLinkVisualMedia.h>
    
    // 设置播放路径为获得url地址
     [hlsPlayer playWithRequestUrl:requestUrl];

    开始播放

    #import <IMSLinkVisualMedia/IMSLinkVisualMedia.h>
    
    -(void)linkVisualHLSPlayerReadyToPlay:(IMSLinkVisualHLSPlayer*)player{
    
    }
    // 播放,加载完毕回调之后,调用才会生效
    [hlsPlayer play];

    seek跳转播放

    #import <IMSLinkVisualMedia/IMSLinkVisualMedia.h>
    
    // seekTime为本段录像时长范围内seek跳转的时间点,单位:秒
     [hlsPlayer seekToTime:CMTimeMake(seekTime, 1)];
    //seek之后触发seek回调
    -(void)linkVisualHLSPlayerSeek:(IMSLinkVisualHLSPlayer*)player completion:(BOOL)finished{
        //[hlsPlayer play];
    }

    暂停播放

    #import <IMSLinkVisualMedia/IMSLinkVisualMedia.h>
    
    // 暂停播放
    [hlsPlayer pause];

    清除

    #import <IMSLinkVisualMedia/IMSLinkVisualMedia.h>
    
    // 清除播放 ,重新设置播放文件才能play
    [hlsPlayer clear];
  • 监听HLS播放器状态(代理)
    #pragma mark - IMSLinkVisualHLSPlayerDelegate
    
    #pragma mark 播放器时间回调
    
    - (void)linkVisualHLSPlayer:(IMSLinkVisualHLSPlayer*)player currentTime:(NSTimeInterval)currentTime {
    
    }
    #pragma mark 播放器加载失败
    
    - (void)linkVisualHLSPlayerFailed:(IMSLinkVisualHLSPlayer *)player {
    }
    #pragma mark 播放器播放完毕
    
    - (void)linkVisualHLSPlayerFinished:(IMSLinkVisualHLSPlayer *)player {
    }
    #pragma mark 播放器加载完成
    
    - (void)linkVisualHLSPlayerReadyToPlay:(IMSLinkVisualHLSPlayer *)player {
    //加载完毕后调用play才会生效
    }
    #pragma mark 播放器seek完毕
    - (void)linkVisualHLSPlayerSeek:(IMSLinkVisualHLSPlayer *)player completion:(BOOL)finished {
    
    }
  • 视频截图
    #import <IMSLinkVisualMedia/IMSLinkVisualMedia.h>
    
    //获取视频截图
    UIImage *image = [self.player videoSnapshot];
    //获取视频截图
    UIImage *image = [hlsPlayer videoSnapshot];
    					
  • 边录边播 (不支持hlsPlayer)
    #import <IMSLinkVisualMedia/IMSLinkVisualMedia.h>
    
    - (IBAction)recordVideoButtonClick:(UIButton *)sender {
        sender.selected = !sender.selected;
        NSString *tmpPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"tmp.mp4"];
        if (sender.selected) {
            [self.player startRecordVideoWithfilePath:tmpPath];
        } else {
            [self.player stopRecordVideo];
        }
    }

播放器错误列表

错误主码(PlayerMainError) 描述 子码(解析userInfo中subCode获取) 描述
ErrorSource 数据源相关错误 IMSLinkVisualPlayerErrorConnect 建立连接失败
IMSLinkVisualPlayerErrorEncrypt 无效的解密密钥
IMSLinkVisualPlayerErrorUrl 无效的播放地址
IMSLinkVisualPlayerErrorDataSource 数据源错误或未设置
IMSLinkVisualPlayerErrorGetURL 获取链接失败
IMSLinkVisualPlayerErrorStop 关闭失败
IMSLinkVisualPlayerErrorStart 启动失败
ErrorRender 渲染相关错误渲染相关错误 IMSLinkVisualPlayerErrorDecode 解码错误
ErrorUnexpected 不符合预期错误 IMSLinkVisualPlayerErrorStream 接收数据流失败

HLS播放器错误列表

HLS播放器错误码 描述
IMSLinkVisualPlayerErrorUrl (1007) 无效的播放地址
IMSLinkVisualPlayerErrorStart (1009) 请求播放地址失败
IMSLinkVisualPlayerErrorDataSource (1008) 数据源错误或未设置
IMSLinkVisualPlayerErrorConnect (1005) 拉流失败,未拉取到流或连接被异常断开
IMSLinkVisualPlayerErrorStream(1100) 流连接失败(一段时间内没收到流,如20秒)

语音对讲

提供App和IPC设备之间端到端的双向实时音频传输能力。

语音对讲支持双工模式,App端需要实现以下流程。

App端需实现的流程
支持的音频格式 编码 解码
AAC_LC
G711A
G711U

使用指南(语音对讲)

  • 创建语音对讲编码参数

    参数为录制语音数据的参数,用来与设备端对齐。

    //常用对讲模式为以下参数,不建议更改,支持8K和16K
    //sampleRate 8000 或 16000 以设备支持为准
        IMSLinkVisualAudioParams *intercomEncodeParams = [[IMSLinkVisualAudioParams alloc] init];
        intercomEncodeParams.sampleRate = 8000;
        intercomEncodeParams.channel = 1;
        intercomEncodeParams.bitsPerSample = 16;
        intercomEncodeParams.format = IMSLinkVisualAudioFormatG711a;
  • 设置语音对讲参数

    创建编码器用于编码语音数据。

        //player 为播放器实例 IMSLinkVisualPlayerViewController
        player.intercomEncodeParams = intercomEncodeParams;
  • 设置语音对讲回调代理

    用于语音对讲开始与结束流程的消息回调代理,开始对讲前,先增加语音对讲状态回调方法。

     player.intercomDelegate = self;
  • 开语音对讲

    设置播放器为对讲模式并开启对讲功能。

    [player startIntercom:IMSLinkVisualIntercomAudioModeIntercom];
  • 停止语音对讲
     [player stopIntercom];

语音对讲状态回调方法与触发规则如下。

#pragma mark - IMSLinkVisualIntercomDelegate
#pragma mark 语音对讲连接服务器
- (void)linkVisualIntercomConnect:(IMSLinkVisualPlayerViewController *)player {
    //语音对讲连接服务器成功
    //连接成功不代表可以可以立即发送语音
}#pragma mark 语音对讲ready
//当对讲连接于服务端连接建立后,若对端已就绪,会告知本端事件talk ready. 此时向对端发送音频数据都会被对端收到并处理.
- (void)linkVisualIntercomReady:(IMSLinkVisualPlayerViewController * _Nullable)player {
}
#pragma mark 对讲接收到设备端音频参数
//当语音对讲通道建立后,若对端支持录音,会先收到对端发送过来的音频参数信息,
//后续对端发送的音频数据按照此音频参数来做解码. 该事件是语音对讲通道建立成功的标志. 
//可以在此时构建音频播放器实例用于对端采集音频的实时播放.

- (void)linkVisualIntercom:(IMSLinkVisualPlayerViewController *)player audioParams:(IMSLinkVisualAudioParams *)params {
}

#pragma mark 对讲接收到设备端音频数据
//若对端支持录音,语音对讲中会持续不断的收到对端发送过来的音频数据.
- (void)linkVisualIntercom:(IMSLinkVisualPlayerViewController *)intercom audioData:(NSData *)data {
    //无特殊需求可以不收集数据
    if (data) {
        //playBuffers为自定义可变数组收集数据
        [self.playBuffers addObject:data];
    }
}
#pragma mark 录音数据完成回调
//语音对讲开始后,会收集不断收到mic采集的数据,根据对讲的状态开始发送的数据

- (void)linkVisualIntercom:(IMSLinkVisualPlayerViewController *)intercom didRecordData:(NSData *)data{
    if (data) {
        //发送录音数据 audioBuffers为自定义可变数组收集数据
        [player sendAudioData:audioData];
    }
}   
#pragma mark 语音对讲停止
- (void)linkVisualIntercomStop:(IMSLinkVisualPlayerViewController *)player {
}
#pragma mark 语音对讲出错
- (void)linkVisualIntercom:(IMSLinkVisualPlayerViewController *)player
             errorOccurred:(NSError *)error {
 //处理对讲出错的错误信息
//error.code 与 IMSLinkVisualIntercomError 对应
    
}

错误列表

语音对讲错误状态码 描述
IMSLinkVisualIntercomErrorGetURL 获取链接失败
IMSLinkVisualIntercomErrorParams 对讲参数错误
IMSLinkVisualIntercomErrorStart 启动对讲失败
IMSLinkVisualIntercomErrorConnect 语音流建立失败
IMSLinkVisualIntercomErrorRecorder 录音失败
IMSLinkVisualIntercomErrorStream 接收数据流失败
IMSLinkVisualIntercomErrorDecode 解码错误
IMSLinkVisualIntercomErrorSendData 发送语音对讲数据失败
IMSLinkVisualIntercomErrorStop 关闭失败