#17 YouTube 対応

This commit is contained in:
2025-08-25 23:30:41 +09:00
parent 34e79e9826
commit b8c2c221ca
4 changed files with 125 additions and 23 deletions
+48
View File
@@ -0,0 +1,48 @@
import YoutubeEmbed from 'react-youtube'
import NicoViewer from '@/components/NicoViewer'
import TwitterEmbed from '@/components/TwitterEmbed'
import type { FC } from 'react'
import type { Post } from '@/types'
type Props = { post: Post }
export default (({ post }: Props) => {
const url = new URL (post.url)
switch (url.hostname.split ('.').slice (-2).join ('.'))
{
case 'nicovideo.jp':
{
const [videoId] = url.pathname.match (/(?<=\/watch\/)[a-zA-Z0-9]+?(?=\/|$)/)!
return <NicoViewer id={videoId} width={640} height={360}/>
}
case 'twitter.com':
case 'x.com':
const [userId] = url.pathname.match (/(?<=\/)[^\/]+?(?=\/|$|\?)/)!
const [statusId] = url.pathname.match (/(?<=\/status\/)\d+?(?=\/|$|\?)/)!
return <TwitterEmbed userId={userId} statusId={statusId}/>
case 'youtube.com':
{
const [videoId] = url.pathname.match (/(?<=\/watch\?v\=)[a-zA-Z0-9]+?(?=\/|$|&)/)!
return (
<YoutubeEmbed videoId={videoId} opts={{ playerVars: {
playsinline: 1,
autoplay: 1,
mute: 0,
loop: 1,
width: '640',
height: '360' } }}/>)
}
}
return (
<a href={post.url} target="_blank">
<img src={post.thumbnailBase || post.thumbnail}
alt={post.url}
className="mb-4 w-full"/>
</a>)
}) satisfies FC<Props>