Skip to content

Comments

feat: add hevc video detection and play function#1311

Merged
yiiqii merged 13 commits intofeat/2.8from
feat/hevc
Dec 16, 2025
Merged

feat: add hevc video detection and play function#1311
yiiqii merged 13 commits intofeat/2.8from
feat/hevc

Conversation

@ChengYi996
Copy link
Collaborator

@ChengYi996 ChengYi996 commented Dec 11, 2025

Summary by CodeRabbit

  • New Features

    • Optional HEVC video support and runtime detection for improved video playback; player now respects device pixel ratio.
  • Bug Fixes

    • Improved multimedia URL resolution and error handling during asset loading.
    • Removed TypeScript suppression related to sprite texture animations, addressing related type warnings.
  • Chores

    • Updated effects specification dependency for compatibility.

✏️ Tip: You can customize this high-level summary in your review settings.

@ChengYi996 ChengYi996 requested a review from yiiqii December 11, 2025 05:53
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 11, 2025

Walkthrough

Adds optional HEVC selection to scene loading via a new useHevcVideo flag and multimedia utilities that detect browser HEVC capability and select preferred video sources; demo updated to pass the flag and use parsed scene JSON; package dependency bumped.

Changes

Cohort / File(s) Summary
Scene Loading Configuration
packages/effects-core/src/scene.ts, packages/effects-core/package.json
Added optional useHevcVideo?: boolean to SceneLoadOptions. Bumped @galacean/effects-specification from 2.7.0-alpha.02.7.1.
Multimedia HEVC & Helpers
plugin-packages/multimedia/src/utils.ts
Added canPlayHevcCodec and parseCodec exports, introduced MultimediaError, and new internal helpers (isCodecValue, isCodecKey, getVideoUrl). processMultimedia now resolves video URLs (preferring HEVC when appropriate) and throws on invalid renderLevel; loadAudio signature/documentation clarified.
Demo Update
web-packages/demo/src/single.ts
Swapped plugin import to multimedia, replaced external URL arrays with JSON scene string parsed at runtime, added pixelRatio setting, changed error prefixing, and calls loadScene with { useHevcVideo: true }.
TypeScript Cleanup
packages/effects-core/src/plugins/sprite/sprite-item.ts
Removed @ts-expect-error suppression and a placeholder comment; small spacing/format cleanup in geometry assignment.

Sequence Diagram

sequenceDiagram
    participant App as Application
    participant Player as Player
    participant Loader as SceneLoader
    participant Multimedia as MultimediaUtils
    participant Browser as Browser/CodecAPI
    participant Network as Network

    App->>Player: create(playerOptions)
    Player->>Loader: loadScene(sceneData, { useHevcVideo: true })
    Loader->>Multimedia: processMultimedia(mediaItems, options)
    Multimedia->>Browser: canPlayHevcCodec(codec)
    Browser-->>Multimedia: supported? (true/false)

    alt HEVC supported & enabled
        Multimedia->>Multimedia: getVideoUrl() → select HEVC source
    else fallback
        Multimedia->>Multimedia: getVideoUrl() → select base/source URL
    end

    Multimedia->>Network: fetch(videoUrl)
    Network-->>Multimedia: video data
    Multimedia-->>Loader: resolved media (URLs/buffers)
    Loader-->>Player: scene assets ready
    Player-->>App: playback starts
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Review multimedia helpers in plugin-packages/multimedia/src/utils.ts (codec parsing, HEVC selection, getVideoUrl, and error handling).
  • Verify useHevcVideo propagation from packages/effects-core/src/scene.ts through loaders.
  • Check demo changes in web-packages/demo/src/single.ts for correct JSON scene structure and pixelRatio usage.
  • Confirm package.json bump aligns with specification expectations.

Poem

🐰 I hop through bytes and codec streams,
Choosing HEVC in clever schemes.
URLs picked with nimble paw,
Fallback ready — no big flaw.
Playback hops — hooray for beams! 🎥✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add hevc video detection and play function' accurately reflects the main changes: adding HEVC codec detection capabilities (canPlayHevcCodec, parseCodec) and video selection logic to play optimal video formats based on browser support.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/hevc

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8a92a1b and 593a7f9.

📒 Files selected for processing (1)
  • packages/effects-core/src/plugins/sprite/sprite-item.ts (0 hunks)
💤 Files with no reviewable changes (1)
  • packages/effects-core/src/plugins/sprite/sprite-item.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/effects-core/src/asset-manager.ts (1)

