update ecommerce & Huangshan Introduction case

This commit is contained in:
kero-ly
2026-07-01 20:01:52 +08:00
parent 4658772f60
commit 6609e6a3b6
7 changed files with 182 additions and 13 deletions

View File

@@ -240,6 +240,9 @@ TRAFFIC_COPY = {
"video_names": {
"hero-companion-character": "首页主视觉:陪伴类角色",
"case-ecommerce-livestream": "案例:电商带货",
"case-ecommerce-livestream-front": "案例:电商直播正视",
"case-ecommerce-livestream-angle": "案例:电商带货斜视",
"case-huangshan-tour-guide": "案例:黄山文旅导览",
"case-news-anchor": "案例:新闻主播",
"case-companion-character": "案例:陪伴类角色",
"case-anime-talk-show": "案例:动漫脱口秀",
@@ -323,6 +326,9 @@ TRAFFIC_COPY = {
"video_names": {
"hero-companion-character": "Hero: Companion Character",
"case-ecommerce-livestream": "Case: E-commerce Livestream",
"case-ecommerce-livestream-front": "Case: E-commerce Front View",
"case-ecommerce-livestream-angle": "Case: E-commerce Angled View",
"case-huangshan-tour-guide": "Case: Huangshan Tourism Guide",
"case-news-anchor": "Case: News Anchor",
"case-companion-character": "Case: Companion Character",
"case-anime-talk-show": "Case: Anime Talk Show",

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 713 KiB

View File

@@ -16,7 +16,7 @@ export type CaseStudy = {
slug: string;
title: string;
eyebrow: string;
category: "livestream" | "media" | "character" | "companion" | "experiment";
category: "livestream" | "media" | "tourism" | "character" | "companion" | "experiment";
categoryLabel: string;
description: string;
detailIntro: string;
@@ -27,6 +27,13 @@ export type CaseStudy = {
accent: "cyan" | "mint" | "amber" | "violet" | "rose" | "slate";
comingSoon?: boolean;
videoUrl?: string;
videoVariants?: Array<{
title: string;
description: string;
url: string;
poster?: string;
videoId?: string;
}>;
sections: Array<{
title: string;
body: string;
@@ -83,6 +90,7 @@ export const caseCategories = [
{ key: "all", label: "全部场景" },
{ key: "livestream", label: "直播带货" },
{ key: "media", label: "媒体播报" },
{ key: "tourism", label: "文旅导览" },
{ key: "character", label: "角色内容" },
{ key: "companion", label: "陪伴互动" },
{ key: "experiment", label: "创意实验" },
@@ -130,11 +138,27 @@ export const caseStudies: CaseStudy[] = [
"面向商品讲解、评论问答和直播间陪跑,把语音回复、字幕和实时视频渲染整合到同一链路。",
detailIntro:
"用 OpenTalking 搭建一个可互动的数字人直播间,让商品介绍、用户问题和优惠转化都能通过实时语音和画面完成。",
route: "Local GPU 或 OmniRT 高质量路线",
route: "双机位直播带货演示",
features: ["实时问答", "角色音色", "字幕同步"],
image: "/images/cases/live-sales.jpeg",
image: "/images/cases/ecommerce-live-front-preview.png",
accent: "amber",
videoUrl: "https://1441945933.vod-qcloud.com/0b66444dvodcq1441945933/d9d848c95001834806724661995/SaicQA0Ah7QA.mp4",
videoUrl: "https://1441945933.vod-qcloud.com/0b66444dvodcq1441945933/742bcb745001834809665869890/vkxsFysr5REA.mp4",
videoVariants: [
{
title: "正视直播间",
description: "正面机位展示商品讲解、优惠信息和直播间视觉元素,适合官网主案例展示。",
url: "https://1441945933.vod-qcloud.com/0b66444dvodcq1441945933/742bcb745001834809665869890/vkxsFysr5REA.mp4",
poster: "/images/cases/ecommerce-live-front-preview.png",
videoId: "case-ecommerce-livestream-front",
},
{
title: "斜视带货机位",
description: "加入真实拍摄机位感,突出桌面商品、导购动作和直播场景的空间层次。",
url: "https://1441945933.vod-qcloud.com/0b66444dvodcq1441945933/cca683435001834809670031995/aswhi0HNmYkA.mp4",
poster: "/images/cases/ecommerce-live-angle-preview.png",
videoId: "case-ecommerce-livestream-angle",
},
],
sections: [
{
title: "场景挑战",
@@ -151,6 +175,37 @@ export const caseStudies: CaseStudy[] = [
],
outcomes: ["商品讲解自动化", "评论问答实时响应", "字幕与视频同步展示"],
},
{
slug: "huangshan-tour-guide",
title: "黄山文旅导览",
eyebrow: "沉浸讲解",
category: "tourism",
categoryLabel: "文旅导览",
description:
"面向景区、城市展馆和文旅宣传,用数字人讲解自然景观、路线亮点和地域文化。",
detailIntro:
"以黄山介绍为例,把景区画面、导览口播和数字讲解员结合起来,适合游客中心、城市展厅和线上文旅内容展示。",
route: "QuickTalk / FlashTalk",
features: ["景区讲解", "沉浸画面", "多语言扩展"],
image: "/images/cases/huangshan-guide-preview.png",
accent: "mint",
videoUrl: "https://1441945933.vod-qcloud.com/0b66444dvodcq1441945933/742bcf735001834809665869970/T9jkqMRNCacA.mp4",
sections: [
{
title: "场景挑战",
body: "文旅内容既要讲清景点特色,也要保持画面感染力和讲解节奏,传统拍摄更新成本较高。",
},
{
title: "适合扩展",
body: "可以接入景区知识库、路线推荐、多语言导览和游客问答,把单条宣传片扩展成可互动的数字导览员。",
},
{
title: "推荐模型",
body: "推荐 QuickTalk / FlashTalk先快速验证导览脚本和画面融合再按展厅大屏或宣传片质量要求升级。",
},
],
outcomes: ["景区讲解视频化", "导览内容可复用", "支持后续多语言与问答扩展"],
},
{
slug: "news-anchor",
title: "新闻主播",

View File

@@ -150,6 +150,7 @@ const enCaseCategories = [
{ key: "all", label: "All" },
{ key: "livestream", label: "Live commerce" },
{ key: "media", label: "Media" },
{ key: "tourism", label: "Tourism" },
{ key: "character", label: "Character content" },
{ key: "companion", label: "Companion" },
{ key: "experiment", label: "Creative demos" },
@@ -197,11 +198,27 @@ const enCaseStudies: CaseStudy[] = [
"Combine product narration, audience Q&A, captions, speech, and real-time avatar video in one live commerce workflow.",
detailIntro:
"Build an interactive AI host that can follow product scripts, answer audience questions, and present offers with synchronized voice and video.",
route: "Local GPU or OmniRT quality route",
route: "Two-view live commerce demo",
features: ["Real-time Q&A", "Voice persona", "Caption sync"],
image: "/images/cases/live-sales.jpeg",
image: "/images/cases/ecommerce-live-front-preview.png",
accent: "amber",
videoUrl: "https://1441945933.vod-qcloud.com/0b66444dvodcq1441945933/d9d848c95001834806724661995/SaicQA0Ah7QA.mp4",
videoUrl: "https://1441945933.vod-qcloud.com/0b66444dvodcq1441945933/742bcb745001834809665869890/vkxsFysr5REA.mp4",
videoVariants: [
{
title: "Front-facing livestream",
description: "A direct host view for product explanation, offer highlights, and live commerce UI elements.",
url: "https://1441945933.vod-qcloud.com/0b66444dvodcq1441945933/742bcb745001834809665869890/vkxsFysr5REA.mp4",
poster: "/images/cases/ecommerce-live-front-preview.png",
videoId: "case-ecommerce-livestream-front",
},
{
title: "Angled selling setup",
description: "A more realistic camera angle with visible products, presenter movement, and livestream staging.",
url: "https://1441945933.vod-qcloud.com/0b66444dvodcq1441945933/cca683435001834809670031995/aswhi0HNmYkA.mp4",
poster: "/images/cases/ecommerce-live-angle-preview.png",
videoId: "case-ecommerce-livestream-angle",
},
],
sections: [
{
title: "Scenario Challenge",
@@ -218,6 +235,37 @@ const enCaseStudies: CaseStudy[] = [
],
outcomes: ["Automated product narration", "Real-time audience response", "Synchronized captions and video"],
},
{
slug: "huangshan-tour-guide",
title: "Huangshan Tourism Guide",
eyebrow: "Immersive narration",
category: "tourism",
categoryLabel: "Tourism",
description:
"Use an avatar guide to introduce scenic areas, travel routes, cultural highlights, and destination stories.",
detailIntro:
"This Huangshan example combines scenic footage, guide narration, and a digital presenter for visitor centers, city exhibitions, and online tourism campaigns.",
route: "QuickTalk / FlashTalk",
features: ["Scenic narration", "Immersive visuals", "Multilingual-ready"],
image: "/images/cases/huangshan-guide-preview.png",
accent: "mint",
videoUrl: "https://1441945933.vod-qcloud.com/0b66444dvodcq1441945933/742bcf735001834809665869970/T9jkqMRNCacA.mp4",
sections: [
{
title: "Scenario Challenge",
body: "Tourism videos need clear destination storytelling, strong visuals, and a consistent narration rhythm, while updates can be costly with traditional shoots.",
},
{
title: "Extension Path",
body: "Connect destination knowledge, route recommendations, multilingual narration, and visitor Q&A to turn a video into an interactive digital guide.",
},
{
title: "Recommended Model",
body: "Recommended: QuickTalk / FlashTalk. Start by validating narration and scene composition, then upgrade quality for exhibition screens or destination campaigns.",
},
],
outcomes: ["Turn scenic content into guided video", "Reuse destination scripts", "Extend to multilingual Q&A later"],
},
{
slug: "news-anchor",
title: "News Anchor",
@@ -479,7 +527,7 @@ export const siteContent: Record<Language, SiteContent> = {
capabilityDescription: "OpenTalking 把会话、语音、字幕、播放和模型服务串成完整的数字人产品链路。",
showcaseEyebrow: "Showcase",
showcaseTitle: "真实产品场景,为数字人服务而生",
showcaseDescription: "用同一套编排层覆盖直播、播报、陪伴、角色内容和端到端演示。",
showcaseDescription: "用同一套编排层覆盖直播、文旅导览、播报、陪伴、角色内容和端到端演示。",
allCasesCta: "全部案例",
deploymentEyebrow: "Deployment",
deploymentTitle: "按你的需求匹配不同部署方式",
@@ -603,7 +651,7 @@ export const siteContent: Record<Language, SiteContent> = {
capabilityDescription: "OpenTalking connects dialogue, voice, captions, playback, and model services into a complete AI avatar workflow.",
showcaseEyebrow: "Showcase",
showcaseTitle: "Built for real avatar use cases",
showcaseDescription: "Use the same orchestration layer for livestreaming, broadcast, companion experiences, character content, and end-to-end demos.",
showcaseDescription: "Use the same orchestration layer for livestreaming, tourism guides, broadcast, companion experiences, character content, and end-to-end demos.",
allCasesCta: "All cases",
deploymentEyebrow: "Deployment",
deploymentTitle: "Pick the right path for your stage",

View File

@@ -1,4 +1,5 @@
import { ArrowLeft, CheckCircle2, ExternalLink, PlayCircle } from "lucide-react";
import { useEffect, useMemo, useState } from "react";
import { trackAnalyticsEvent } from "../analytics";
import { CaseCard } from "../components/CaseCard";
import type { CaseStudy } from "../content";
@@ -19,6 +20,32 @@ export function CaseDetailPage({
onBack,
onOpenCase,
}: CaseDetailPageProps) {
const videoItems = useMemo(() => {
if (item.videoVariants?.length) {
return item.videoVariants;
}
if (!item.videoUrl) {
return [];
}
return [
{
title: copy.videoTitle,
description: item.route,
url: item.videoUrl,
poster: item.image,
videoId: `case-${item.slug}`,
},
];
}, [copy.videoTitle, item]);
const [activeVideoIndex, setActiveVideoIndex] = useState(0);
const activeVideo = videoItems[Math.min(activeVideoIndex, Math.max(videoItems.length - 1, 0))];
useEffect(() => {
setActiveVideoIndex(0);
}, [item.slug]);
return (
<>
<section className="case-detail-hero">
@@ -51,17 +78,18 @@ export function CaseDetailPage({
<section className="section-container">
<div className="grid gap-8 lg:grid-cols-[1fr_340px]">
<article className="grid gap-6">
{item.videoUrl ? (
{activeVideo ? (
<div className="video-panel">
<div className="flex items-center gap-2 border-b border-white/14 px-5 py-4 text-white">
<PlayCircle className="h-5 w-5 text-indigo-200" />
<span className="font-semibold">{copy.videoTitle}</span>
</div>
<video
key={activeVideo.url}
className="aspect-video w-full bg-black"
src={item.videoUrl}
src={activeVideo.url}
controls
poster={item.image}
poster={activeVideo.poster ?? item.image}
onPlay={() =>
trackAnalyticsEvent({
eventName: "video_play",
@@ -69,10 +97,42 @@ export function CaseDetailPage({
language: window.location.pathname === "/en" || window.location.pathname.startsWith("/en/") ? "en" : "zh",
page: "caseDetail",
caseSlug: item.slug,
videoId: `case-${item.slug}`,
videoId: activeVideo.videoId ?? `case-${item.slug}`,
})
}
/>
{videoItems.length > 1 ? (
<div className="grid gap-3 border-t border-white/14 bg-indigo-950/95 p-4 md:grid-cols-2">
{videoItems.map((video, index) => {
const isActive = index === activeVideoIndex;
return (
<button
key={video.url}
type="button"
className={`group flex cursor-pointer gap-3 rounded-lg border p-2 text-left transition duration-300 ${
isActive
? "border-cyanline bg-white text-ink"
: "border-white/14 bg-white/10 text-white hover:border-white/30 hover:bg-white/20"
}`}
onClick={() => setActiveVideoIndex(index)}
>
<img
src={video.poster ?? item.image}
alt={`${video.title} preview`}
className="h-16 w-24 shrink-0 rounded-md object-cover"
/>
<span className="min-w-0">
<span className="block text-sm font-semibold">{video.title}</span>
<span className={`mt-1 block max-h-10 overflow-hidden text-xs leading-5 ${isActive ? "text-slate-600" : "text-white/70"}`}>
{video.description}
</span>
</span>
</button>
);
})}
</div>
) : null}
</div>
) : null}