|
|
@@ -1,5 +1,5 @@
|
|
|
-import React from "react";
|
|
|
-import { Composition, Sequence, AbsoluteFill, Audio, staticFile, Img, useCurrentFrame, interpolate } from "remotion";
|
|
|
+import React, { useEffect, useState } from "react";
|
|
|
+import { Composition, Sequence, AbsoluteFill, Audio, staticFile, Img, useCurrentFrame, interpolate, continueRender, delayRender } from "remotion";
|
|
|
import type { TemplateType, AspectRatio } from "@pipeline/shared";
|
|
|
import type { WordTimestamp } from "@pipeline/shared";
|
|
|
import NewsScene from "./news/index";
|
|
|
@@ -163,7 +163,7 @@ const CoverScene: React.FC<{
|
|
|
}}>
|
|
|
<div style={{
|
|
|
fontSize: 72, fontWeight: 800, color: "white",
|
|
|
- fontFamily: "sans-serif", lineHeight: 1.2, marginBottom: 20,
|
|
|
+ fontFamily: "Noto Sans SC", lineHeight: 1.2, marginBottom: 20,
|
|
|
maxWidth: "80%",
|
|
|
}}>
|
|
|
{title}
|
|
|
@@ -171,7 +171,7 @@ const CoverScene: React.FC<{
|
|
|
{subtitle && (
|
|
|
<div style={{
|
|
|
fontSize: 28, color: "rgba(255,255,255,0.7)",
|
|
|
- fontFamily: "sans-serif", marginBottom: 40,
|
|
|
+ fontFamily: "Noto Sans SC", marginBottom: 40,
|
|
|
}}>
|
|
|
{subtitle}
|
|
|
</div>
|
|
|
@@ -181,7 +181,7 @@ const CoverScene: React.FC<{
|
|
|
{keyframes.map((kf, i) => (
|
|
|
<div key={i} style={{
|
|
|
fontSize: 22, color: "rgba(255,255,255,0.5)",
|
|
|
- fontFamily: "sans-serif",
|
|
|
+ fontFamily: "Noto Sans SC",
|
|
|
}}>
|
|
|
{kf.content}
|
|
|
</div>
|
|
|
@@ -212,7 +212,7 @@ const OutroScene: React.FC<{
|
|
|
}}>
|
|
|
<div style={{
|
|
|
fontSize: 48, fontWeight: 700, color: "white",
|
|
|
- fontFamily: "sans-serif", lineHeight: 1.4, marginBottom: 40,
|
|
|
+ fontFamily: "Noto Sans SC", lineHeight: 1.4, marginBottom: 40,
|
|
|
maxWidth: "80%",
|
|
|
}}>
|
|
|
{text}
|
|
|
@@ -220,7 +220,7 @@ const OutroScene: React.FC<{
|
|
|
{cta && (
|
|
|
<div style={{
|
|
|
fontSize: 28, fontWeight: 600, color: "#fbbf24",
|
|
|
- fontFamily: "sans-serif",
|
|
|
+ fontFamily: "Noto Sans SC",
|
|
|
padding: "16px 48px",
|
|
|
borderRadius: 12,
|
|
|
border: "2px solid #fbbf24",
|
|
|
@@ -314,6 +314,54 @@ const defaultProps: RemotionProps = {
|
|
|
};
|
|
|
|
|
|
export const RemotionRoot: React.FC = () => {
|
|
|
+ // Load bundled Noto Sans SC at component mount (staticFile() requires the
|
|
|
+ // bundle context which is only ready after the component tree mounts).
|
|
|
+ const [fontHandle] = useState(() => delayRender("Loading Noto Sans SC"));
|
|
|
+ useEffect(() => {
|
|
|
+ let cancelled = false;
|
|
|
+ try {
|
|
|
+ const style = document.createElement("style");
|
|
|
+ style.textContent = `
|
|
|
+ @font-face {
|
|
|
+ font-family: "Noto Sans SC";
|
|
|
+ src: local("Noto Sans CJK SC"),
|
|
|
+ url(${staticFile("fonts/NotoSansSC-Regular.ttf")}) format("truetype");
|
|
|
+ font-weight: 400;
|
|
|
+ font-display: block;
|
|
|
+ }
|
|
|
+ @font-face {
|
|
|
+ font-family: "Noto Sans SC";
|
|
|
+ src: local("Noto Sans CJK SC"),
|
|
|
+ url(${staticFile("fonts/NotoSansSC-Bold.ttf")}) format("truetype");
|
|
|
+ font-weight: 700;
|
|
|
+ font-display: block;
|
|
|
+ }
|
|
|
+ `;
|
|
|
+ document.head.appendChild(style);
|
|
|
+
|
|
|
+ const fonts = document.fonts as unknown as {
|
|
|
+ load: (font: string) => Promise<unknown>;
|
|
|
+ };
|
|
|
+ Promise.all([
|
|
|
+ fonts.load('400 16px "Noto Sans SC"'),
|
|
|
+ fonts.load('700 16px "Noto Sans SC"'),
|
|
|
+ ])
|
|
|
+ .then(() => {
|
|
|
+ if (!cancelled) continueRender(fontHandle);
|
|
|
+ })
|
|
|
+ .catch((err) => {
|
|
|
+ console.error("Font loading failed:", err);
|
|
|
+ if (!cancelled) continueRender(fontHandle);
|
|
|
+ });
|
|
|
+ } catch (err) {
|
|
|
+ console.error("Font init failed:", err);
|
|
|
+ continueRender(fontHandle);
|
|
|
+ }
|
|
|
+ return () => {
|
|
|
+ cancelled = true;
|
|
|
+ };
|
|
|
+ }, [fontHandle]);
|
|
|
+
|
|
|
return (
|
|
|
<>
|
|
|
{TEMPLATES.map((template) =>
|