From c773c279ca54b0fdf8c4b633c0c9cbecda3ff7ef Mon Sep 17 00:00:00 2001 From: Sora <8521327+SoraKasvgano@users.noreply.github.com> Date: Thu, 18 Dec 2025 14:11:32 +0800 Subject: [PATCH] add embed code. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Navidrome 分享播放器嵌入代码使用示例 ## 功能说明 在分享详情页(如 `http://127.0.0.1:4533/app/#/share/895AGkthN4`),现在会显示四种嵌入代码选项: ### 1. 左下角悬浮播放器 (推荐) 这是最适合博客和网页的嵌入方式,提供: - 🎵 可折叠的悬浮按钮 - 📱 响应式设计,支持移动端 - 🎨 美观的渐变样式 - 👆 点击展开/收起播放器 - 🔒 点击外部区域自动收起 **效果预览:** - 收起状态:左下角显示一个圆形音乐图标按钮 - 展开状态:显示完整的播放器界面(380x520px) ### 2. 基础 iframe 最简单的嵌入方式,适合: - 固定位置显示 - 快速集成 - 无需额外样式 ### 3. 响应式 iframe 自适应布局嵌入,适合: - 需要响应式设计的页面 - 博客文章内容区域 - 16:9 宽高比显示 ### 4. 右下角悬浮播放器 与左下角版本功能相同,但显示在右下角,可根据网页布局选择。 --- ## 使用方法 ### 步骤 1:创建分享 1. 在 Navidrome 中选择要分享的歌曲、专辑或播放列表 2. 点击"分享"按钮创建分享链接 3. 进入分享详情页 ### 步骤 2:获取嵌入代码 1. 在分享详情页向下滚动到"嵌入代码 (Embed Code)"区域 2. 选择需要的嵌入类型(推荐"左下角悬浮播放器") 3. 点击复制按钮复制代码 ### 步骤 3:嵌入到网页 将复制的代码粘贴到您的网页 HTML 中,通常在 `` 标签之前。 --- ## 代码示例 ### 示例 1:博客文章中添加悬浮播放器 ```html 我的博客文章

我的音乐分享

这是我最喜欢的音乐收藏...

