华为云用户手册

  • 回调示例 录制文件生成事件回调示例如下。回调消息体字段如表2所示。 { "project_id": "70b76xxxxxx34253880af501cdxxxxxx", "job_id": "dc0a1773-0cef-xxxx-xxxx-9a38fdb095d2", "task_id": "51126d0ebe94b1da00d2e21a10xxxxxx", "event_type": "RECORD_FILE_COMPLETE", "publish_domain": "push.example.com", "app": "live", "stream": "mystream", "record_format": "HLS", "download_url": "https://obs.cn-north-4.myhuaweicloud.com/live/record-xxxx-mystream-1589967495/record-push.example.com-live-mystream-1589967495.m3u8", "asset_id": "1a0d8e9bfaexxxxxxbe5021e62aa1e96", "file_size": 3957964, "record_duration": 120, "start_time": "2020-03-08T14:10:25Z", "end_time": "2020-03-08T14:12:25Z", "width": 1280, "height": 720, "auth_sign": "4f97f46759axxxxxx7ad21e9935dc175", "auth_timestamp": 1583676745 }
  • 入门指引 若您需要用自己的 域名 体验完整的云直播功能,可以参考本节快速实现,具体的操作流程,如图1所示。 图1 云直播入门流程 云直播入门操作流程说明,如表1所示。 表1 云直播入门流程说明 序号 操作方法 操作说明 1 添加直播域名 将准备的已备案的域名添加到 视频直播 服务,包括推流域名和播放域名。您可以注册备案一个一级域名(如example.com),然后使用两个不同的二级域名(如live-play.example.com和live-push.example.com)作为直播推流域名和播放域名。 2 关联域名 推流域名和播放域名添加完成后,您需要在播放域名中关联对应的推流域名,否则将会导致播放失败。 3 配置CNAME 推流域名和播放域名添加成功后,视频直播会为其分配对应的CNAME地址。您需要在域名DNS服务商处为推流域名和播放域名配置CNAME解析,开启直播推流加速和播放加速。 4 开启HTTPS安全加速 您可以为低时延直播开启HTTPS安全加速,保障您的直播数据在传输过程中受到加密保护。 仅低时延直播场景,需要执行此操作。 4 配置推流(可选) 配置转码模板 配置录制模板 配置截图模板 配置推流鉴权 配置播流(可选) 配置延时 配置拉流回源 配置HTTPS 配置播放鉴权 若您需要对直播进行录制、转码、截图、鉴权等操作,您可以在直播开始前,进行相关的配置。 5 推流 您可以使用第三方推流工具OBS进行推流。 标准直播场景,请参考推流操作。 低时延直播场景,请参考推流操作。 6 播放 标准直播场景:您可以使用第三方播放工具VLC进行播放。操作请参考播放。 低时延直播场景:您可以使用华为云低时延在线Demo或根据API接口开放web端播放。操作请参考播放(Web接入方式)。 父主题: 快速入门
  • 注意事项 此功能仅支持“华北-北京四”区域使用。 录制规则配置支持域名级、应用级和流级,优先生效细粒度配置(即流级别最优先),同级配置不支持多种录制类型。 直播服务不支持清理录制内容,仅记录直播录制事件,且直播录制事件的数据只保留30天。 直播录制过程中,若直播推流因网络抖动等问题中断,则直播服务将中止录制。当推流重新启动时,直播服务将重新开启新的录制任务。 配置录制后,启动推流即开始录制,结束推流才可停止录制,暂无法按需停启;若在推流过程中删除录制规则,录制仍然会继续,直到推流结束 。 仅支持对接收到的源直播流进行录制,暂不支持录制直播转码流。
  • 支持审计的关键操作列表 表1 表1 云审计 服务支持的云服务器操作列表 操作名称 资源类型 事件名称 创建直播域名 domain createDomain 删除直播域名 domain deleteDomain 修改直播域名 domain updateDomain 域名映射 domain createDomainsMapping 删除直播域名映射关系 domain deleteDomainsMapping 新增或覆盖直播推流通知配置 domain updateStreamNotification 删除直播推流通知配置 domain deleteStreamNotification 创建直播域名配置项 domain createCDNConfig 修改直播域名配置项 domain updateCDNConfig 删除直播域名配置项 domain deleteCDNConfig 修改IP黑白名单 domain updateIPAuthList 修改直播业务地域限制列表 domain updateGeoBlocking 设置referer防盗链黑白名单 domain updateRefererChain 删除referer防盗链黑白名单 domain deleteRefererChain 创建录制规则 transcode createTranscodingsTemplate 修改录制规则 transcode deleteTranscodingsTemplate 删除录制规则 transcode updateTranscodingsTemplate 添加转码SEI信息 transcode createSEI 禁止直播推流 stream createStreamForbidden 禁推恢复 stream deleteStreamForbidden 修改禁推属性 stream updateStreamForbidden 直播流闪断 stream createStreamForbiddenOnce 创建外网拉流注入任务 stream createPullTask 删除外网拉流注入任务 stream deletePullTask 设置计费模式 tenant updateChargingMode 创建录制规则 record createRule 修改录制规则 record updateRule 删除录制规则 record deleteRule 提交录制控制命令 record createCommand 创建录制回调配置 record createCallback 修改录制回调配置 record updateCallback 删除录制回调配置 record deleteCallback 添加直播截图配置 snapshot createRule 修改直播截图配置 snapshot updateRule 删除直播截图配置 snapshot deleteRule
  • 动作活体检测 目前支持检测视频文件,或视频的Base64编码,不支持直接检测视频流,需要用户客户端自己获取视频流并保存成文件,然后调用活体检测接口。 视频文件大小不超过8MB,建议客户端压缩到200KB~2MB。 限制视频时长1~15秒。 建议帧率10fps~30fps。 封装格式:mp4、avi、flv、webm、asf、mov。 视频编码格式:h261、h263、h264、hevc、vc1、vp8、vp9、wmv3。
  • 人脸检测/比对/搜索 人脸比对输入的两张图片总大小小于8MB。 图片大小小于8MB,由于图片过大会导致图片在网络传输过程中耗时较长,建议小于1MB。 图片分辨率小于4096*4096,图片中人脸像素大于80*80,建议120*120以上。 为保证识别效果,人脸图片建议要求如下: 光照大于200lux、无反光强光阴影现象。 人脸无遮挡、整体清晰无拖尾抖动等运动模糊。 侧脸不超过30°、俯仰角小于15°、偏转角小于15°、图片中人脸保持竖置正脸。
  • 使用服务 人脸识别 提供了Web化的服务管理平台,即管理控制台,以及基于HTTPS请求的API管理方式。人脸识别以开放API的方式提供给用户,用户需要将人脸识别集成到第三方系统后才可使用。 用户需要先在管理控制台开通 人脸识别服务 ,使用第三方系统调用API即可使用服务,具体流程如下: 申请服务 在使用服务之前,您需要先登录人脸识别管理控制台开通服务,服务开通一次即可,后续使用时无需再开通。 在使用人脸识别服务时需要对OBS的数据进行操作,因此需要先同意服务授权:在开通服务界面,单击右上角“服务授权”,完成OBS授权操作。 获取请求认证 调用人脸识别的API有如下两种认证方式,请任选其中一种进行认证鉴权,鉴权详情请参见《认证鉴权》。 Token认证:通过Token认证调用请求。 AK/SK认证:通过AK/SK加密调用请求。AK/SK认证安全性更高。 调用API 人脸识别以API的方式提供服务,具体请参见《人脸识别API参考》。 查看服务使用信息 用户可以在人脸识别管理控制台查看服务调用成功的次数。
  • 云监控 人脸识别服务使用云监控(Cloud Eye)监控各个子服务的API调用次数、时延等信息,具体如表2所示。云监控的更多信息请参见《云监控用户指南》。 表2 监控指标 指标名称 指标含义 取值范围 测量对象 成功调用次数 该指标用于统计API的成功调用次数。 单位:次(times)。 ≥ 0 times 人脸识别 失败调用次数 该指标用于统计状态码为5xx的调用API失败的次数。 单位:次(times)。 ≥ 0 times 人脸识别 平均时延 该指标用于统计API的平均时延。 单位:毫秒(ms)。 ≥ 0 ms 人脸识别 人脸数量 该指标用于统计人脸库的人脸数量。 建议人脸库的名称不要以下划线“_”开头,否则 云监控服务 会无法采集人脸数量。 单位:张(count)。 ≥ 0 count 人脸识别
  • 概述 欢迎使用 虚拟专用网络 (Virtual Private Network,以下简称VPN)。VPN用于在远端用户和虚拟私有云(Virtual Private Cloud,以下简称VPC)之间建立一条安全加密的公网通信隧道。默认情况下,在虚拟私有云(VPC)中的弹性云服务器无法与用户的数据中心或私有网络进行通信。如果需要将VPC中的弹性云服务器和数据中心或私有网络连通,可以启用VPN功能。 您可以使用本文档提供的API对VPN进行相关操作,如创建、查询、删除、更新等。支持的全部操作请参见API概览。 在调用VPN服务的API之前,请确保已经充分了解VPN服务相关概念,详细信息请参见《虚拟专用网络产品文档》的“产品介绍”章节。 目前VPN分为经典版和企业版两类产品,本文只针对企业版VPN。 父主题: 使用前阅读
  • 错误码说明 当您调用API时,如果遇到“APIGW”开头的错误码,请参见API网关错误码进行处理。 模块 状态码 错误码 错误信息 描述 处理措施 公共 400 VPN.0001 invalid request:xxx 输入参数不合法 联系技术支持。 500 VPN.0002 server error: xxx 服务器内部错误 联系技术支持。 403 VPN.0003 Authentication failed: xxx 拒绝访问 请赋予正确的细粒度权限。 404 VPN.0004 resource not found 资源未找到 请确认资源的id是否填写正确或该租户下是否确实存在该资源。
  • 状态码 表1 正常返回值 正常返回码 类型 说明 200 OK GET、PUT操作正常返回。 201 Created POST操作正常返回。 204 No Content DELETE操作正常返回。 表2 异常返回值 返回值 类型 说明 400 Bad Request 服务器未能处理请求。 401 Unauthorized 被请求的页面需要用户名和密码。 403 Forbidden 对被请求页面的访问被禁止。 404 Not Found 服务器无法找到被请求的页面。 405 Method Not Allowed 请求中指定的方法不被允许。 406 Not Acceptable 服务器生成的响应无法被客户端所接受。 407 Proxy Authentication Required 用户必须首先使用代理服务器进行验证,这样请求才会被处理。 408 Request Timeout 请求超出了服务器的等待时间。 409 Conflict 由于冲突,请求无法被完成。 500 Internal Server Error 请求未完成。服务异常。 501 Not Implemented 请求未完成。服务器不支持所请求的功能。 502 Bad Gateway 请求未完成。服务器从上游服务器收到一个无效的响应。 503 Service Unavailable 请求未完成。系统暂时异常。 504 Gateway Timeout 网关超时。 父主题: 附录
  • 以下为历史版本变更说明 版本变更说明 Meeting新增支持OPPO/VIVO手机推送会议通知功能,为此更新隐私声明。 “第三方SDK”章节中,新增OPUSH SDK、VIVO推送SDK。 “个人信息存储期限”章节中,增加推送功能个人数据留存期描述。 更新时间:2024年1月12日 点击查看华为云会议隐私声明全文 版本变更说明 因业务发展优化导致隐私声明更新,请您仔细阅读此次隐私声明的变更内容: Meeting新增支持企业微信用户快速登录华为云会议,新增电话权限适配Android 12系统,为此更新隐私声明。 “您提供的个人信息”章节中,新增1.2.2 企业微信登录功能相关描述及涉及的个人数据说明、新增1.2.5 音视频会议服务,含网络研讨会中电话权限、自启动相关描述。 “设备权限调用”章节中,新增Android系统电话权限描述、iOS系统本地网络权限描述。 “第三方SDK”章节中,新增企业微信登录分享SDK、统一扫描服务SDK。 更新时间:2024年1月5日 点击查看华为云会议隐私声明全文 版本变更说明 因业务发展优化导致隐私声明更新,请您仔细阅读此次隐私声明的变更内容: Meeting新增屏蔽周围人声功能,为此更新隐私声明。 “您提供的个人信息”章节中,新增1.2.13 屏蔽周围人声功能相关描述及涉及的个人数据说明。 “我们如何对个人信息进行存储”章节中,新增屏蔽周围人声涉及的个人数据留存期说明。 增加距离传感器、方向传感器、系统信息、运营商信息、Wi-Fi信息收集场景和使用说明。 优化隐私声明部分段落语言描述方式,以更为清晰和便于您理解的方式,向您展示我们如何收集和使用您的个人数据。 更新时间:2023年7月11日 点击查看华为云会议隐私声明全文 版本变更说明 因业务发展优化导致隐私声明更新,请您仔细阅读此次隐私声明的变更内容: Meeting服务新增支持石墨文档的功能,为此隐私更新 “我们收集和使用哪些信息”章节中,新增以石墨为代表的第三方服务相关描述,从第三方获取的个人信息中增加从石墨获取的个人数据 “第三方服务提供商及其服务”章节中,新增第三方供应商石墨 Meeting服务新增鸿蒙流转、虚拟背景功能,为此隐私更新 “我们收集和使用哪些信息”章节中,新增鸿蒙流转、虚拟背景中涉及的个人数据说明 “设备权限调用”章节中,新增鸿蒙流转使用的权限说明 “第三方服务提供商及其服务”章节中,新增360虚拟背景SDK(奇酷软件(深圳)有限公司) Meeting服务HiCar场景功能下线,为此隐私更新 “设备权限调用”章节、“第三方服务提供商及其服务”章节中,增加hicar场景功能下线说明 更新时间:2022年7月27日 点击查看华为云会议隐私声明全文 版本变更说明 因业务发展优化导致隐私声明更新,请您仔细阅读此次隐私声明的变更内容: 华为云会议服务新增SmartRooms、IdeaHub系列接入场景,为此更新隐私声明 “我们收集和使用哪些信息”章节中,新增SmartRooms、IdeaHub系列接入场景个人数据收集说明、权限使用场景说明、关闭自动收集路径的描述 “第三方服务提供商及其服务”章节中,新增第三方SDK说明 华为云会议服务新增用户体验改进计划,为此更新隐私声明 “我们如何使用您的个人信息”章节中,新增用户体验改进计划加入和退出的描述 华为云会议服务加强公共环境管理,调整了举报的留存期,为此更新隐私声明 “数据存储与保留”章节,举报留存期从30天调整到6个月 更新时间:2022年6月1日 点击查看华为云会议隐私声明全文
  • The following describes changes of earlier versions. [Version Changes] We have updated the Privacy Statement to improve your experience with this service. Please read the following to learn more about the relevant changes. Added the SmartRooms and IdeaHub access scenarios. Added the description of Personal Data collection, permissions, and path of disabling automatic collection in SmartRooms and IdeaHub access scenarios in Article "How We Collect Your Personal Data." Added the description of third-party SDKs in Article "Third-Party Service Providers and Their Services." Added the user experience improvement program. Added the description of joining and exiting the user experience improvement program in Article "How We Use Your Personal Data." Adjusted the report retention period for better public environment. Changed the report retention period from 30 days to 6 months in Section "Data Storage and Retention." Updated: June 1, 2022 View Huawei Cloud Meeting Privacy Statement
  • [Version Changes] Please carefully read the changes made to the Privacy Statement due to service development and optimization: Added the Shimo Docs function. Added the description of third-party services (mainly Shimo Docs) and added the personal information obtained from Shimo Docs to the personal information obtained from third parties in the section "How We Collect Your Personal Data." Added the third-party service provider Shimo Docs to the section "Third-Party Service Providers and Their Services." Added the transfer and virtual background functions of HarmonyOS. Added the description of personal information involved in HarmonyOS transfer and virtual background functions to the section "How We Collect Your Personal Data." Added the permission description for the HarmonyOS transfer function to section "Required Permissions." Added the 360 virtual background SDK of Qiku Software (Shenzhen) Co., Ltd. to the section "Third-Party Service Providers and Their Services." Removed the HiCar function. Added the description of bringing the HiCar function offline to sections "Required Permissions" and "Third-Party Service Providers and Their Services." Updated: July 27, 2022 View Huawei Cloud Meeting Privacy Statement
  • 标注数据.json文件说明 数据集中必含“.json”文件,用于集合该时间戳已标注点云的所有标注数据信息,包括该点云所在的项目id、数据包id、图片上所有标注框信息等。上传数据集前请保证“.json”文件内容正确。“.json”文件编写的参考样例如下: 3D立方体框数据: 该文件说明适用于3D目标识别,3D目标追踪,3D联合任务。 { "frame_id": 11, #帧序号 "batch_task_id": 2284, #批次任务ID "project_id": "da7febfd1405496ffd1240e6c17efc0f", #资源域ID "label_mode": "auto", #标注类型:auto和manual两种 "status": " labeled ", #标注任务状态:unlabeled、labeled "sample_type": "POINT_CLOUD", #样本类型:包含”IMAGE”(图片)和” POINT_CLOUD”(点云) "des_order": "", #此份数据对应的原始数据包描述 "tag_names": [ "a_in_premodel", "b_in_premodel" ], #标签名称 "valid": true, #是否有效,包含”true”和”false”两种 "create_time": 1669339994173, #标注的创建时间 "difficult": false, #是否难例,包含”true”难例和”false”非难例 "label_counts": [ #各类标注物的个数统计 { "label_meta_id": 5414, #标注物使用的标签ID, "label_num": 1, #标注物个数 "label_meta_name": "Car", #标签名称 "label_meta_desc": "自采目标识别", #标签描述 "label_meta_attr": "{\"优先级\":\"0,1\"}", #标签额外属性 "label_meta_shape": "cube_3d", #标签形状 "label_meta_color": "#d0021b", #标签颜色 "level": 0 } ], "point_cloud_meta_info": { #3D点云的标注属性信息,包含标定项id、图片名称、传感器类型、图片大小、图片源的obs路径url、时间戳 "id": "6a275591-53e1-406e-820e-ad077ae1da49", "name": "lidar-269-19.pcd", #点云名称 "source":"https://Octopus-raw-da7febfd1405496ffd1240e6c17efc0f.obs.cn-north-5.myhuaweicloud.com/label-data/task-2284/data/8/lidar-269-19.pcd", #点云源的obs路径url "calibration_item_id": 269, #标定项ID "sensor": "lidar", #传感器类型 "timestamp": 1669339994173, "size": 0 }, "image_meta_infos": [ #图片属性信息,包含标定项id、图片名称、传感器类型、图片大小、图片源的obs路径url、时间戳 { "id": "3b018a08-caa8-4e86-ae7a-1e9988b65578", "name": "camera03-268-19.jpg", "source": "https://Octopus-raw-da7febfd1405496ffd1240e6c17efc0f.obs.cn-north-5.myhuaweicloud.com/label-data/task-2284/data/8/camera03-268-19.jpg", "sensor": "camera03_0", #传感器名称 "timestamp": 1669339994173, "calibration_item_id": 268, #标定项ID "size": { #图片尺寸 "width": 1920, "depth": 3, "height": 1020 } } ], "label_task_id": 1372, #批次子任务ID "partitionId": 20221124, "label_update_time": 1688457112216, #标注最近更新时间 "prefix_folder": "8", "image_id": "9af1a414-d943-4965-96dd-ac0cd620eda5", "inspection": 0, "labels": [ #标注物信息 { "label_meta_id": 5414, #标注物对应的标签ID "create_time": 0, "name": "Car", #标注物名称 "shape_type": "cube_3d", #标注物形状:3D立体框 "serial_number": 0, "label_object_id": -1, "attribute": "", #标注物属性 "label_meta_name": "Car", "inspection": { #审核属性 "miss_label_error": false, #漏标 "vehicle_direction_error": false, #车头方向错误 "attribute_error": false, #属性错误 "out_range_label_error": false, #未贴合 "anchor_error": false, #锚点错误 "classification_error": false, #类别错误 "correct_label": true, "extra_label_error": false #多标 }, "cube_3d": { "orientation": 1.53980839, "alpha": 1.527701791334979, "rotation": { #3D框旋转角 "x": 0.0, "y": 0.0, "z": 1.53980839 }, "bndboxs": [ #3D联合标注中2D框的标注信息 { "label_meta_id": 5414, "bndbox": { "ymin": 508.54608, "xmin": 926.8102, "ymax": 727.8024, "xmax": 1189.3324 }, "label_meta_color": "#d0021b", "serial_number": 2, "sensor": "camera03_0", "attribute": "{}", "source": "https://Octopus-raw-da7febfd1405496ffd1240e6c17efc0f.obs.cn-north-5.myhuaweicloud.com/label-data/task-2284/data/8/camera03-268-19.jpg", "label_meta_name": "Car", "inspection": { "miss_label_error": false, "vehicle_direction_error": false, "attribute_error": false, "out_range_label_error": false, "anchor_error": false, "classification_error": false, "correct_label": true, "extra_label_error": false } } ], "serial_number": 2, #标注物合成对象的唯一自增id,如果标注物之间没有合成则与serial_number保持一致,追踪任务中同一物体在不同帧中此字段相同 "location": { #3D框中心点坐标 "x": 0.6671804785728455, "y": 15.472203254699707, "z": -1.1619998216629028 }, "attribute": "{\"优先级\":\"1\"}", "dimensions": { #3D框长宽高 "length": 4.557755470275879, "width": 2.0348410606384277, "height": 1.4403225183486938 } } } ], "labels_ext": { "track_points": [ { "serial_number": 1, "points": [ ] } ] } }
  • 回放仿真作业队列相关操作 在“作业队列”页签,还可以进行以下操作。 表1 作业队列相关操作 任务 操作步骤 置顶作业 单击操作栏中的“置顶”,即可将作业调整至队列中最高优先级。 置底作业 单击操作栏中的“置底”,即可将作业调整至队列中最低优先级。 上移作业 单击操作栏中的“上移”,即可将作业调整至队列中上一级。 下移作业 单击操作栏中的“下移”,即可将作业调整至队列中下一级。 更新作业优先级 勾选单个或多个作业。 单击“更新优先级”,输入[-50,50]的整数,数字越大,优先级越高。 单击“确定”,优先级更改成功。相同优先级的任务,作业队列更新时间越早,优先级越高。 搜索作业 在搜索输入框中输入“作业ID”,按回车键即可查询。
  • 作业输入输出规范 用户完成自定义脱敏算子创建,运行作业容器时Octopus平台向其中注入以下环境变量: input_file:待脱敏的文件路径 raw_dir:抽取的image,gnss,lidar数据存放路径 desensitized_dir:脱敏后的image,gnss,lidar数据存放路径 output_dir:脱敏后的文件存放路径 用户根据需要可以自定义环境变量,以rosbag文件为例,可以定义如下环境变量: rosbag_version:robag版本 image_topics:图像数据topic列表 gnss_topic:gnss数据topic lidar_topics:lidar数据topic列表 用户作业容器需要将input_file中的image,gnss,lidar数据抽取到raw_dir,待系统内置算子脱敏完成,并将脱敏后的数据存放到desensitized_dir后,用户算子根据input_file和desensitized_dir中的脱敏数据生成新的数据文件存放到output_dir。 文件结构如下: -raw --image ---topic0 ----timestamp1.jpg ----timestamp2.jpg ---topic1 ----timestamp1.jpg --gnss ---gnss_topic.json --lidar ---pcd_topic0 ----timestamp0.pcd ----timestamp1.pcd --SUC CES S -desensitized --image ---topic0 ----timestamp1.jpg ----timestamp2.jpg ---topic1 ----timestamp1.jpg --gnss ---gnss_topic.json --lidar ---pcd_topic0 ----timestamp0.pcd ----timestamp1.pcd --SUCCESS -output --test.bag --SUCCESS 其中,“SUCCESS”文件为标识文件,标识所在阶段的任务结束。 父主题: 数据脱敏作业
  • 本地调试 准备一个待处理的rosbag包。 sudo docker run -v ${HOME}/data/test.bag:/home/main/test.bag --env input_file=/home/main/test.bag –env raw_dir=/home/main/raw_dir –env desensitized_dir=/home/main/desensitized_dir –env output_dir=/home/main/output_dir -it rosbagmask:0.1 /bin/sh -c "python mask.py"
  • 示例代码 用户可以自定义一个脱敏算子,构建为一个合规脱敏镜像,在Octopus平台镜像仓库中导入自己构建的合规脱敏镜像。在合规服务新建算子时,选择镜像仓库中自己导入的合规脱敏镜像,即可使用脱敏算子对数据进行脱敏处理。 下面是rosbag脱敏的算子示例: # mask.py import json import logging import multiprocessing as mp import os import shutil import time from pathlib import Path from typing import cast import av import numpy as np import open3d from rosbags.highlevel import AnyReader from rosbags.interfaces import ConnectionExtRosbag1, ConnectionExtRosbag2 from rosbags.rosbag1 import Writer as Writer1 from rosbags.rosbag2 import Writer as Writer2 from rosbags.serde import cdr_to_ros1, serialize_cdr from rosbags.typesys import get_types_from_msg, register_types from rosbags.typesys.types import builtin_interfaces__msg__Time as Time from rosbags.typesys.types import \ sensor_msgs__msg__CompressedImage as CompressedImage from rosbags.typesys.types import std_msgs__msg__Header as Header logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', ) LOG = logging.getLogger(__file__) # Octopus数据服务拉起镜像时灌入的环境变量 # 获取环境变量 input_path = os.getenv('input_path', 'data/hangyan-move.bag.bak') raw_dir = os.getenv('raw_dir', 'empty_dir/raw') # 抽取的文件存放目录 desens_dir = os.getenv('desensitized_dir', 'empty_dir/desens') # 脱敏后的文件存放目录 output_dir = os.getenv('output_dir', 'empty_dir/output') lidar_process_num = os.getenv('lidar_process_num', 5) # lidar数据进程数 # 用户自定义环境变量 rosbag_version = os.getenv('rosbag_version', '1') # rosbag版本,取值为'1'或'2' image_topics = [ x.strip(' ') for x in os.getenv('image_topics', '/camera_encoded_1').split(',') ] # 图像数据的topic列表 gnss_topic = os.getenv('gnss_topic', '/inspvax') # gnss数据的topic,gnss数据只能有一个topic lidar_topics = [ x.strip(' ') for x in os.getenv('lidar_topic', '/pandar').split(',') ] # 点云数据的topic列表 # 注册自定义消息类型 Video_encoded_data_text = Path('msgs/Video_encoded_data.msg').read_text() NovatelMessageHeader_text = Path('msgs/NovatelMessageHeader.msg').read_text() NovatelExtendedSolutionStatus_text = Path( 'msgs/NovatelExtendedSolutionStatus.msg').read_text() NovatelReceiverStatus_text = Path('msgs/NovatelReceiverStatus.msg').read_text() Inspvax_text = Path('msgs/Inspvax.msg').read_text() add_types = {} add_types.update( get_types_from_msg( Video_encoded_data_text, 'kyber_msgs/msg/Video_encoded_data', )) add_types.update( get_types_from_msg( NovatelMessageHeader_text, 'novatel_gps_msgs/msg/NovatelMessageHeader', )) add_types.update( get_types_from_msg( NovatelExtendedSolutionStatus_text, 'novatel_gps_msgs/msg/NovatelExtendedSolutionStatus', )) add_types.update( get_types_from_msg( NovatelReceiverStatus_text, 'novatel_gps_msgs/msg/NovatelReceiverStatus', )) add_types.update( get_types_from_msg( Inspvax_text, 'novatel_gps_msgs/msg/Inspvax', )) register_types(add_types) # create gnss file gnss_file_path = Path(raw_dir, 'gnss') / f'{gnss_topic}.json'.strip('/') Path.mkdir(gnss_file_path.parent, parents=True, exist_ok=True) def extract_image(input_rosbag): '''从原始rosbag中抽取图像数据.''' LOG.info('Start extracting image.') codec_ctx = av.codec.Codec('hevc', 'r') h265_code = codec_ctx.create() with AnyReader([Path(input_rosbag)]) as reader: for connection, timestamp, data in reader.messages(): topic = connection.topic if topic in image_topics: deserialized_data = reader.deserialize(data, connection.msgtype) try: data = deserialized_data.raw_data packet = av.packet.Packet(data) out = h265_code.decode(packet) img = None for frame in out: if frame.format.name != 'rgb24': frame = frame.reformat(format='rgb24') img = frame.to_image() # 图像存放路径 file_name = f'{timestamp}.jpg' f_path = Path(raw_dir, 'image') / topic.strip('/') tmp_path = Path(raw_dir, 'tmp_image') / topic.strip('/') Path.mkdir(tmp_path, parents=True, exist_ok=True) tmp_file = tmp_path / file_name file = f_path / file_name # 当未建立目录时,先基于topic名称建立目录 Path.mkdir(file.parent, parents=True, exist_ok=True) img.save(tmp_file) os.chmod(tmp_file, 0o777) os.chmod(file.parent, 0o777) shutil.move(tmp_file, file) except Exception as e: LOG.info("%s frame can not trans to jpg, message: %s", timestamp, str(e)) LOG.info('Finish extracting image.') def extract_lidar(task_id, task_num, input_rosbag): '''从原始rosbag中抽取点云数据.''' LOG.info('Start extracting pcd.') with AnyReader([Path(input_rosbag)]) as reader: for i, (connection, timestamp, data) in enumerate(reader.messages()): if i % task_num != task_id: continue topic = connection.topic if topic in lidar_topics: deserialized_data = reader.deserialize(data, connection.msgtype) pcd = open3d.geometry.PointCloud() reshaped = deserialized_data.data.reshape( int(len(deserialized_data.data) / 3), 3) pcd.points = open3d.utility.Vector3dVector(reshaped) file_name = f'{timestamp}.pcd' f_path = Path(raw_dir, 'lidar') / topic.strip('/') tmp_path = Path(raw_dir, 'tmp_lidar') / topic.strip('/') Path.mkdir(tmp_path, parents=True, exist_ok=True) tmp_file = tmp_path / file_name file = f_path / file_name # 当未建立目录时,先基于topic名称建立目录 Path.mkdir(file.parent, parents=True, exist_ok=True) open3d.io.write_point_cloud(str(tmp_file), pcd) os.chmod(tmp_file, 0o777) os.chmod(file.parent, 0o777) shutil.move(tmp_file, file) LOG.info('Finish extracting pcd.') def extract_gnss(input_rosbag): '''从原始rosbag中抽取gnss数据.''' LOG.info('Start extracting rosbag.') gnss_file = open(gnss_file_path, 'w') gnss = dict() with AnyReader([Path(input_rosbag)]) as reader: for connection, timestamp, data in reader.messages(): topic = connection.topic if topic == gnss_topic: deserialized_data = reader.deserialize(data, connection.msgtype) # 这里以msgytpe为NavSatFix为例 latitude = deserialized_data.latitude longitude = deserialized_data.longitude altitude = deserialized_data.altitude gnss[timestamp] = { 'latitude': latitude, 'longitude': longitude, 'altitude': altitude } gnss_file.write(json.dumps(gnss)) gnss_file.close() LOG.info('Finish extracting gnss.') def _get_masked_image(topic, timestamp): '''从脱敏后的图像数据中获取目标图像数据.''' file = Path(desens_dir, 'image') / topic.strip('/') / f'{timestamp}.jpg' if file.is_file(): return np.fromfile(file, dtype='uint8') else: return None def _get_conn_map(rosbag_version: int, reader, writer): '''构建connection的索引.''' conn_map = {} if rosbag_version == '1': for conn in reader.connections: if conn.topic in image_topics: conn_map[conn.id] = writer.add_connection( '/image', CompressedImage.__msgtype__, ) else: ext = cast(ConnectionExtRosbag1, conn.ext) conn_map[conn.id] = writer.add_connection( conn.topic, conn.msgtype, conn.msgdef, conn.md5sum, ext.callerid, ext.latching, ) elif rosbag_version == '2': for conn in reader.connections: if conn.topic in image_topics: conn_map[conn.id] = writer.add_connection( '/image', CompressedImage.__msgtype__, ) else: ext = cast(ConnectionExtRosbag2, conn.ext) conn_map[conn.id] = writer.add_connection( conn.topic, conn.msgtype, ext.serialization_format, ext.offered_qos_profiles, ) return conn_map def _serialize_data(rosbag_version, data, msgtype): '''对数据进行序列化.''' if rosbag_version == '1': return cdr_to_ros1(serialize_cdr(data, msgtype), msgtype) elif rosbag_version == '2': return serialize_cdr(data, msgtype) def generate_rosbag(input_rosbag, output_rosbag): '''生成脱敏后rosbag.''' LOG.info('Start generating rosbag.') gnss_file = open( Path(desens_dir, 'gnss') / f'{gnss_topic}.json'.strip('/'), 'r') gnss_data = json.load(gnss_file) gnss_file.close() Writer = Writer1 if rosbag_version == '1' else Writer2 with AnyReader([Path(input_rosbag) ]) as reader, Writer(Path(output_rosbag)) as writer: conn_map = _get_conn_map(rosbag_version, reader, writer) for connection, timestamp, data in reader.messages(): topic = connection.topic # 当topic为图像数据的topic时,读取脱敏后图像数据 if topic in image_topics: masked_data = _get_masked_image(topic, timestamp) if masked_data is None: # 没有解析出图像文件时,不要该帧了 continue deserialized_data = CompressedImage( Header( stamp=Time( sec=int(timestamp // 10**9), nanosec=int(timestamp % 10**9), ), frame_id='0', ), format='jpg', data=masked_data, ) data = _serialize_data( rosbag_version, deserialized_data, CompressedImage.__msgtype__, ) # 当topic为gnss数据时,读取脱敏后gnss数据 elif topic == gnss_topic: deserialized_data = reader.deserialize(data, connection.msgtype) deserialized_data.latitude = gnss_data.get( str(timestamp)).get('latitude') deserialized_data.longitude = gnss_data.get( str(timestamp)).get('longitude') deserialized_data.altitude = gnss_data.get( str(timestamp)).get('altitude') data = _serialize_data( rosbag_version, deserialized_data, connection.msgtype, ) # 当topic为点云数据时,读取脱敏后点云数据 elif topic in lidar_topics: deserialized_data = reader.deserialize( data, connection.msgtype, ) file = Path( desens_dir, 'lidar', ) / topic.strip('/') / f'{timestamp}.pcd' point_cloud = open3d.io.read_point_cloud(str(file)) deserialized_data.data = np.asarray( point_cloud.points).flatten() writer.write(conn_map[connection.id], timestamp, data) # 生成_SUCCESS文件标识完成数据抽取 Path(output_dir, '_SUCCESS').touch() LOG.info('Finish generating rosbag.') if __name__ == "__main__": LOG.info('Start user operator.') process_image = mp.Process(target=extract_image, args=(input_path, )) pool_lidar = mp.Pool(processes=lidar_process_num) for i in range(lidar_process_num): pool_lidar.apply_async(extract_lidar, args=(i, lidar_process_num, input_path)) process_gnss = mp.Process(target=extract_gnss, args=(input_path, )) # 启动子进程 process_image.start() pool_lidar.close() process_gnss.start() process_image.join() pool_lidar.join() process_gnss.join() LOG.info('Child processes exit.') # 生成_SUCCESS文件标识完成数据抽取 Path(raw_dir, '_SUCCESS').touch() # 后面输出的rosbag文件与输入的rosbag文件保持同名 output_rosbag_file = Path(output_dir, Path(input_path).name) # 如果输出文件夹不存在,先创建文件夹 Path.mkdir(output_rosbag_file.parent, parents=True, exist_ok=True) # 检测到脱敏任务结束后,生成新的rosbag文件 while time.sleep(1) is None: if Path(desens_dir).joinpath('_SUCCESS').is_file(): generate_rosbag(Path(input_path), output_rosbag_file) break 父主题: 数据脱敏作业
  • DES传输的数据最终存放在哪里? 使用DES传输的数据会存放在 对象存储服务 (Object Storage Service,OBS)中,OBS是一个基于对象的海量存储服务,为客户提供海量、安全、高可靠、低成本的数据存储能力。关于OBS服务的详细介绍可参见对象存储服务产品概述。 目前DES不支持直接将数据上传到其他云服务,传输的数据最终存放在OBS中,OBS可以作为其他云服务的存储资源池,还可以作为其他云服务的数据分析学习的数据源。如果用户需使用DES将待数据传输到其他云服务,可先将数据上传到OBS,然后以OBS为资源背景使用其他云服务。 父主题: 服务概念类
  • 使用DES把数据上传到OBS后,数据目录结构会变化吗? 不会。虽然挂载上传数据时,生成“xxx/deshare/DES服务单/数据源目录”的挂载前缀做传输密钥,但DES把用户数据成功上传到OBS中后,OBS会保留用户存储在Teleport或磁盘设备中数据的目录结构。 因OBS不支持文件目录系统的“超链接”,如果用户传输数据的文件目录中有通过“超链接”来获取的文件,DES传输数据过程中“超链接”会失效,而“超链接”中文件会被跳过,不会上传到OBS。 父主题: 服务操作类
  • 邮寄磁盘的费用由谁来承担? 磁盘方式邮寄磁盘的费用都由用户承担,在邮寄签收前后用户需注意以下事项: 选择磁盘方式传输数据,您需要将所有待传输数据存放在磁盘,再将磁盘邮寄至华为数据中心。华为数据中心管理员接收并挂载磁盘到服务器,根据您输入的访问密钥(AK/SK)启动数据传输,该过程磁盘邮寄费用需您来承担。 确认数据已完全上传至OBS后,华为数据中心管理员通过运费到付方式将磁盘邮寄给您。收到磁盘后您需确保磁盘完好无误,再签收付邮寄费用,此过程磁盘邮寄费用也需要由您来承担。 父主题: 服务资费类
  • 服务单状态是“传输失败”是什么意思? 磁盘方式的服务单,当您输入访问密钥(AK/SK)启动数据上传后,如果校验失败服务单状态变为“传输失败”。 以下几种情况会出现“传输失败”情况,请根据实际情况排查解决后,重新输入访问密钥(AK/SK)启动上传。 访问密钥(AK/SK)输入错误,请重新尝试输入正确的AK/SK。 服务单中输入的“磁盘目录”与邮寄的磁盘中的目录不一致。此时请修改服务单中的“磁盘目录”,使之与邮寄的磁盘中的目录保持一致。 签名文件未按照要求存放在磁盘根目录。此时数据中心管理员将会联系您,并将磁盘寄回,您需要按要求重新存放签名文件后再邮寄磁盘。 父主题: 服务状态类
  • 哪些状态下能修改已创建的服务单? 支持在以下三种状态修改服务单。 Teleport方式服务单状态显示“服务单审核中”,此时如果用户发现服务单信息有误,可对服务单信息进行修改。 磁盘方式服务单状态显示“待寄送磁盘”,此时如果用户发现服务单信息有误,可对服务单信息进行修改。 当用户输入访问密钥(AK/SK)启动数据上传后,磁盘方式服务单状态显示“传输失败”,界面会提示“磁盘目录不存在”错误。此时因磁盘目录下的文件夹名称与服务单“磁盘文件”信息不一致,导致数据传输失败。用户需修改服务单“磁盘文件”信息,并输入访问密钥(AK/SK)重新启动数据上传。 父主题: 服务操作类
  • 收到磁盘或Teleport已挂载的短信后,如何启动数据上传? 当您收到磁盘或Teleport已挂载的短信后,请尽快登录DES管理控制台,选择服务单列表中“待输入访问密钥(AK/SK)”状态服务单,单击“输入访问密钥(AK/SK)”,根据界面提示,将上传数据到OBS时需要的访问密钥(AK/SK)输入到弹出的对话框中,DES支持一个服务单仅需上传一次AK/SK。 如果您没有访问密钥(AK/SK),请通过“我的认证”页面创建。 如果在创建服务单时已提交访问密钥(AK/SK),此时仅需关注上传动态。 父主题: 服务操作类
  • 操作步骤 登录DES管理控制台。 选择服务单列表“待输入访问密钥(AK/SK)”状态服务单,在操作列单击“输入访问密钥(AK/SK)”。 根据界面提示,将后台往OBS桶中上传数据时需要使用的访问密钥(AK/SK),输入到弹出的对话框中。如图1。 图1 输入访问密钥(Teleport方式) Access Key ID(AK):后台往OBS桶中上传数据时需要使用的接入证书,一个AK对应唯一用户。 Secret Access Key(SK):后台往OBS桶中上传数据时需要使用的安全证书,SK与AK一一对应,形成访问OBS时的密钥对,确保访问安全。 如果没有访问密钥(AK/SK),请通过单击右上角用户名,并在下拉列表中单击“我的凭证”,进入“我的凭证”界面,单击“管理访问密钥”页签下方的“新增访问密钥”,创建密钥。 单击“确定”,提交AK/SK。AK/SK提交成功,且后台验证AK/SK无误后,数据便开始上传。
  • 操作步骤 登录DES管理控制台。 在操作列单击“下载签名文件”,将签名文件下载到本地。 将签名文件导入磁盘的根目录。 签名文件是服务单与磁盘一一对应的唯一标识,一个服务单生成一个签名文件。管理员收到磁盘后,将磁盘挂载到服务器上,系统根据签名文件自动匹配磁盘与服务单,避免了人为干预带来的误操作。签名文件信息如表1。 表1 签名文件 参数 说明 version 服务版本号。 OrderURN 包括服务名称、服务区域、标识码和服务单号。 将下载到本地的签名文件拷贝到磁盘根目录。 当一个服务单有多个磁盘时,需拷贝签名文件到每个磁盘中。
  • 操作步骤 登录DES管理控制台。 选择服务单列表中“待输入访问密钥(AK/SK)”状态服务单,在操作列单击“输入访问密钥(AK/SK)”。 根据界面提示,将后台上传数据到OBS桶中需要的访问密钥(AK/SK),输入到弹出的对话框中。如图1。 图1 输入访问密钥(磁盘方式) Access Key ID(AK):后台往OBS桶中上传数据时需要使用的接入证书,一个AK对应唯一用户。 Secret Access Key(SK):后台往OBS桶中上传数据时需要使用的安全证书,SK与AK一一对应,形成访问OBS时的密钥对,确保访问安全。 如果没有访问密钥(AK/SK),请通过单击右上角用户名,并在下拉列表中单击“我的凭证”,进入“我的凭证”界面,单击“管理访问密钥”页签下方的“新增访问密钥”,创建密钥。 单击“确定”,提交AK/SK。AK/SK提交成功,且后台验证AK/SK无误后,数据便开始上传。
  • 使用流程 Teleport方式数据快递服务使用流程如图1和表1。 图1 Teleport方式使用流程图 表1 使用流程简介 操作步骤 说明 登录DES管理控制台 注册华为账号 ,并登录数据快递服务控制台。 创建桶 数据快递服务的数据最终存放在OBS中,需先在OBS创建桶。 创建服务单 就近选择华为数据中心,选择创建Teleport方式服务单。 接收设备并连线配置 用户收到华为数据中心Teleport设备后开箱配置。 拷贝数据 用户将本地数据拷贝至Teleport存储系统。 下载并导入签名文件 签名文件是服务单中Teleport设备的唯一标识,Teleport设备回寄前需要将签名文件存入teleportshare根目录。 设备下电和封装 用户确保本地数据已全部存入Teleport后,将Teleport下电并封装。 回寄设备 将Teleport回寄给华为数据中心,被回寄的Teleport存储系统中需要包含签名文件。 启动数据上传 管理员将Teleport挂载到服务器,并且用户输入了AK/SK后,会启动数据上传。 查看数据传输结果 完成数据传输后,用户可下载数据传输报告,检查数据是否全部上传成功。 父主题: Teleport方式详细指导
  • 使用流程 磁盘方式数据快递服务使用流程如图1和表1。 图1 磁盘方式使用流程图 表1 磁盘方式使用流程简介 操作步骤 说明 登录DES管理控制台 需注册华为账号,并登录数据快递服务控制台。 创建桶 数据快递服务的数据最终是存放在OBS中,需先在OBS创建桶。 创建服务单 支持就近选择华为数据中心,选择创建磁盘方式服务单。 拷贝数据 用户将本地数据拷贝至磁盘。 下载签名文件 签名文件是服务单中磁盘的唯一标识,磁盘寄送前需要将签名文件存入磁盘根目录。 寄送磁盘到华为数据中心 被寄送的磁盘中需要包含签名文件。 输入访问密钥(AK/SK) 管理员收到用户的磁盘并将磁盘挂载到服务器后,会短信通知用户上传AK/SK密钥,启动数据上传。 查看数据传输结果 数据传输完成后,用户可下载数据传输报告,检查数据是否全部上传成功。 接收回寄磁盘 用户确认无误后,管理员回寄磁盘。 父主题: 磁盘方式详细指导
共100000条