你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

适用于 Java 的 Azure 远程渲染 客户端库 - 版本 1.1.23

使用 Azure 远程渲染 (ARR) 服务可以在云中渲染高质量的交互式 3D 内容,并将其实时流式传输到 HoloLens 2 等设备。

此 SDK 提供将资产转换为运行时所需的格式以及管理远程呈现会话生存期的功能。

注意:运行会话后,客户端应用程序将使用“运行时 SDK”之一连接到该会话。 这些 SDK 旨在最好地支持执行 3D 渲染的交互式应用程序的需求。 它们在 .NETC++ 中可用。

源代码 | API 参考文档 | 产品文档

入门

先决条件

添加包

包括 BOM 文件

请将 azure-sdk-bom 包含在项目中,以依赖于库的正式发布 (GA) 版本。 在以下代码段中,将 {bom_version_to_target} 占位符替换为版本号。 若要详细了解 BOM,请参阅 AZURE SDK BOM 自述文件

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.azure</groupId>
            <artifactId>azure-sdk-bom</artifactId>
            <version>{bom_version_to_target}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

然后在 dependencies 节中包含直接依赖项,不带版本标记,如下所示。

<dependencies>
  <dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-mixedreality-remoterendering</artifactId>
  </dependency>
</dependencies>

包括直接依赖项

注意:此版本面向 Azure 远程渲染服务 API 版本 v2021-01-01。

添加以下 Maven 依赖项:

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-mixedreality-remoterendering</artifactId>
    <version>1.1.23</version>
</dependency>

验证客户端

构造远程渲染客户端需要经过身份验证的帐户和远程渲染终结点。 帐户由其 accountId 和帐户域组成。 对于在 eastus 区域中创建的帐户,帐户域的格式为“eastus.mixedreality.azure.com”。 有几种形式的身份验证:

  • 帐户密钥身份验证
    • 使用帐户密钥可以快速开始使用 Azure 远程渲染。 但是,在将应用程序部署到生产环境之前,我们建议你将应用更新为使用 Azure AD 身份验证。
  • Azure Active Directory (AD) 令牌身份验证
    • 如果你正在生成企业应用程序,并且你的公司使用 Azure AD 作为其标识系统,则你可以在应用中使用基于用户的 Azure AD 身份验证。 然后,使用现有的 Azure AD 安全组授予对 Azure 远程渲染 帐户的访问权限。 还可以直接向组织中的用户授予访问权限。
    • 否则,我们建议从支持你的应用的 Web 服务获取 Azure AD 令牌。 建议对生产应用程序使用此方法,因为这可以避免在客户端应用程序中嵌入用于访问 Azure 空间定位点的凭据。

有关详细说明和信息,请参阅 此处

在以下所有示例中,客户端都是使用 对象构造的 RemoteRenderingClientBuilder 。 参数始终相同,但凭据对象除外,每个示例都对此进行了说明。 参数 remoteRenderingEndpoint 是一个 URL,用于确定服务执行其工作的区域。 例如 https://remoterendering.eastus2.mixedreality.azure.com

注意:对于转换资产,最好选择靠近包含资产的存储的区域。

注意:对于呈现,强烈建议使用服务选择离设备最近的区域。 与服务器通信所需的时间会影响体验的质量。

使用帐户密钥身份验证进行身份验证

AzureKeyCredential使用 对象使用帐户标识符和帐户密钥进行身份验证:

AzureKeyCredential credential = new AzureKeyCredential(environment.getAccountKey());

RemoteRenderingClient client = new RemoteRenderingClientBuilder()
    .accountId(environment.getAccountId())
    .accountDomain(environment.getAccountDomain())
    .endpoint(environment.getServiceEndpoint())
    .credential(credential)
    .buildClient();

使用 AAD 客户端密码进行身份验证

ClientSecretCredential使用 对象执行客户端机密身份验证。

ClientSecretCredential credential = new ClientSecretCredentialBuilder()
    .tenantId(environment.getTenantId())
    .clientId(environment.getClientId())
    .clientSecret(environment.getClientSecret())
    .authorityHost("https://login.microsoftonline.com/" + environment.getTenantId())
    .build();

RemoteRenderingClient client = new RemoteRenderingClientBuilder()
    .accountId(environment.getAccountId())
    .accountDomain(environment.getAccountDomain())
    .endpoint(environment.getServiceEndpoint())
    .credential(credential)
    .buildClient();

使用设备代码身份验证对用户进行身份验证

DeviceCodeCredential使用 对象执行设备代码身份验证。

DeviceCodeCredential credential = new DeviceCodeCredentialBuilder()
    .challengeConsumer((DeviceCodeInfo deviceCodeInfo) -> {
        logger.info(deviceCodeInfo.getMessage());
    })
    .clientId(environment.getClientId())
    .tenantId(environment.getTenantId())
    .authorityHost("https://login.microsoftonline.com/" + environment.getTenantId())
    .build();

