本节主要为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 needForceIFrame:true];
          //开始播放
          [player start];
          //停止播放 ,释放播放器,
          [player stop];
    • TF卡点播播放器
      //创建播放器
          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 seekTime:time];
          //开始播放
          [player start];
          //暂停播放
          [player pause];
          //暂停之后恢复播放
          [player restore];
          //停止播放 ,释放播放器,
          [player stop];
    • 自研HLS播放器
      //创建播放器
          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;
          [player setDataSource:iotId hlsFileName:file.fileName seekTime:seekTime];
          //开始播放
          [player start];
          //暂停播放
          [player pause];
          //暂停之后恢复播放
          [player restore];
          //停止播放,释放播放器
          [player stop];
  3. 查看播放器状态。
    /// 播放器状态
    typedef NS_ENUM(NSUInteger,IMSLinkVisualPlayerState){
        /// 空闲
        IMSLinkVisualPlayerStateIdle = 0,
        /// 缓冲中
        IMSLinkVisualPlayerStateBuffering = 2,
        /// 开始播放
        IMSLinkVisualPlayerStateStartPlay = 4,
        /// 暂停播放
        IMSLinkVisualPlayerStatePausePlay = 8,
        /// 切换到后台
        IMSLinkVisualPlayerStateBackground = 16,
    };

接口说明

  • 直播与卡录像点播
    1. 设置数据源
      • 设置直播业务的数据源
        /**
         设置直播业务数据源、加密(推荐使用)
        
         @see IMSLinkVisualPlayerLiveStreamType
         @param iotId 设备iotId
         @param streamType 直播码流
         @param needForceIFrame 是否强制I帧
        
         @return 是否成功设置数据源
         */
        - (BOOL)setDataSource:(NSString*)iotId
                   streamType:(IMSLinkVisualPlayerLiveStreamType)streamType
              needForceIFrame:(BOOL)needForceIFrame;
        
        /**
         设置直播业务数据源、不加密(不推荐)
        
         @see IMSLinkVisualPlayerLiveStreamType
         @param iotId:设备iotId
         @param streamType:直播码流
         @param needForceIFrame:是否强制I帧
         @return 是否成功设置数据源
         */
        - (BOOL)setNoEncryptDataSource:(NSString*)iotId
                            streamType:(IMSLinkVisualPlayerLiveStreamType)streamType
                       needForceIFrame:(BOOL)needForceIFrame;
      • 设置录播业务的数据源
        /**
         设置TF卡录播业务数据源、加密(推荐使用)
         
         @param iotId 设备iotId
         @param vodStartTime 录播开始时间、单位为1970年1月1日开始的秒数,单位秒
         @param vodEndTime 录播结束时间、单位为1970年1月1日开始的秒数,单位秒
         @param seekTime 录播直接从这个时间点开始播放、单位为1970年1月1日开始的秒数,单位秒
         @return 是否成功设置数据源
         */
        - (BOOL)setDataSource:(NSString*)iotId
                 vodStartTime:(NSInteger)vodStartTime
                   vodEndTime:(NSInteger)vodEndTime
                     seekTime:(NSInteger)seekTime;
        
        /**
         设置TF卡录播业务数据源、不加密(不推荐)
         
         @param iotId 设备iotId
         @param vodStartTime 录播开始时间、单位为1970年1月1日开始的秒数,单位秒
         @param vodEndTime 录播结束时间、单位为1970年1月1日开始的秒数,单位秒
         @param seekTime 录播直接从这个时间点开始播放、单位为1970年1月1日开始的秒数,单位秒
         @return 是否成功设置数据源
         */
        - (BOOL)setNoEncryptDataSource:(NSString*)iotId
                          vodStartTime:(NSInteger)vodStartTime
                            vodEndTime:(NSInteger)vodEndTime
                              seekTime:(NSInteger)seekTime;
      • 设置HLS云端录播业务数据源
        /**
         设置云端录播业务数据源
        
         @param iotId 设备iotId
         @param hlsFileName 录播文件名
         @param seekTime 跳转秒数(默认为0)单位秒
         @return 是否成功设置数据源
         */
        - (BOOL)setDataSource:(NSString*)iotId
                  hlsFileName:(NSString*)hlsFileName
                     seekTime:(NSInteger)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];
        }
    }
  • /// 播放器渲染模式
    typedef NS_ENUM(NSUInteger, IMSLinkVisualPlayerDisplayMode){
        /// 客户对YUV数据不可见,完全由SDK处理和渲染,默认使用这个模式
        IMSLinkVisualPlayerDisplayMode_SDK,
        /// 允许客户对YUV数据进行二次加工,然后再还给SDK渲染
        IMSLinkVisualPlayerDisplayMode_Client_SDK,
        /// YUV数据完全交由客户处理和渲染
        IMSLinkVisualPlayerDisplayMode_Client
    };
    
    /// 设置播放器渲染模式,默认 IMSLinkVisualPlayerDisplayMode_SDK 模式
    @property (assign, nonatomic) IMSLinkVisualPlayerDisplayMode lvDisplayMode;
    
    /**
     直播、点播的共用代理接口
     视频帧YUV数据回调,同步接口,帧数据的内存和SDK是共用的,如外部需要缓存数据,必须把数据拷贝出去
     @see IMSLinkVisualPlayerViewController
     @param frame 视频帧YUV数据
     */
    - (void)linkVisual:(IMSLinkVisualPlayerViewController *_Nullable)player withFrame:(IMSPlayerVideoFrame *_Nullable)frame;

播放器错误列表

错误主码(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 关闭失败