This commit is contained in:
Vaica committed 2026-06-22 18:35:51 +08:00
1 parent 591abf5877
commit f70b603cf7
3 files changed
+56 -38

No files matched your search

+12 -12
View File
@@ -5711,12 +5711,23 @@ a.link-card:hover .link-card-arrow {
color: var(--accent, #3b82f6) !important; color: var(--accent, #3b82f6) !important;
} }
/* ==================== 视频样式(简约风格) ==================== */ /* ==================== 视频样式(Amigo 风格) ==================== */
.video-wrap { .video-wrap {
margin: 1.5rem 0; margin: 1.5rem 0;
} }
/* GIF 模式:透明背景,图片显示 */
.gif-image {
display: block;
max-width: 100%;
height: auto;
border-radius: 12px;
margin: 0 auto;
background: transparent;
}
/* 视频播放器 */
.video-player { .video-player {
position: relative; position: relative;
width: 100%; width: 100%;
@@ -5845,17 +5856,6 @@ a.link-card:hover .link-card-arrow {
color: #9ca3af; color: #9ca3af;
} }
/* GIF 模式:自动播放、循环、无控制栏 */
.video-player.gif-mode {
cursor: default;
}
.video-player.gif-mode video {
width: 100%;
max-height: 500px;
object-fit: contain;
}
[data-theme="dark"] .video-player { [data-theme="dark"] .video-player {
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4); box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
} }
+43 -25
View File
@@ -1,8 +1,9 @@
{{/* {{/*
视频嵌入 shortcode(简约风格) 视频嵌入 shortcode(Amigo 风格)
用法: 用法:
{{< video src="xxx.mp4" >}} {{< video src="xxx.mp4" >}}
{{< video src="xxx.mp4" poster="cover.jpg" caption="说明" >}} {{< video src="xxx.mp4" poster="cover.jpg" caption="说明" >}}
{{< video src="xxx.gif" loop="true" muted="true" >}} ← GIF 模式
{{< bilibili BV1xx411c7mD >}} {{< bilibili BV1xx411c7mD >}}
{{< youtube dQw4w9WgXcQ >}} {{< youtube dQw4w9WgXcQ >}}
*/}} */}}
@@ -46,30 +47,47 @@
{{ $videoSrc = printf "/%s/%s" .Page.Slug $src }} {{ $videoSrc = printf "/%s/%s" .Page.Slug $src }}
{{ end }} {{ end }}
<div class="video-wrap"> {{ if $isGifMode }}
<figure class="video-player gif-mode"> {{/* GIF 模式:图片标签显示,自动循环 */}}
<video <div class="video-wrap">
preload="auto" <img src="{{ $videoSrc }}" alt="{{ $caption }}" class="gif-image" loading="lazy">
playsinline {{ with $caption }}
webkit-playsinline <figcaption class="video-caption">{{ . }}</figcaption>
loop {{ end }}
muted </div>
autoplay {{ else }}
{{ with $poster }}poster="{{ . }}"{{ end }} {{/* 视频模式:自定义播放器 */}}
> <div class="video-wrap">
<source src="{{ $videoSrc }}"> <figure class="video-player" onclick="toggleVideo(this)">
</video> <video preload="metadata" playsinline webkit-playsinline {{ with $poster }}poster="{{ . }}"{{ end }}>
</figure> <source src="{{ $videoSrc }}">
{{ with $caption }} </video>
<figcaption class="video-caption">{{ . }}</figcaption> <div class="video-play-icon">
{{ end }} <svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
</div> </div>
<script> <div class="video-controls">
(function() { <button class="video-ctrl-btn" onclick="event.stopPropagation(); togglePlay(this)">
var v = document.currentScript.previousElementSibling.querySelector('video'); <svg class="icon-play" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
if (v) { v.muted = true; v.play().catch(function(){}); } <svg class="icon-pause" viewBox="0 0 24 24" fill="currentColor" style="display:none"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>
})(); </button>
</script> <div class="video-progress" onclick="event.stopPropagation(); seekVideo(event, this)">
<div class="video-progress-bar"></div>
</div>
<span class="video-time">0:00</span>
<button class="video-ctrl-btn" onclick="event.stopPropagation(); toggleMute(this)">
<svg class="icon-unmute" viewBox="0 0 24 24" fill="currentColor"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/></svg>
<svg class="icon-mute" viewBox="0 0 24 24" fill="currentColor" style="display:none"><path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z"/></svg>
</button>
<button class="video-ctrl-btn" onclick="event.stopPropagation(); fullscreenVideo(this)">
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/></svg>
</button>
</div>
</figure>
{{ with $caption }}
<figcaption class="video-caption">{{ . }}</figcaption>
{{ end }}
</div>
{{ end }}
{{ end }} {{ end }}
<script> <script>
+1 -1
View File
@@ -269,7 +269,7 @@ async function handleDocument(chatId: number, fileId: string, fileName?: string,
const gifPath = path.join(articleDir, gifFilename); const gifPath = path.join(articleDir, gifFilename);
try { try {
await sendMessage(chatId, "🎞️ 正在转换 GIF..."); await sendMessage(chatId, "🎞️ 正在转换 GIF...");
execSync(`ffmpeg -y -i "${fullPath}" -vf "fps=15,scale=480:-1:flags=lanczos" -loop 0 "${gifPath}"`, { timeout: 60000 }); execSync(`ffmpeg -y -i "${fullPath}" -vf "fps=15,scale=480:-1:flags=lanczos,split[s0][s1];[s0]palettegen=stats_mode=diff[p];[s1][p]paletteuse=dither=bayer:bayer_scale=5:diff_mode=rectangle" -loop 0 "${gifPath}"`, { timeout: 60000 });
fs.unlinkSync(fullPath); fs.unlinkSync(fullPath);
appendContent(chatId, `\n![${fileCaption}](${gifFilename})\n`); appendContent(chatId, `\n![${fileCaption}](${gifFilename})\n`);
await sendMessage(chatId, `🎞️ GIF 已转换:${gifFilename}`); await sendMessage(chatId, `🎞️ GIF 已转换:${gifFilename}`);