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 (
+
+ {value === index && {children}}
+
+ )
+}
+
+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 && }