Add audio asset support in App and RunnerCanvas components
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
||||
} from "react";
|
||||
|
||||
import { createCreateBoxBrushCommand } from "../commands/create-box-brush-command";
|
||||
import { createImportAudioAssetCommand } from "../commands/import-audio-asset-command";
|
||||
import { createImportBackgroundImageAssetCommand } from "../commands/import-background-image-asset-command";
|
||||
import { createImportModelAssetCommand } from "../commands/import-model-asset-command";
|
||||
import { createMoveBoxBrushCommand } from "../commands/move-box-brush-command";
|
||||
@@ -44,6 +45,11 @@ import {
|
||||
getModelInstanceDisplayLabelById,
|
||||
getSortedModelInstanceDisplayLabels
|
||||
} from "../assets/model-instance-labels";
|
||||
import {
|
||||
importAudioAssetFromFile,
|
||||
loadAudioAssetFromStorage,
|
||||
type LoadedAudioAsset
|
||||
} from "../assets/audio-assets";
|
||||
import {
|
||||
importModelAssetFromFile,
|
||||
importModelAssetFromFiles,
|
||||
@@ -59,7 +65,7 @@ import {
|
||||
type ImportedImageAssetResult,
|
||||
type LoadedImageAsset
|
||||
} from "../assets/image-assets";
|
||||
import type { ImageAssetRecord, ModelAssetRecord, ProjectAssetRecord } from "../assets/project-assets";
|
||||
import type { AudioAssetRecord, ImageAssetRecord, ModelAssetRecord, ProjectAssetRecord } from "../assets/project-assets";
|
||||
import { getProjectAssetKindLabel } from "../assets/project-assets";
|
||||
import {
|
||||
BOX_FACE_IDS,
|
||||
@@ -85,7 +91,11 @@ import {
|
||||
DEFAULT_POINT_LIGHT_DISTANCE,
|
||||
DEFAULT_POINT_LIGHT_INTENSITY,
|
||||
DEFAULT_SOUND_EMITTER_GAIN,
|
||||
DEFAULT_SOUND_EMITTER_AUDIO_ASSET_ID,
|
||||
DEFAULT_SOUND_EMITTER_RADIUS,
|
||||
DEFAULT_SOUND_EMITTER_VOLUME,
|
||||
DEFAULT_SOUND_EMITTER_REF_DISTANCE,
|
||||
DEFAULT_SOUND_EMITTER_MAX_DISTANCE,
|
||||
DEFAULT_TELEPORT_TARGET_YAW_DEGREES,
|
||||
DEFAULT_SPOT_LIGHT_ANGLE_DEGREES,
|
||||
DEFAULT_SPOT_LIGHT_COLOR_HEX,
|
||||
@@ -333,6 +343,10 @@ function isImageAsset(asset: ProjectAssetRecord): asset is ImageAssetRecord {
|
||||
return asset.kind === "image";
|
||||
}
|
||||
|
||||
function isAudioAsset(asset: ProjectAssetRecord): asset is AudioAssetRecord {
|
||||
return asset.kind === "audio";
|
||||
}
|
||||
|
||||
function formatByteLength(byteLength: number): string {
|
||||
if (byteLength < 1024) {
|
||||
return `${byteLength} B`;
|
||||
@@ -383,6 +397,17 @@ function formatImageAssetSummary(asset: ImageAssetRecord): string {
|
||||
return details.join(" | ");
|
||||
}
|
||||
|
||||
function formatAudioAssetSummary(asset: AudioAssetRecord): string {
|
||||
const details = [
|
||||
asset.metadata.durationSeconds === null ? "duration unavailable" : `${asset.metadata.durationSeconds.toFixed(2)}s`,
|
||||
asset.metadata.channelCount === null ? "channels unavailable" : `${asset.metadata.channelCount} channel${asset.metadata.channelCount === 1 ? "" : "s"}`,
|
||||
asset.metadata.sampleRateHz === null ? "sample rate unavailable" : `${asset.metadata.sampleRateHz} Hz`,
|
||||
formatByteLength(asset.byteLength)
|
||||
];
|
||||
|
||||
return details.join(" | ");
|
||||
}
|
||||
|
||||
function createModelInstancePlacementPosition(asset: ModelAssetRecord, anchor: Vec3 | null): Vec3 {
|
||||
const boundingBox = asset.metadata.boundingBox;
|
||||
|
||||
@@ -466,6 +491,10 @@ function getInteractionActionLabel(link: InteractionLink): string {
|
||||
return "Play Animation";
|
||||
case "stopAnimation":
|
||||
return "Stop Animation";
|
||||
case "playSound":
|
||||
return "Play Sound";
|
||||
case "stopSound":
|
||||
return "Stop Sound";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
|
||||
import type { LoadedAudioAsset } from "../assets/audio-assets";
|
||||
import type { LoadedModelAsset } from "../assets/gltf-model-import";
|
||||
import type { LoadedImageAsset } from "../assets/image-assets";
|
||||
import type { ProjectAssetRecord } from "../assets/project-assets";
|
||||
@@ -14,6 +15,7 @@ interface RunnerCanvasProps {
|
||||
projectAssets: Record<string, ProjectAssetRecord>;
|
||||
loadedModelAssets: Record<string, LoadedModelAsset>;
|
||||
loadedImageAssets: Record<string, LoadedImageAsset>;
|
||||
loadedAudioAssets: Record<string, LoadedAudioAsset>;
|
||||
navigationMode: RuntimeNavigationMode;
|
||||
onRuntimeMessageChange(message: string | null): void;
|
||||
onFirstPersonTelemetryChange(telemetry: FirstPersonTelemetry | null): void;
|
||||
@@ -25,6 +27,7 @@ export function RunnerCanvas({
|
||||
projectAssets,
|
||||
loadedModelAssets,
|
||||
loadedImageAssets,
|
||||
loadedAudioAssets,
|
||||
navigationMode,
|
||||
onRuntimeMessageChange,
|
||||
onFirstPersonTelemetryChange,
|
||||
@@ -78,8 +81,8 @@ export function RunnerCanvas({
|
||||
}, [onFirstPersonTelemetryChange, onInteractionPromptChange, onRuntimeMessageChange]);
|
||||
|
||||
useEffect(() => {
|
||||
hostRef.current?.updateAssets(projectAssets, loadedModelAssets, loadedImageAssets);
|
||||
}, [projectAssets, loadedModelAssets, loadedImageAssets]);
|
||||
hostRef.current?.updateAssets(projectAssets, loadedModelAssets, loadedImageAssets, loadedAudioAssets);
|
||||
}, [projectAssets, loadedModelAssets, loadedImageAssets, loadedAudioAssets]);
|
||||
|
||||
useEffect(() => {
|
||||
hostRef.current?.loadScene(runtimeScene);
|
||||
|
||||
Reference in New Issue
Block a user