RemoteRenderingClient client = new RemoteRenderingClientBuilder()
    .accountId(environment.getAccountId())
    .accountDomain(environment.getAccountDomain())
    .endpoint(environment.getServiceEndpoint())
    .credential(credential)
    .buildClient();

有关使用设备代码身份验证流的详细信息,请参阅 此处

使用 DefaultAzureCredential 进行交互式身份验证

使用 DefaultAzureCredential 对象:

DefaultAzureCredential credential = new DefaultAzureCredentialBuilder().build();

RemoteRenderingClient client = new RemoteRenderingClientBuilder()
    .accountId(environment.getAccountId())
    .accountDomain(environment.getAccountDomain())
    .endpoint(environment.getServiceEndpoint())
    .credential(credential)
    .buildClient();

使用静态访问令牌进行身份验证

可以将混合现实访问令牌作为AccessToken以前从 混合现实 STS 服务检索到的令牌传递,以用于混合现实客户端库:

// GetMixedRealityAccessTokenFromWebService is a hypothetical method that retrieves
// a Mixed Reality access token from a web service. The web service would use the
// MixedRealityStsClient and credentials to obtain an access token to be returned
// to the client.
AccessToken accessToken = getMixedRealityAccessTokenFromWebService();

RemoteRenderingClient client = new RemoteRenderingClientBuilder()
    .accountId(environment.getAccountId())
    .accountDomain(environment.getAccountDomain())
    .endpoint(environment.getServiceEndpoint())
    .accessToken(accessToken)
    .buildClient();

关键概念

RemoteRenderingClient

RemoteRenderingClient是用于访问 RemoteRenderingService 的客户端库。 它提供了创建和管理资产转换和呈现会话的方法。

示例

转换简单资产

我们假设已按照 对客户端进行身份验证 部分中所述构造 RemoteRenderingClient。 以下代码片段介绍如何请求转换给定 URL 处 Blob 容器根目录中的“box.fbx”。

AssetConversionOptions conversionOptions = new AssetConversionOptions()
    .setInputStorageContainerUrl(getStorageURL())
    .setInputRelativeAssetPath("box.fbx")
    .setOutputStorageContainerUrl(getStorageURL());

// A randomly generated UUID is a good choice for a conversionId.
String conversionId = UUID.randomUUID().toString();

SyncPoller<AssetConversion, AssetConversion> conversionOperation = client.beginConversion(conversionId, conversionOptions);

输出文件将放置在输入资产旁边。

转换更复杂的资产

资产可以引用其他文件,Blob 容器可以包含属于许多不同资产的文件。 在此示例中,我们演示如何使用前缀来组织 Blob,以及如何转换资产以考虑该组织。 假设 处 inputStorageURL 的 blob 容器包含许多文件,包括“Bicycle/bicycle.gltf”、“Bicycle/bicycle.bin”和“Bicycle/saddleTexture.jpg”。 (因此,前缀“Bicycle”的行为非常类似于 folder.) 我们希望转换 gltf,使其可以访问共享前缀的其他文件,而无需转换服务访问任何其他文件。 为了保持整洁,我们还希望将输出文件写入其他存储容器,并指定一个通用前缀:“ConvertedBicycle”。 代码如下所示:

AssetConversionOptions conversionOptions = new AssetConversionOptions()
    .setInputStorageContainerUrl(inputStorageURL)
    .setInputRelativeAssetPath("bicycle.gltf")
    .setInputBlobPrefix("Bicycle")
    .setOutputStorageContainerUrl(outputStorageURL)
    .setOutputBlobPrefix("ConvertedBicycle");

String conversionId = UUID.randomUUID().toString();

SyncPoller<AssetConversion, AssetConversion> conversionOperation = client.beginConversion(conversionId, conversionOptions);

注意:在输入选项中给定前缀时,假定输入文件参数相对于该前缀。 这同样适用于输出选项中的输出文件参数。

在资产转换完成时获取输出

转换资产可能需要几秒钟到几小时的时间。 此代码使用现有的 conversionOperation 并定期轮询,直到转换完成或失败。 默认轮询期为 10 秒。 请注意,conversionOperation 可以从现有转换和客户端的 conversionId 构造。

AssetConversion conversion = conversionOperation.getFinalResult();
if (conversion.getStatus() == AssetConversionStatus.SUCCEEDED) {
    logger.info("Conversion succeeded: Output written to {}", conversion.getOutputAssetUrl());
} else if (conversion.getStatus() == AssetConversionStatus.FAILED) {
    logger.error("Conversion failed: {} {}", conversion.getError().getCode(), conversion.getError().getMessage());
} else {
    logger.error("Unexpected conversion status: {}", conversion.getStatus());
}