``` ### 示例 2:WordPress 博客 在 WordPress 中使用自定义 HTML 块: 1. 添加"自定义 HTML"块 2. 粘贴嵌入代码 3. 发布文章 ### 示例 3:个人网站多个页面共享 将嵌入代码添加到网站模板的 footer 中,所有页面都会显示悬浮播放器。 --- ## 自定义样式 如果需要自定义悬浮播放器的位置或样式,可以修改嵌入代码中的 CSS: ### 修改位置 ```css /* 修改为右下角 */ #navidrome-floating-player { right: 20px; /* 改为 right */ bottom: 20px; } /* 修改为右上角 */ #navidrome-floating-player { right: 20px; top: 20px; /* 改为 top */ } ``` ### 修改大小 ```css /* 展开时的大小 */ #nav-player-container.nav-expanded { width: 450px; /* 修改宽度 */ height: 600px; /* 修改高度 */ } /* 按钮大小 */ #nav-player-toggle { width: 70px; /* 修改按钮宽度 */ height: 70px; /* 修改按钮高度 */ } ``` ### 修改颜色主题 ```css /* 按钮渐变色 */ #nav-player-toggle { background: linear-gradient(135deg, #FF6B6B 0%, #4ECDC4 100%); } ``` --- ## 注意事项 1. **跨域问题**:确保 Navidrome 服务器配置允许 iframe 嵌入 2. **HTTPS**:如果您的网站使用 HTTPS,Navidrome 也需要配置 HTTPS 3. **分享过期**:嵌入的播放器依赖分享链接,注意设置合适的过期时间 4. **移动端优化**:悬浮播放器已包含移动端适配,但建议在移动设备上测试效果 --- ## 浏览器兼容性 悬浮播放器支持所有现代浏览器: - ✅ Chrome/Edge (88+) - ✅ Firefox (85+) - ✅ Safari (14+) - ✅ iOS Safari (14+) - ✅ Android Chrome (88+) --- ## 功能特性 ### 悬浮播放器特性 - ✨ 平滑展开/收起动画 - 🎯 自动定位到角落 - 🖱️ 悬停放大效果 - 📱 移动端自适应 - 🎨 渐变色设计 - 🔊 完整的 APlayer 功能支持 ### APlayer 功能 - 🎵 播放/暂停控制 - ⏭️ 上一首/下一首 - 🔀 随机播放 - 🔁 循环模式 - 🎚️ 音量控制 - 📋 播放列表 - 📥 下载功能(如果启用) --- ## 技术支持 如果遇到问题,可以: 1. 检查浏览器控制台是否有错误 2. 确认 Navidrome 服务器正常运行 3. 验证分享链接是否有效 4. 提交 Issue 到 Navidrome GitHub 仓库 --- ui/src/share/EmbedCodeField.jsx | 300 ++++++++++++++++++++++++++++++++ ui/src/share/ShareEdit.jsx | 10 +- 2 files changed, 309 insertions(+), 1 deletion(-) create mode 100644 ui/src/share/EmbedCodeField.jsx diff --git a/ui/src/share/EmbedCodeField.jsx b/ui/src/share/EmbedCodeField.jsx new file mode 100644 index 000000000..c8df4c2ac --- /dev/null +++ b/ui/src/share/EmbedCodeField.jsx @@ -0,0 +1,300 @@ +import React, { useState } from 'react' +import { + Box, + Typography, + TextField, + IconButton, + Tabs, + Tab, + makeStyles, + Snackbar, +} from '@material-ui/core' +import FileCopyIcon from '@material-ui/icons/FileCopy' + +const useStyles = makeStyles((theme) => ({ + root: { + marginBottom: theme.spacing(3), + }, + tabPanel: { + marginTop: theme.spacing(2), + }, + codeField: { + fontFamily: 'monospace', + fontSize: '12px', + '& .MuiInputBase-root': { + fontFamily: 'monospace', + fontSize: '12px', + }, + }, + copyButton: { + marginLeft: theme.spacing(1), + }, + header: { + display: 'flex', + alignItems: 'center', + marginBottom: theme.spacing(1), + }, +})) + +const TabPanel = ({ children, value, index, ...other }) => { + return ( + + ) +} + +export const EmbedCodeField = ({ url, title = 'Music Player' }) => { + const classes = useStyles() + const [tabValue, setTabValue] = useState(0) + const [snackbarOpen, setSnackbarOpen] = useState(false) + + const handleTabChange = (event, newValue) => { + setTabValue(newValue) + } + + const handleCopy = (text) => { + navigator.clipboard.writeText(text).then(() => { + setSnackbarOpen(true) + }) + } + + const handleSnackbarClose = () => { + setSnackbarOpen(false) + } + + // 基础 iframe 嵌入代码 + const iframeEmbed = `` + + // 响应式 iframe 嵌入代码 + const responsiveEmbed = `
+ +
` + + // 左下角悬浮播放器嵌入代码 + const floatingPlayerEmbed = ` + + + + +` + + // 右下角悬浮播放器(备选) + const floatingPlayerRightEmbed = floatingPlayerEmbed + .replace('left: 20px;', 'right: 20px;') + .replace('left: 10px;', 'right: 10px;') + + const embedOptions = [ + { + label: '左下角悬浮播放器', + code: floatingPlayerEmbed, + description: '可折叠的左下角悬浮播放器,用户可点击展开/收起', + }, + { + label: '基础 iframe', + code: iframeEmbed, + description: '简单的 iframe 嵌入,适合固定位置显示', + }, + { + label: '响应式 iframe', + code: responsiveEmbed, + description: '16:9 响应式布局,自适应不同屏幕宽度', + }, + { + label: '右下角悬浮播放器', + code: floatingPlayerRightEmbed, + description: '可折叠的右下角悬浮播放器(备选位置)', + }, + ] + + return ( + + + 嵌入代码 (Embed Code) + + + + {embedOptions.map((option, index) => ( + + ))} + + + {embedOptions.map((option, index) => ( + + + {option.description} + + + + 20 ? 20 : 12} + variant="outlined" + value={option.code} + className={classes.codeField} + InputProps={{ + readOnly: true, + }} + /> + handleCopy(option.code)} + color="primary" + size="small" + title="复制代码" + > + + + + + + 提示:将此代码复制并粘贴到您的网页 HTML 中即可使用 + + + ))} + + + + ) +} diff --git a/ui/src/share/ShareEdit.jsx b/ui/src/share/ShareEdit.jsx index d7287c3a3..009581511 100644 --- a/ui/src/share/ShareEdit.jsx +++ b/ui/src/share/ShareEdit.jsx @@ -7,9 +7,10 @@ import { TextInput, } from 'react-admin' import { sharePlayerUrl, shareAPlayerUrl } from '../utils' -import { Link, Box, Typography } from '@material-ui/core' +import { Link, Box, Typography, Divider } from '@material-ui/core' import { DateField } from '../common' import config from '../config' +import { EmbedCodeField } from './EmbedCodeField' export const ShareEdit = (props) => { const { id, basePath, hasCreate, ...rest } = props @@ -34,6 +35,13 @@ export const ShareEdit = (props) => { {aplayerUrl} + + + + + + + {config.enableDownloads && }