Azure 远程渲染(ARR)是一项服务,可用于在云中呈现高质量的交互式 3D 内容,并将其实时流式传输到设备,例如 HoloLens 2。
此 SDK 提供将资产转换为运行时预期格式的功能,还用于管理远程呈现会话的生存期。
注意:会话运行后,客户端应用程序将使用其中一个“运行时 SDK”连接到它。 这些 SDK 旨在最好地支持执行 3d 呈现的交互式应用程序的需求。 它们可用于 (.net 或 (C++)。
开始
当前支持的环境
- LTS 版本的 Node.js
- Safari、Chrome、Edge 和 Firefox 的最新版本。
先决条件
需要使用 Azure 订阅 和 Azure 远程渲染帐户 才能使用此包。
安装 @azure/mixed-reality-remote-rendering
包
使用 npm
安装适用于 JavaScript 的模板客户端库:
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 令牌。 建议对生产应用程序使用此方法,因为它允许你避免在客户端应用程序中嵌入凭据。
在以下示例中,客户端是使用 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"
});
使用静态访问令牌进行身份验证
可以将混合现实访问令牌作为以前从 混合现实 STS 服务检索的 AccessToken
传递给混合现实客户端库:
// 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
);
请注意,可以通过调用 toString()序列化 RenderingSessionPollerLike 的状态。
稍后可以将该值作为 resumeFrom
值传递到 beginSession 中,以构造一个新的轮询器,该轮询器从前面一个离开的位置继续执行:
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。
后续步骤
- 阅读 产品文档
- 了解运行时 SDK:
贡献
若要参与此库,请阅读 贡献指南 了解有关如何生成和测试代码的详细信息。
相关项目
- 用于 Javascript 的 Azure SDK Microsoft