204-450: Fix early-return in processVideoURL to process all videos, not just the first valid one.

The integration point and overall flow look good (running codec selection before bins/images and timing it via hookTimeInfo), but there is a critical logic bug:

Early exit prevents processing remaining videos: The function contains a return statement inside the per-video loop:

for (const video of jsonScene.videos) {
  const hevc = video.hevc as { url?: string, codec?: string } | undefined;

  // @ts-expect-error
  if (!hevc?.url || !hevc?.codec || !spec.HevcVideoCodec) {return;}
  
  const codec = this.stringToHevcVideoCodec(hevc.codec);
  if (codec && this.canPlayHevcCodec(codec)) {
    video.url = hevc.url;
  }
}

As soon as any video is missing hevc.url / hevc.codec, the function exits entirely and no subsequent videos are processed. This silently skips remaining videos without error.

Change return to continue:

  for (const video of jsonScene.videos) {
    const hevc = video.hevc as { url?: string, codec?: string } | undefined;

    // @ts-expect-error
-   if (!hevc?.url || !hevc?.codec || !spec.HevcVideoCodec) {return;}
+   if (!hevc?.url || !hevc?.codec || !spec.HevcVideoCodec) {continue;}

    const codec = this.stringToHevcVideoCodec(hevc.codec);

    if (codec && this.canPlayHevcCodec(codec)) {
      video.url = hevc.url;
    }
  }

This preserves the "skip when spec.HevcVideoCodec is unavailable" behavior while still processing all valid videos.

Secondary notes: The jsonScene: any parameter could be narrowed to spec.JSONScene once HevcVideoCodec is officially available in the spec, allowing you to remove the @ts-expect-error comments. Additionally, canPlayHevcCodec creates a new video element per call; if processing many videos, consider memoizing results by codec.

🧹 Nitpick comments (1)
plugin-packages/multimedia/demo/src/hevc-video.ts (1)

223-246: Harden demo against real-page issues (HTTP video URL and container null).

  • The HEVC and fallback URLs are plain http://. If the demo is ever served over HTTPS, this will be blocked as mixed content and the video won’t load. If an HTTPS endpoint exists, it’s safer to switch to it here.
  • const container = document.getElementById('J-container'); may be null if the element is missing or the script runs before DOMReady. You might want to guard and log a clear error, or assert non-null with a runtime check to avoid a less-obvious failure inside Player.

These are demo-only, so feel free to treat them as polish rather than blockers.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e5edd08 and e8185f4.

📒 Files selected for processing (2)
  • packages/effects-core/src/asset-manager.ts (2 hunks)
  • plugin-packages/multimedia/demo/src/hevc-video.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: yiiqii
Repo: galacean/effects-runtime PR: 214
File: packages/effects/src/player.ts:416-429
Timestamp: 2024-10-17T07:15:16.523Z
Learning: Data compatibility or processing logic related to replacing text variables in scene compositions should be handled in the AssetManager class through the updateOptions method, not in the Player class.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
packages/effects-core/src/asset-manager.ts (1)

409-409: Fix parameter type to avoid any.

Based on past review feedback and coding guidelines, the parameter should be typed as spec.JSONScene instead of any for better type safety.

Apply this diff:

