| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- import React from "react"
- interface VideoEmbedProps {
- url: string
- title?: string
- caption?: string
- }
- function extractVideoId(url: string): string | null {
- const patterns = [
- /(?:youtube\.com\/watch\?v=)([^&\s]+)/,
- /(?:youtube\.com\/embed\/)([^?\s]+)/,
- /(?:youtu\.be\/)([^?\s]+)/,
- /(?:youtube\.com\/v\/)([^?\s]+)/,
- ]
- for (const pattern of patterns) {
- const match = url.match(pattern)
- if (match) {
- return match[1] ?? null
- }
- }
- return null
- }
- export function VideoEmbed({ url, title = "Video", caption }: VideoEmbedProps) {
- const videoId = extractVideoId(url)
- if (!videoId) {
- return (
- <div
- style={{
- padding: "1rem",
- backgroundColor: "var(--red-100, #fee2e2)",
- color: "var(--red-700, #b91c1c)",
- borderRadius: "0.5rem",
- margin: "1.5rem 0",
- }}
- >
- Invalid YouTube URL: {url}
- </div>
- )
- }
- return (
- <div
- style={{
- maxWidth: "640px",
- margin: "1.5rem 0",
- }}
- >
- <div
- style={{
- position: "relative",
- paddingBottom: "56.25%",
- height: 0,
- overflow: "hidden",
- borderRadius: "0.5rem",
- }}
- >
- <iframe
- src={`https://www.youtube.com/embed/${videoId}`}
- title={title}
- style={{
- position: "absolute",
- top: 0,
- left: 0,
- width: "100%",
- height: "100%",
- border: "none",
- borderRadius: "0.5rem",
- }}
- allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
- allowFullScreen
- />
- </div>
- {caption && (
- <figcaption
- style={{
- fontStyle: "italic",
- textAlign: "center",
- marginTop: "0.5rem",
- color: "var(--gray-600, #6b7280)",
- }}
- >
- {caption}
- </figcaption>
- )}
- </div>
- )
- }
|