Java SDK
Aholo OpenAPI 官方 Java SDK。
- 运行要求: Java 8+,Maven ≥ 3.6(从源码构建推荐使用 JDK 17 或 21)
- GitHub: manycoretech/aholo-spatial-sdk
安装
在 pom.xml 中按需添加依赖(版本号以 Maven Central 最新为准):
<dependency>
<groupId>com.manycoreapis</groupId>
<artifactId>aholo-sdk-asset</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>com.manycoreapis</groupId>
<artifactId>aholo-sdk-world</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>com.manycoreapis</groupId>
<artifactId>aholo-sdk-lux3d</artifactId>
<version>1.2.0</version>
</dependency>
鉴权
推荐: 通过环境变量设置,SDK 自动读取 AHOLO_API_KEY:
export AHOLO_API_KEY=your_api_key_here
也可在代码中显式传入:
import com.manycoreapis.sdk.core.AholoClientConfig;
AholoClientConfig config = AholoClientConfig.of("your_api_key_here", "cn");
安全提示
请勿将 API Key 硬编码到源代码、安装包或公开仓库中。
区域
| 值 | 说明 | API 接入点 |
|---|---|---|
cn | 中国区 | https://api.aholo3d.cn |
com | 海外区 | https://api.aholo3d.com |
通用上传(Asset)
import com.manycoreapis.sdk.asset.AssetClient;
import com.manycoreapis.sdk.asset.UploadResult;
import com.manycoreapis.sdk.core.AholoClientConfig;
import java.nio.file.Files;
import java.nio.file.Paths;
AssetClient asset = AssetClient.create(AholoClientConfig.ofRegion("cn"));
上传文件
UploadResult result = asset.uploadFile(Paths.get("video.mp4"));
System.out.println(result.url()); // 公开访问 URL
上传字节数组
byte[] data = Files.readAllBytes(Paths.get("image.jpg"));
UploadResult result = asset.uploadBytes(data, "image.jpg");
带进度回调
UploadResult result = asset.uploadFile(
Paths.get("video.mp4"),
(uploaded, total) -> {
int pct = (int) (uploaded * 100 / total);
System.out.printf("\r上传进度: %d%%", pct);
}
);
UploadResult 返回值
| 方法 | 类型 | 说明 |
|---|---|---|
url() | String | 文件公开访问 URL |
md5() | String | 文件 MD5 |
uploadKey() | String | OUS 上传 key |
世界(World)
import com.manycoreapis.sdk.world.WorldClient;
import com.manycoreapis.sdk.world.model.ReconstructionCreateParams;
import com.manycoreapis.sdk.world.model.GenerationCreateParams;
import com.manycoreapis.sdk.world.model.WorldAsyncOperation;
import com.manycoreapis.sdk.world.model.WorldDetail;
WorldClient world = WorldClient.create(AholoClientConfig.ofRegion("cn"));
3DGS 重建(从视频 / 图像)
WorldAsyncOperation op = world.reconstructions().create(
ReconstructionCreateParams.builder()
.name("客厅")
.addResource("https://cdn.example.com/room.mp4", "video") // "video" | "image"
.taskQuality("normal") // "low" | "normal" | "high"
.scene("model") // "model" | "space"
.useMask(false) // optional: segment uploaded resources when true
.build());
WorldDetail detail = world.waitFor(op.worldId());
detail.assets().ifPresent(assets ->
assets.splats().ifPresent(splats ->
splats.urls().ifPresent(urls ->
urls.plyPath().ifPresent(System.out::println)))); // PLY 下载 URL
图片重建要求
使用图片重建时,resources 中图片类资源须 ≥ 20 条(type 为 image 或省略)。
3DGS 生成(从文字描述)
WorldAsyncOperation op = world.generations().create(
GenerationCreateParams.builder()
.name("森林小屋")
.prompt("森林中的现代风格小木屋")
.build());
WorldDetail detail = world.waitFor(op.worldId());
查询世界详情
WorldDetail detail = world.retrieve(worldId);
detail.status().ifPresent(System.out::println);
任务状态与轮询
| 阶段 | 状态值 | 说明 |
|---|---|---|
| 进行中 | PENDING | 排队中 |
| 进行中 | PREPROCESSING | 预处理中 |
| 进 行中 | RUNNING | 执行中 |
| 成功终态 | SUCCEEDED | 成功 |
| 失败终态 | FAILED | 失败 |
| 失败终态 | CANCELED | 已取消 |
| 失败终态 | TIMEOUT | 超时 |
| 失败终态 | REJECTED | 被拒绝 |
world.waitFor(worldId) 轮询直至 SUCCEEDED 并返回 WorldDetail;若进入 FAILED / CANCELED / TIMEOUT / REJECTED,抛出 AholoException。
查询世界列表
import com.manycoreapis.sdk.world.model.WorldListParams;
import com.manycoreapis.sdk.world.model.WorldPagedList;
WorldPagedList page = world.list(
WorldListParams.builder().pageNum(1).pageSize(20).build());
page.result().ifPresent(items ->
items.forEach(w -> System.out.println(w.worldId() + " " + w.status())));
WorldDetail 主要字段
| 方法 | 类型 | 说明 |
|---|---|---|
worldId() | String | 世界 ID |
name() | Optional<String> | 名称 |
status() | Optional<String> | 见上方「任务状态与轮询」 |
assets().splats().urls().plyPath() 等 | Optional<String> | splat 下载 URL(plyPath / spzPath / lodMetaPath) |
assets().imagery().panoUrl() | Optional<String> | AI 生成全景图 URL |
assets().semanticsMetadata().upAxis() | Optional<String> | 世界上轴(Y / Z) |
createTime() | Optional<Long> | 创建时间(Unix 毫秒) |
updateTime() | Optional<Long> | 更新时间(Unix 毫秒) |
Lux3D
import com.manycoreapis.sdk.lux3d.Lux3dClient;
import com.manycoreapis.sdk.lux3d.model.ImgTo3dCreateParams;
import com.manycoreapis.sdk.lux3d.model.TextTo3dCreateParams;
import com.manycoreapis.sdk.lux3d.model.MaterialTransferCreateParams;
import com.manycoreapis.sdk.lux3d.model.TaskResult;
import java.nio.file.Paths;
Lux3dClient lux3d = Lux3dClient.create(AholoClientConfig.ofRegion("cn"));
图像转 3D
// 从 URL
long taskId = lux3d.imgTo3d().create(
ImgTo3dCreateParams.builder()
.img("https://example.com/object.jpg")
.version("v2.0-preview") // "v1.0-pro" | "v2.0-preview"(默认)
.build());
// 从本地文件
long taskId2 = lux3d.imgTo3d().createFromFile(Paths.get("object.jpg"));
TaskResult result = lux3d.tasks().waitFor(taskId);
result.outputs().forEach(o -> o.content().ifPresent(System.out::println));
文字转 3D
long taskId = lux3d.textTo3d().create(
TextTo3dCreateParams.builder()
.prompt("带雕花腿的木椅")
// .style("photorealistic") // 见下方风格列表
.build());
TaskResult result = lux3d.tasks().waitFor(taskId);
文字转 3D 风格:
photorealistic(写实,默认)| cartoon(卡通)| anime(动漫)| hand_painted(手绘)| cyberpunk(赛博朋克)| fantasy(奇幻)| glass(玻璃)
材质迁移
long taskId = lux3d.materialTransfer().create(
MaterialTransferCreateParams.builder()
.img("https://example.com/material.jpg")
.meshUrl("https://example.com/model.glb")
.build());
TaskResult result = lux3d.tasks().waitFor(taskId);
版本差异
| 版本 | 默认 | 输出格式 | 说明 |
|---|---|---|---|
v2.0-preview | ✓ | .zip + .glb + .usdz(3 个文件) | 强化文字与纹理细节保持 |
v1.0-pro | .lux3d(1 个文件) | 完整 PBR 材质,支持透明材质 |
任务结果字段
| 方法 | 类型 | 说明 |
|---|---|---|
taskId() | long | 任务 ID |
status() | int | 0 初始化;1 进行中;3 成功;4 失败 |
outputs() | List<TaskOutput> | 输出文件列表(outputs().get(n).content() 为 Optional<String> 下载 URL,成功后约 2 小时内有效) |
lux3d.tasks().waitFor(taskId) 在 status == 3 时返回;status == 4 时抛出 AholoException。建议每 10–15 秒轮询一次。
错误处理
import com.manycoreapis.sdk.core.AuthenticationException;
import com.manycoreapis.sdk.core.RateLimitException;
import com.manycoreapis.sdk.core.BusinessException;
import com.manycoreapis.sdk.core.AholoException;
import com.manycoreapis.sdk.world.model.WorldDetail;
try {
WorldDetail detail = world.waitFor(worldId);
} catch (AuthenticationException e) {
System.err.println("API Key 无效或未设置");
} catch (RateLimitException e) {
System.err.println("请求频率超限,稍后重试");
} catch (BusinessException e) {
System.err.println("业务错误: " + e.getCode() + " " + e.getMessage());
} catch (AholoException e) {
System.err.println("SDK 异常: " + e.getMessage());
}
| 异常类型 | 说明 |
|---|---|
AuthenticationException | API Key 无效或未设置 |
RateLimitException | 请求频率超限 |
BusinessException | 业务错误(含 getCode() 字段) |
AholoException | SDK 其他异常基类 |
更多示例
完整示例见 GitHub examples 目录:
| 文件 | 说明 |
|---|---|
UploadFile.java | 上传本地文件并打印 URL |
WorldReconstruct.java | 上传视频 → 创建 3DGS 重建 → 轮询至完成 |
Lux3dImgTo3d.java | 本地图片 → Lux3D 图生 3D → 轮询至完成 |
克隆仓库后,在 aholo-spatial-sdk/java 目录执行:
export AHOLO_API_KEY=your_api_key_here
# 可选:export AHOLO_REGION=com # 默认 cn
# 上传文件
mvn exec:java -pl examples \
-Dexec.mainClass=com.manycoreapis.sdk.examples.UploadFile \
-Dexec.args="/path/to/photo.jpg"
# 3DGS 世界重建(视频)
mvn exec:java -pl examples \
-Dexec.mainClass=com.manycoreapis.sdk.examples.WorldReconstruct \
-Dexec.args="/path/to/room.mp4"
# Lux3D 图生 3D
mvn exec:java -pl examples \
-Dexec.mainClass=com.manycoreapis.sdk.examples.Lux3dImgTo3d \
-Dexec.args="/path/to/chair.png"
依赖说明
aholo-sdk-core 通过 OkHttp 4.x 提供 HTTP 传输(兼容 Java 8),作为传递依赖自动引入,无需在 pom.xml 中单独声明。
GitHub README 仅作安装说明。若与本文冲突,以本文为准。源码与可运行示例见 GitHub。