列出转换

可以使用 方法获取有关转换 listConversions 的信息。 此方法可能会返回尚未启动的转换、正在运行的转换和已完成的转换。 在此示例中,我们仅列出最近一天开始的成功转换的输出 URL。

for (AssetConversion conversion : client.listConversions()) {
    if ((conversion.getStatus() == AssetConversionStatus.SUCCEEDED)
        && (conversion.getCreationTime().isAfter(OffsetDateTime.now().minusDays(1)))) {
        logger.info("Output Asset URL: {}", conversion.getOutputAssetUrl());
    }
}

创建渲染会话

我们假设已按照 对客户端进行身份验证 部分中所述构造 RemoteRenderingClient。 以下代码片段介绍如何请求启动新的呈现会话。

BeginSessionOptions options = new BeginSessionOptions()
    .setMaxLeaseTime(Duration.ofMinutes(30))
    .setSize(RenderingSessionSize.STANDARD);

// A randomly generated GUID is a good choice for a sessionId.
String sessionId = UUID.randomUUID().toString();

SyncPoller<RenderingSession, RenderingSession> startSessionOperation = client.beginSession(sessionId, options);

延长会话的租用时间

如果会话接近其最长租用时间,但你想要使其保持活动状态,则需要调用 以增加其最长租用时间。 此示例演示如何查询当前属性,并在租约即将到期时延长租约。

注意:运行时 SDK 也提供此功能,在许多典型方案中,你将使用它们来扩展会话租约。

RenderingSession currentSession = client.getSession(sessionId);

Duration sessionTimeAlive = Duration.between(OffsetDateTime.now(), currentSession.getCreationTime()).abs();
if (currentSession.getMaxLeaseTime().minus(sessionTimeAlive).toMinutes() < 2) {
    Duration newLeaseTime = currentSession.getMaxLeaseTime().plus(Duration.ofMinutes(30));
    UpdateSessionOptions longerLeaseOptions = new UpdateSessionOptions().maxLeaseTime(newLeaseTime);
    client.updateSession(sessionId, longerLeaseOptions);
}

列出呈现会话

可以使用 方法获取有关会话 listSessions 的信息。 此方法可能会返回尚未启动的会话和已就绪的会话。

for (RenderingSession session : client.listSessions()) {
    if (session.getStatus() == RenderingSessionStatus.STARTING) {
        logger.info("Session {} is starting.");
    } else if (session.getStatus() == RenderingSessionStatus.READY) {
        logger.info("Session {} is ready at host {}", session.getId(), session.getHostname());
    } else if (session.getStatus() == RenderingSessionStatus.ERROR) {
        logger.error("Session {} encountered an error: {} {}", session.getId(), session.getError().getCode(), session.getError().getMessage());
    } else {
        logger.error("Session {} has unexpected status {}", session.getId(), session.getStatus());
    }
}

停止会话

以下代码将停止具有给定 ID 的正在运行的会话。

client.endSession(sessionId);

疑难解答

有关 Azure 远程渲染 的常规故障排除建议,请参阅 docs.microsoft.com 的远程渲染疑难解答页

如果无法发出请求,客户端方法将引发异常。 但是,在转换和会话的情况下,请求可以成功,但请求的操作可能不会成功。 在这种情况下,不会引发异常,但可以检查返回的对象以了解所发生的情况。

如果转换中的资产无效,转换操作将返回一个 AssetConversion 对象,该对象的状态为“Failed”,并携带包含详细信息的 RemoteRenderingServiceError。 转换服务能够处理该文件后, <assetName.result.json> 文件将写入输出容器。 如果输入资产无效,则该文件将包含问题的更详细说明。

同样,有时请求会话时,会话最终处于错误状态。 startSessionOperation 方法将返回 RenderingSession 对象,但该对象将具有“错误”状态,并带有包含详细信息的 RemoteRenderingServiceError。

后续步骤

  • 阅读 产品文档
  • 了解运行时 SDK:
    • .NET:/dotnet/api/microsoft.azure.remoterendering
    • C++:/cpp/api/remote-rendering/

贡献

本项目欢迎贡献和建议。 大多数贡献要求你同意贡献者许可协议 (CLA),并声明你有权(并且确实有权)授予我们使用你的贡献的权利。 有关详细信息,请访问 https://cla.microsoft.com

提交拉取请求时,CLA 机器人将自动确定你是否需要提供 CLA,并相应地修饰 PR(例如标签、注释)。 直接按机器人提供的说明操作。 只需使用 CLA 对所有存储库执行一次这样的操作。

此项目采用了 Microsoft 开放源代码行为准则。 有关详细信息,请参阅行为准则常见问题解答,或如果有任何其他问题或意见,请与 联系。

曝光数