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

适用于 JavaScript 的 Azure 远程渲染客户端库 - 版本 1.0.0-beta.1

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

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

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

产品文档

入门

目前支持的环境

先决条件

需要一个 Azure 订阅和一个 Azure 远程渲染帐户才能使用此包。

安装 @azure/mixed-reality-remote-rendering

使用 安装适用于 JavaScript 的 npm模板客户端库:

npm install @azure/mixed-reality-remote-rendering

浏览器支持

JavaScript 捆绑包

若要在浏览器中使用此客户端库,首先需要使用捆绑程序。 有关如何执行此操作的详细信息,请参阅捆绑 文档

CORS

此库不能用于从浏览器直接调用 Azure 远程渲染 服务。 有关指南,请参阅 此文档

验证客户端

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

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

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

在以下所有示例中,客户端都是使用 构造的 remoteRenderingEndpoint。 可用终结点对应于区域,终结点的选择决定了服务在其中执行其工作的区域。 示例为 https://remoterendering.eastus2.mixedreality.azure.com

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

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

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

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

const credential = new AzureKeyCredential(accountKey);

const client = new RemoteRenderingClient(serviceEndpoint, accountId, accountDomain, credential);

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

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

let credential = new ClientSecretCredential(tenantId, clientId, clientSecret, {
  authorityHost: "https://login.microsoftonline.com/" + tenantId
});

const client = new RemoteRenderingClient(serviceEndpoint, accountId, accountDomain, credential);

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

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

let deviceCodeCallback = (deviceCodeInfo: DeviceCodeInfo) => {
  console.debug(deviceCodeInfo.message);
  console.log(deviceCodeInfo.message);
};

let credential = new DeviceCodeCredential(tenantId, clientId, deviceCodeCallback, {
  authorityHost: "https://login.microsoftonline.com/" + tenantId
});

const client = new RemoteRenderingClient(serviceEndpoint, accountId, accountDomain, credential);

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

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

DefaultAzureCredential 对象与 结合使用 includeInteractiveCredentials: true ,以使用默认交互式身份验证流:

let credential = new DefaultAzureCredential();

return new RemoteRenderingClient(serviceEndpoint, accountId, accountDomain, credential, {
  authenticationEndpointUrl: "https://sts.mixedreality.azure.com"
});

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

可以将混合现实访问令牌作为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.
const accessToken = GetMixedRealityAccessTokenFromWebService();

RemoteRenderingClient client = new RemoteRenderingClient(remoteRenderingEndpoint, accountId, accessToken);

关键概念

RemoteRenderingClient

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

示例

转换简单资产

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

const inputSettings: AssetConversionInputSettings = {
  storageContainerUrl,
  relativeInputAssetPath: "box.fbx"
};
const outputSettings: AssetConversionOutputSettings = {
  storageContainerUrl
};
const conversionSettings: AssetConversionSettings = { inputSettings, outputSettings };

// A randomly generated UUID is a good choice for a conversionId.
const conversionId = uuid();

const conversionPoller: AssetConversionPollerLike = await client.beginConversion(
  conversionId,
  conversionSettings
);

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

转换更复杂的资产

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

  const inputSettings: AssetConversionInputSettings = {
    storageContainerUrl: inputStorageUrl,
    blobPrefix: "Bicycle"
    relativeInputAssetPath: "bicycle.gltf"
  };
  const outputSettings: AssetConversionOutputSettings = {
    storageContainerUrl: outputStorageUrl,
    blobPrefix: "ConvertedBicycle"
  };
  const conversionSettings: AssetConversionSettings = { inputSettings, outputSettings };

  const conversionId = uuid();

  const conversionPoller: AssetConversionPollerLike = await client.beginConversion(
    conversionId,
    conversionSettings
  );

注意:如果输入选项中提供了前缀,则假定输入文件参数相对于该前缀。 这同样适用于输出选项中的输出文件参数。

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

转换资产可能需要几秒钟到几小时的时间。 此代码使用 beginConversion 返回的 conversionPoller 定期轮询,直到转换完成或失败。 默认轮询周期为 10 秒。

const conversion = await conversionPoller.pollUntilDone();

console.log("== Check results ==");

if (conversion.status === "Succeeded") {
  console.log("Conversion succeeded: Output written to " + conversion.output?.outputAssetUrl);
} else if (conversion.status === "Failed") {
  console.log("Conversion failed: " + conversion.error.code + " " + conversion.error.message);
}

请注意,可以通过调用 conversionPoller.toString () 来序列化 AssetConversionPollerLike 的状态。 该值稍后可以作为 resumeFrom 值传递到 beginConversion 中,以构造一个新的轮询器,该轮询器从前一个轮询器离开的位置继续执行:

const serializedPollerString = conversionPoller.toString();
// ...
const resumedPoller = client.beginConversion({ resumeFrom: serializedPollerString });

列出转换

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

for await (const conversion of client.listConversions()) {
  if (conversion.status === "Succeeded") {
    console.log(
      `Conversion ${conversion.conversionId} succeeded: Output written to ${conversion.output?.outputAssetUrl}`
    );
  } else if (conversion.status === "Failed") {
    console.log(
      `Conversion ${conversion.conversionId} failed: ${conversion.error.code} ${conversion.error.message}`
    );
  }
}

创建会话

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

const sessionSettings: RenderingSessionSettings = {
  maxLeaseTimeInMinutes: 4,
  size: "Standard"
};

// A randomly generated UUID is a good choice for a conversionId.
const sessionId = uuid();

const sessionPoller: RenderingSessionPollerLike = await client.beginSession(
  sessionId,
  sessionSettings
);

请注意,RenderingSessionPollerLike 的状态可以通过调用 toString () 进行序列化。 该值稍后可以作为值传递到 beginSession resumeFrom 中,以构造一个新的轮询器,该轮询器从前一个轮询器离开的位置进行:

const serializedPollerString = sessionPoller.toString();
// ...
const resumedPoller = client.beginSession({ resumeFrom: serializedPollerString });

延长会话的租用时间

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

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

/// When the lease is within 2 minutes of expiring, extend it by 15 minutes.
let currentSession = await client.getSession(sessionId);
if (currentSession.status == "Ready") {
  if (
    currentSession.maxLeaseTimeInMinutes -
      (Date.now() - currentSession.properties.createdOn.valueOf()) / 60000 <
    2
  ) {
    let newLeaseTime = currentSession.maxLeaseTimeInMinutes + 15;

    await client.updateSession(sessionId, { maxLeaseTimeInMinutes: newLeaseTime });
  }
}

列出会话

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

for await (const session of client.listSessions()) {
  console.log(`Session ${session.sessionId} is ${session.status}`);
}

停止会话

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

client.endSession(sessionId);

疑难解答

日志记录

启用日志记录可能有助于发现有关故障的有用信息。 若要查看 HTTP 请求和响应的日志,请将 AZURE_LOG_LEVEL 环境变量设置为 info。 或者,可以在运行时通过调用 @azure/logger 中的 setLogLevel 来启用日志记录:

import { setLogLevel } from "@azure/logger";

setLogLevel("info");

Azure 远程渲染故障排除

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

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

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

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

后续步骤

贡献

若要为此库做出贡献,请阅读贡献指南,详细了解如何生成和测试代码。

曝光数