-  private async processVideoURL (jsonScene: any): Promise<void> {
+  private async processVideoURL (jsonScene: spec.JSONScene): Promise<void> {
🧹 Nitpick comments (2)
packages/effects-core/src/asset-manager.ts (2)

204-206: Consider parallelizing video processing with other asset loading.

Based on past review feedback, the video codec selection could run concurrently with bins/images/fonts loading in the Promise.all below, reducing overall load time. As per coding guidelines, processVideoURL doesn't appear to have dependencies on the other loading tasks.

Apply this diff to parallelize the loading:

-        if (this.options.useHevcVideo) {
-          await hookTimeInfo('selectVideoCodec', () => this.processVideoURL(jsonScene));
-        }
         const [loadedBins, loadedImages] = await Promise.all([
           hookTimeInfo('processBins', () => this.processBins(bins)),
           hookTimeInfo('processImages', () => this.processImages(images, isKTX2Supported)),
           hookTimeInfo('processFontURL', () => this.processFontURL(fonts as spec.FontDefine[])),
+          this.options.useHevcVideo
+            ? hookTimeInfo('selectVideoCodec', () => this.processVideoURL(jsonScene))
+            : Promise.resolve(),
         ]);

425-444: Review the necessity of the stringToHevcVideoCodec method and its type handling.

This private method has 9 @ts-expect-error suppressions across 20 lines of code, indicating significant type incompatibility. Additionally, the method appears to be unused—no calls to it are found in the codebase. Consider whether this method is needed at all. If it is required for future use, the type assertions should be properly addressed by:

  1. Verifying that spec.HevcVideoCodec is correctly imported and typed in the specification package
  2. Replacing type suppressions with proper type guards or factory functions
  3. If the enum definition doesn't support these operations, consider restructuring the validation logic
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e8185f4 and b1ed774.

📒 Files selected for processing (3)
  • packages/effects-core/src/asset-manager.ts (2 hunks)
  • packages/effects-core/src/scene.ts (1 hunks)
  • web-packages/demo/src/single.ts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (3)
packages/effects-core/src/scene.ts (1)

89-93: LGTM! Clean API addition.

The new useHevcVideo field follows the established pattern for optional feature flags and is properly documented.

web-packages/demo/src/single.ts (1)

4-245: LGTM! Effective demo setup.

The demo properly showcases the HEVC video feature with an embedded scene JSON containing HEVC configuration and the useHevcVideo: true option.

packages/effects-core/src/asset-manager.ts (1)

445-452: Implementation is correct, but type suppressions indicate upstream issue.

The canPlayHevcCodec method correctly uses the canPlayType API. However, the @ts-expect-error suppressions suggest the same type definition issue as noted in stringToHevcVideoCodec. This should be resolved by addressing the spec.HevcVideoCodec type availability.

This will be resolved when the type issues flagged in the previous comment are addressed.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
packages/effects-core/src/asset-manager.ts (1)

407-422: Critical: loop uses return (exits early); should be continue

Line 414 exits the whole function on the first non-HEVC video, skipping subsequent entries.

   for (const video of jsonScene.videos) {
     // @ts-expect-error
     const hevc = video.hevc as { url?: string, codec?: string } | undefined;

-    if (!hevc?.url || !hevc?.codec) {return;}
+    if (!hevc?.url || !hevc?.codec) { continue; }

     const codec = this.stringToHevcVideoCodec(hevc.codec);

     if (codec && this.canPlayHevcCodec(codec)) {
       video.url = hevc.url;
     }
   }
🧹 Nitpick comments (2)
packages/effects-core/src/asset-manager.ts (2)

423-442: Avoid @ts-expect-error here; strongly type the “hevc extension” once

Rather than suppressing type checks repeatedly, introduce a narrow local type (e.g. type VideoWithHevc = spec.VideoSource & { hevc?: { url?: string; codec?: string } }) and use it in processVideoURL/stringToHevcVideoCodec. This will also make it clearer what shape you expect from jsonScene.videos.


443-450: Add memoization for repeated codec checks

Calling canPlayType() repeatedly for the same HEVC codec is unnecessary when processing multiple videos that may share codecs. Add a simple cache:

+  private readonly hevcSupportCache = new Map<string, boolean>();
+
   private canPlayHevcCodec (codecString: spec.HevcVideoCodec): boolean {
+    const cached = this.hevcSupportCache.get(String(codecString));
+    if (cached !== undefined) { return cached; }
+    
     const v = document.createElement('video');
     const contentType = `video/mp4; codecs="${codecString}"`;
     const result = v.canPlayType(contentType);
-
-    return result === 'probably' || result === 'maybe';
+    const ok = result === 'probably' || result === 'maybe';
+    this.hevcSupportCache.set(String(codecString), ok);
+    return ok;
   }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b1ed774 and 002ddcc.

📒 Files selected for processing (1)
  • packages/effects-core/src/asset-manager.ts (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-10T07:59:18.725Z
Learnt from: ChengYi996
Repo: galacean/effects-runtime PR: 1263
File: packages/effects-core/src/texture/ktx2/transcoder/binomial-workercode.ts:99-110
Timestamp: 2025-11-10T07:59:18.725Z
Learning: In packages/effects-core/src/texture/ktx2/transcoder/binomial-workercode.ts, the KTX2TargetFormat.ETC case in getTranscodeFormatFromTarget already handles ETC1 through the hasAlpha flag (returns BasisFormat.ETC1 when hasAlpha is false, BasisFormat.ETC2 when true), so a separate ETC1 case is not needed.

Applied to files:

  • packages/effects-core/src/asset-manager.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (1)
packages/effects-core/src/asset-manager.ts (1)

202-210: processVideoURL runs in parallel with bins/images; confirm this ordering is intended

You’re mutating jsonScene.videos while processBins/processImages run in the same Promise.all. If any downstream logic reads jsonScene.videos during those steps (now or in future), you can get surprising ordering dependencies. Consider running processVideoURL before the Promise.all (or at least add a brief comment that it’s safe to run concurrently).

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
packages/effects-core/src/fallback/particle.ts (1)

146-156: Consider properly typing textureSheetAnimation instead of suppressing errors.

The @ts-expect-error directive suppresses type checking for the textureSheetAnimation assignment. While this allows the code to compile, it bypasses TypeScript's type safety. Consider either updating the type definitions in @galacean/effects-specification to match the actual structure, or creating a proper type assertion.

Based on learnings, ensure this isn't temporary debugging code that should be properly implemented.

packages/effects-core/src/fallback/sprite.ts (1)

96-103: Consider properly typing textureSheetAnimation instead of suppressing errors.

Similar to the change in particle.ts, this @ts-expect-error directive bypasses type checking. Consider updating type definitions or using proper type assertions to maintain type safety.

packages/effects-core/src/utils/hevc-video.ts (1)

8-14: Consider caching the video element or results.

The function creates a new video element on each call. If this function is called multiple times with the same codec, consider caching either the video element or the results to improve performance.

+const codecCache = new Map<spec.HevcVideoCodec, boolean>();
+
 export function canPlayHevcCodec (codec: spec.HevcVideoCodec): boolean {
+  if (codecCache.has(codec)) {
+    return codecCache.get(codec)!;
+  }
+
   const video = document.createElement('video');
   const contentType = `video/mp4; codecs="${codec}"`;
   const result = video.canPlayType(contentType);
-
-  return result === 'probably' || result === 'maybe';
+  
+  const canPlay = result === 'probably' || result === 'maybe';
+  codecCache.set(codec, canPlay);
+  return canPlay;
 }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 002ddcc and 6b0ca42.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • packages/effects-core/package.json (1 hunks)
  • packages/effects-core/src/asset-manager.ts (3 hunks)
  • packages/effects-core/src/fallback/particle.ts (1 hunks)
  • packages/effects-core/src/fallback/sprite.ts (1 hunks)
  • packages/effects-core/src/plugins/sprite/sprite-item.ts (2 hunks)
  • packages/effects-core/src/utils/hevc-video.ts (1 hunks)
  • packages/effects-core/src/utils/index.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-08-05T07:51:18.728Z
Learnt from: ChengYi996
Repo: galacean/effects-runtime PR: 1118
File: packages/effects-core/src/components/ffd-component.ts:162-164
Timestamp: 2025-08-05T07:51:18.728Z
Learning: In packages/effects-core/src/components/ffd-component.ts, the //ts-expect-error usage for accessing siblingComponent.splits (around lines 162-164) is temporary debugging code that will be properly implemented later, as confirmed by ChengYi996.

Applied to files:

  • packages/effects-core/src/fallback/sprite.ts
  • packages/effects-core/src/plugins/sprite/sprite-item.ts
  • packages/effects-core/src/fallback/particle.ts
📚 Learning: 2025-12-09T08:44:15.153Z
Learnt from: Fryt1
Repo: galacean/effects-runtime PR: 1305
File: packages/effects-core/src/fallback/migration.ts:325-330
Timestamp: 2025-12-09T08:44:15.153Z
Learning: In `packages/effects-core/src/fallback/migration.ts`, the `textColor` 0-255 to 0-1 conversion in `version35Migration` is intentionally applied only to `TextComponent` and not to `RichTextComponent`, as confirmed by Fryt1.

Applied to files:

  • packages/effects-core/src/fallback/sprite.ts
  • packages/effects-core/src/fallback/particle.ts
📚 Learning: 2025-08-05T07:50:26.317Z
Learnt from: ChengYi996
Repo: galacean/effects-runtime PR: 1118
File: packages/effects-core/src/components/ffd-component.ts:135-219
Timestamp: 2025-08-05T07:50:26.317Z
Learning: In packages/effects-core/src/components/ffd-component.ts, the mesh subdivision logic (lines 147-219) within the collectSpriteComponents method is temporary debug code that will be properly implemented later, as confirmed by ChengYi996.

Applied to files:

  • packages/effects-core/src/plugins/sprite/sprite-item.ts
📚 Learning: 2024-10-18T09:15:08.038Z
Learnt from: wumaolinmaoan
Repo: galacean/effects-runtime PR: 691
File: packages/effects-core/src/plugins/timeline/playables/color-property-mixer-playable.ts:39-42
Timestamp: 2024-10-18T09:15:08.038Z
Learning: In `packages/effects-core/src/plugins/timeline/playables/color-property-mixer-playable.ts`, when accumulating color components, avoid using `clone()` methods because it can cause additional garbage collection overhead.

Applied to files:

  • packages/effects-core/src/plugins/sprite/sprite-item.ts
  • packages/effects-core/src/fallback/particle.ts
📚 Learning: 2025-11-10T07:59:18.725Z
Learnt from: ChengYi996
Repo: galacean/effects-runtime PR: 1263
File: packages/effects-core/src/texture/ktx2/transcoder/binomial-workercode.ts:99-110
Timestamp: 2025-11-10T07:59:18.725Z
Learning: In packages/effects-core/src/texture/ktx2/transcoder/binomial-workercode.ts, the KTX2TargetFormat.ETC case in getTranscodeFormatFromTarget already handles ETC1 through the hasAlpha flag (returns BasisFormat.ETC1 when hasAlpha is false, BasisFormat.ETC2 when true), so a separate ETC1 case is not needed.

Applied to files:

  • packages/effects-core/src/asset-manager.ts
🧬 Code graph analysis (1)
packages/effects-core/src/asset-manager.ts (1)
packages/effects-core/src/utils/hevc-video.ts (2)
  • parseCodec (21-33)
  • canPlayHevcCodec (8-14)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (8)
packages/effects-core/src/plugins/sprite/sprite-item.ts (1)

224-225: LGTM!

The formatting changes improve code clarity without altering functionality.

Also applies to: 242-243

packages/effects-core/src/utils/index.ts (1)

10-10: LGTM!

The export follows the established pattern and properly exposes the new HEVC utilities.

packages/effects-core/src/asset-manager.ts (3)

11-11: LGTM!

The imports are correctly added to support HEVC video processing.


208-208: LGTM!

The HEVC processing step is correctly integrated into the parallel loading pipeline with proper conditional execution when useHevcVideo is enabled. This addresses previous feedback about running in parallel with other loading steps.


407-425: LGTM!

The processVideoURL method correctly implements HEVC video URL processing. Previous review concerns have been addressed:

  • Type annotation uses spec.JSONScene instead of any
  • Uses forEach with return (correct for iteration skip)
  • Removes meaningless enum existence check
  • Properly validates hevc.url and hevc.codec before processing
packages/effects-core/src/utils/hevc-video.ts (2)

21-33: LGTM!

The parseCodec function correctly handles both enum value and enum key inputs, providing flexible parsing with appropriate fallback to undefined for invalid inputs.


35-45: LGTM!

The helper functions correctly validate codec strings against the enum definition using appropriate TypeScript type guards.

packages/effects-core/package.json (1)

54-54: Version 2.7.0 of @galacean/effects-specification is published on npm and no security advisories were found.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
plugin-packages/multimedia/src/utils.ts (1)

32-32: Error message references wrong variable.

The error message uses media (the entire array) instead of medium (the specific item that failed the renderLevel check). This makes debugging harder.

-    throw new Error(`Invalid ${type} source: ${JSON.stringify(media)}.`);
+    throw new Error(`Invalid ${type} source: ${JSON.stringify(medium)}.`);
🧹 Nitpick comments (2)
plugin-packages/multimedia/src/utils.ts (2)

82-86: Dead code branch due to type signature.

The url parameter is typed as string, making the else branch unreachable. Either remove the dead code or update the type signature to accept MediaProvider if that's a valid use case (similar to loadVideo in downloader.ts).

-    // 设置音频源
-    if (typeof url === 'string') {
-      audio.src = url;
-    } else {
-      audio.srcObject = url;
-    }
+    audio.src = url;

166-172: Consider using Object.values() for cleaner code.

The current implementation iterates over keys to check values. Using Object.values() would be more direct and readable.

 function isCodecValue (codec: string): codec is spec.HevcVideoCodec {
-  return Object
-    .keys(spec.HevcVideoCodec)
-    .some(key =>
-      spec.HevcVideoCodec[key as keyof typeof spec.HevcVideoCodec] as string === codec
-    );
+  return Object.values(spec.HevcVideoCodec).includes(codec as spec.HevcVideoCodec);
 }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6b0ca42 and 0667c47.

📒 Files selected for processing (1)
  • plugin-packages/multimedia/src/utils.ts (6 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
plugin-packages/multimedia/src/utils.ts (2)
packages/effects-core/src/downloader.ts (1)
  • loadVideo (271-303)
packages/effects-core/src/scene.ts (1)
  • SceneLoadOptions (62-146)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (4)
plugin-packages/multimedia/src/utils.ts (4)

108-127: LGTM!

The custom error class follows best practices: sets name properly and uses Error.captureStackTrace when available with appropriate feature detection.


134-140: LGTM!

Correctly uses canPlayType API to detect HEVC codec support.


147-159: LGTM!

The function correctly handles both enum value strings and enum key names, providing flexibility for consumers.


189-203: LGTM!

The function follows a clear fallback strategy: only use HEVC URL when explicitly enabled, HEVC config is present, and the browser supports the codec. Otherwise, gracefully falls back to the standard URL.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
plugin-packages/multimedia/src/utils.ts (2)

134-140: Consider caching or memoizing HEVC codec detection.

The function creates a new video element on each call. If canPlayHevcCodec is invoked multiple times with the same codec during scene loading, consider caching the results or reusing a single video element to improve performance.

Example caching approach:

+const codecCache = new Map<spec.HevcVideoCodec, boolean>();
+
 export function canPlayHevcCodec (codec: spec.HevcVideoCodec): boolean {
+  if (codecCache.has(codec)) {
+    return codecCache.get(codec)!;
+  }
   const video = document.createElement('video');
   const contentType = `video/mp4; codecs="${codec}"`;
   const result = video.canPlayType(contentType);
-
-  return result === 'probably' || result === 'maybe';
+  const canPlay = result === 'probably' || result === 'maybe';
+  codecCache.set(codec, canPlay);
+  return canPlay;
 }

166-172: Simplify with Object.values() for better readability.

The current implementation iterates through enum keys to check values. Using Object.values() is more direct and readable.

Apply this diff:

 function isCodecValue (codec: string): codec is spec.HevcVideoCodec {
-  return Object
-    .keys(spec.HevcVideoCodec)
-    .some(key =>
-      spec.HevcVideoCodec[key as keyof typeof spec.HevcVideoCodec] as string === codec
-    );
+  return Object.values(spec.HevcVideoCodec).includes(codec as spec.HevcVideoCodec);
 }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0667c47 and 8a92a1b.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (2)
  • packages/effects-core/package.json (1 hunks)
  • plugin-packages/multimedia/src/utils.ts (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/effects-core/package.json
🧰 Additional context used
🧬 Code graph analysis (1)
plugin-packages/multimedia/src/utils.ts (2)
packages/effects-core/src/downloader.ts (1)
  • loadVideo (271-303)
packages/effects-core/src/scene.ts (1)
  • SceneLoadOptions (62-146)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (5)
plugin-packages/multimedia/src/utils.ts (5)

12-36: LGTM! URL resolution logic is sound.

The addition of HEVC-aware video URL selection via getVideoUrl and the conversion to absolute URLs using new URL() properly handles both relative and absolute URL inputs.


147-159: LGTM! Codec parsing logic handles both enum values and keys correctly.

The function appropriately checks for enum values first, then enum keys, with a clear undefined fallback for invalid inputs.


179-181: LGTM! Clean and efficient enum key check.

The use of the in operator is the appropriate approach for checking enum key membership.


189-203: LGTM! HEVC fallback logic is well-structured.

The function correctly validates all preconditions (feature flag, HEVC data presence, codec validity, browser support) before selecting the HEVC URL, with appropriate fallback to the base URL.


134-203: Verify HEVC types are defined in @galacean/effects-specification@2.7.1.

The new HEVC functionality depends on spec.HevcVideoCodec enum and spec.VideoInfo.hevc property. Ensure these types are properly exported from the updated @galacean/effects-specification@2.7.1 package to avoid runtime errors.

Run the following script to verify the types are available:

#!/bin/bash
# Verify that HevcVideoCodec and VideoInfo.hevc are exported from the specification package

# Check if HevcVideoCodec is exported
rg -n "HevcVideoCodec" packages/effects-core/node_modules/@galacean/effects-specification/ --type-add 'types:*.d.ts' --type types -C3

# Check if VideoInfo has hevc property
rg -n "interface VideoInfo" packages/effects-core/node_modules/@galacean/effects-specification/ --type-add 'types:*.d.ts' --type types -A10

@yiiqii yiiqii merged commit b5a6cb7 into feat/2.8 Dec 16, 2025
2 checks passed
@yiiqii yiiqii deleted the feat/hevc branch December 16, 2025 11:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants