video curcse
All checks were successful
Deploy to Server / deploy (push) Successful in 26s

This commit is contained in:
jeremygan2021
2026-02-27 13:47:32 +08:00
parent f57edbd4ee
commit 357bd75f24
9 changed files with 206 additions and 44 deletions

View File

@@ -10,6 +10,32 @@
max-width: 100%;
}
}
.markdown-video-container {
width: 100%;
margin: 16px 0;
border-radius: 12px;
overflow: hidden;
position: relative;
background: #0a0a1a;
border: 1px solid rgba(0, 243, 255, 0.3);
box-shadow: 0 0 20px rgba(0, 243, 255, 0.1);
.markdown-video {
width: 100%;
height: 225px;
display: block;
}
.markdown-video-caption {
padding: 12px;
background: rgba(10, 10, 26, 0.9);
color: rgba(0, 243, 255, 0.9);
font-size: 14px;
text-align: center;
border-top: 1px solid rgba(255, 255, 255, 0.1);
}
}
}
.markdown-code-block {

View File

@@ -1,5 +1,5 @@
import React, { useMemo } from 'react'
import { View, RichText } from '@tarojs/components'
import { View, RichText, Video } from '@tarojs/components'
import { marked, Renderer } from 'marked'
import CodeBlock from './CodeBlock'
import './index.scss'
@@ -51,6 +51,11 @@ const MarkdownReader: React.FC<Props> = ({ content, themeColor = '#00b96b' }) =>
// Process tokens
tokens.forEach((token, index) => {
if (token.type === 'code') {
// Skip css blocks that look like the video component styles
if ((token.lang === 'css' || !token.lang) && token.text.includes('.simple-tech-video')) {
return
}
// Flush accumulated tokens
if (currentTokens.length > 0) {
// preserve links if any
@@ -69,6 +74,57 @@ const MarkdownReader: React.FC<Props> = ({ content, themeColor = '#00b96b' }) =>
/>
</View>
)
} else if (token.type === 'html') {
// Check for video tag
const videoRegex = /<video[^>]*>[\s\S]*?<source[^>]*src=["'](.*?)["'][^>]*>[\s\S]*?<\/video>/i
const simpleVideoRegex = /<video[^>]*src=["'](.*?)["'][^>]*>/i
const match = token.text.match(videoRegex) || token.text.match(simpleVideoRegex)
if (match) {
// Flush accumulated tokens
if (currentTokens.length > 0) {
(currentTokens as any).links = (tokens as any).links
const html = marked.parser(currentTokens as any, { renderer, breaks: true })
result.push(<RichText key={`rt-${index}`} nodes={html} className='markdown-text' />)
currentTokens = []
}
const src = match[1]
// Try to extract caption
const captionRegex = /class=["']video-caption["'][^>]*>(.*?)<\/div>/i
const captionMatch = token.text.match(captionRegex)
const caption = captionMatch ? captionMatch[1] : null
result.push(
<View key={`video-${index}`} className='markdown-video-container'>
<Video
src={src}
className='markdown-video'
controls
autoplay={false}
objectFit='contain'
showFullscreenBtn
showPlayBtn
showCenterPlayBtn
enablePlayGesture
/>
{caption && <View className='markdown-video-caption'>{caption}</View>}
</View>
)
} else {
// Filter out style tags for video component if they are parsed as HTML
if (token.text.includes('<style>') && token.text.includes('.simple-tech-video')) {
// If it's JUST the style tag, ignore it. If it's mixed with other content, we might need to be careful.
// But usually marked parses block HTML separately.
// Let's verify if we can just skip it.
// If the token is ONLY the style block, we skip it.
// If it contains other content, we might need to strip the style.
// For now, let's assume it's a block HTML token.
return
}
currentTokens.push(token)
}
} else {
currentTokens.push(token)
}