mirror of
https://github.com/wassname/optuna-dashboard.git
synced 2026-09-11 12:30:25 +08:00
Merge pull request #716 from toshihikoyanase/add-wavesurfer
Use WaveSurfer instead of `audio` tag.
This commit is contained in:
@@ -3,6 +3,7 @@ import {
|
||||
ThreejsArtifactViewer,
|
||||
isThreejsArtifact,
|
||||
} from "./ThreejsArtifactViewer"
|
||||
import { WaveSurferArtifactViewer } from "./WaveSurferArtifactViewer"
|
||||
import InsertDriveFileIcon from "@mui/icons-material/InsertDriveFile"
|
||||
import { CardMedia, Box } from "@mui/material"
|
||||
|
||||
@@ -43,9 +44,12 @@ export const ArtifactCardMedia: FC<{
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<audio controls style={{ width: "100%" }}>
|
||||
<source src={urlPath} type={artifact.mimetype} />
|
||||
</audio>
|
||||
<WaveSurferArtifactViewer
|
||||
height={100}
|
||||
waveColor="rgb(200, 0, 200)"
|
||||
progressColor="rgb(100, 0, 100)"
|
||||
url={urlPath}
|
||||
/>
|
||||
</Box>
|
||||
)
|
||||
} else if (artifact.mimetype.startsWith("image")) {
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
import React, { useCallback, useEffect, useState, useRef } from "react"
|
||||
import WaveSurfer from "wavesurfer.js"
|
||||
import { Box } from "@mui/material"
|
||||
|
||||
interface WaveSurferArtifactViewerProps {
|
||||
height: number
|
||||
waveColor: string
|
||||
progressColor: string
|
||||
url: string
|
||||
}
|
||||
|
||||
const useWavesurfer = (
|
||||
containerRef: React.MutableRefObject<HTMLDivElement>,
|
||||
options: WaveSurferArtifactViewerProps
|
||||
) => {
|
||||
const [wavesurfer, setWavesurfer] = useState<WaveSurfer | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (!containerRef.current) return
|
||||
|
||||
const ws = WaveSurfer.create({
|
||||
...options,
|
||||
container: containerRef.current,
|
||||
})
|
||||
|
||||
setWavesurfer(ws)
|
||||
|
||||
return () => {
|
||||
ws.destroy()
|
||||
}
|
||||
}, [containerRef])
|
||||
|
||||
return wavesurfer
|
||||
}
|
||||
|
||||
// Create a React component of wavesurfer.
|
||||
export const WaveSurferArtifactViewer: React.FC<
|
||||
WaveSurferArtifactViewerProps
|
||||
> = (props) => {
|
||||
const containerRef = useRef<HTMLDivElement>(null!)
|
||||
const [isPlaying, setIsPlaying] = useState(false)
|
||||
const wavesurfer = useWavesurfer(containerRef, props)
|
||||
|
||||
const onPlayClick = useCallback(() => {
|
||||
if (!wavesurfer) return
|
||||
wavesurfer.isPlaying() ? wavesurfer.pause() : wavesurfer.play()
|
||||
}, [wavesurfer])
|
||||
|
||||
useEffect(() => {
|
||||
if (!wavesurfer) return
|
||||
|
||||
setIsPlaying(false)
|
||||
|
||||
const subscriptions = [
|
||||
wavesurfer.on("play", () => setIsPlaying(true)),
|
||||
wavesurfer.on("pause", () => setIsPlaying(false)),
|
||||
]
|
||||
|
||||
return () => {
|
||||
subscriptions.forEach((unsub) => unsub())
|
||||
}
|
||||
}, [wavesurfer])
|
||||
|
||||
return (
|
||||
<Box style={{ width: "100%", display: "flex", flexDirection: "column" }}>
|
||||
<div ref={containerRef} style={{ minHeight: "120px", width: "100%" }} />
|
||||
<button onClick={onPlayClick} style={{ marginTop: "1em" }}>
|
||||
{isPlaying ? "Pause" : "Play"}
|
||||
</button>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
Generated
+12
-1
@@ -32,7 +32,8 @@
|
||||
"rehype-raw": "^6.1.1",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"remark-math": "^5.1.1",
|
||||
"three": "^0.155.0"
|
||||
"three": "^0.155.0",
|
||||
"wavesurfer.js": "^7.4.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.14.3",
|
||||
@@ -14824,6 +14825,11 @@
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wavesurfer.js": {
|
||||
"version": "7.4.12",
|
||||
"resolved": "https://registry.npmjs.org/wavesurfer.js/-/wavesurfer.js-7.4.12.tgz",
|
||||
"integrity": "sha512-KzH4LkcOp8LECs9cOVIPBl6vsSoICKuZz+v5kh/zvxilpaVszU+QKC+4s2KEAqcCxBCecg3cNSg4RqAx278F8g=="
|
||||
},
|
||||
"node_modules/web-namespaces": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz",
|
||||
@@ -25938,6 +25944,11 @@
|
||||
"graceful-fs": "^4.1.2"
|
||||
}
|
||||
},
|
||||
"wavesurfer.js": {
|
||||
"version": "7.4.12",
|
||||
"resolved": "https://registry.npmjs.org/wavesurfer.js/-/wavesurfer.js-7.4.12.tgz",
|
||||
"integrity": "sha512-KzH4LkcOp8LECs9cOVIPBl6vsSoICKuZz+v5kh/zvxilpaVszU+QKC+4s2KEAqcCxBCecg3cNSg4RqAx278F8g=="
|
||||
},
|
||||
"web-namespaces": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz",
|
||||
|
||||
+2
-1
@@ -41,7 +41,8 @@
|
||||
"rehype-raw": "^6.1.1",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"remark-math": "^5.1.1",
|
||||
"three": "^0.155.0"
|
||||
"three": "^0.155.0",
|
||||
"wavesurfer.js": "^7.4.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.14.3",
|
||||
|
||||
Reference in New Issue
Block a user