我正在尝试在我的 React 中实现 Plyr 以支持我播放视频。
这是我目前正在尝试使用的节点包:PLYR REACT
我得到了一个video
来自 URL,它将是 mp4 或 HLS - 具体是m3u8
URL。
我已成功附加它并播放了视频(但只有 HLS - m3u8 url),我无法显示它的质量控制。
如果是 MP4 URL,则整个函数将不会继续,只会返回blank video
,这是我不想要的。
那么,如何检测它是 mp4 还是 m3u8 URL?而且我只想在 m3u8 URL 中进行质量控制。你可以在我的代码中看到这一点。
整个getList
很长,但我收到的视频网址在第二部分response
,所以请随意跳过整个getList
功能的前半部分。
这是我的代码:
import { useState, useEffect, useRef } from "react"
import { useParams } from "react-router-dom"
import axios from "axios"
import Plyr from "plyr-react"
import Hls from "hls.js"
import "plyr-react/dist/plyr.css"
import "./animewatch.css"
function AnimeWatch({ instance }) {
const videoPlayer = useRef(null)
const { anime } = useParams()
const queryParams = new URLSearchParams(window.location.search)
const index = queryParams.get("index")
const [info, setInfo] = useState([])
const [titleAnime, setTitleAnime] = useState("")
const [currentEpisodeName, setCurrentEpisodeName] = useState("")
useEffect(() => {
const CancelToken = axios.CancelToken
const source = CancelToken.source()
const getList = async () => {
await instance
.get(`/watch/${anime}`, {
cancelToken: source.token,
})
.then(async (response) => {
const mainId = response.data.data.id
const numIndex = Number(index)
setTitleAnime(response.data.data.name)
setInfo(response.data.data.episodes)
await instance
.get(`/anime/${mainId}/episodes/${numIndex}`, {
cancelToken: source.token,
})
.then((res) => {
// VIDEO URL IS HERE, It'll be m3u8 or else mp4
const videoUrl = res.data.data.videoSource
const videoElement = videoPlayer.current.plyr.media
const hls = new Hls()
hls.loadSource(videoUrl)
hls.on(Hls.Events.MANIFEST_PARSED, function (event, data) {
// Transform available levels into an array of integers (height values).
const availableQualities = hls.levels.map((l) => l.height)
// If it's m3u8, it can get quality controls from here, and it's worked.
videoPlayer.current.plyr.config.quality = {
default: availableQualities[availableQualities.length - 1],
options: availableQualities,
// this ensures Plyr to use Hls to update quality level
forced: true,
}
})
// But somehow I can't attach these quality controls into my PLYR
hls.attachMedia(videoElement)
setCurrentEpisodeName(res.data.data.full_name)
})
})
.catch((thrown) => {
if (axios.isCancel(thrown)) return
})
}
getList()
return () => {
source.cancel()
}
}, [])
return (
<>
<div style={{ marginTop: "-90px" }}>
<div>
<Plyr ref={videoPlayer} />
</div>
</div>
</>
)
}
export default AnimeWatch
更新:
我尝试阅读了一下并能够对 mp4 和 m3u8 URL 进行分类,但我仍然真的不知道如何将其实现为 Plyr(MP4),HLS m3u8
我只知道如何实现其最简单的形式,我仍然无法对其实施质量控制。
这就是我现在的做法。
// VIDEO URL IS HERE
const videoUrl = res.data.data.videoSource
let xhttp = new XMLHttpRequest()
xhttp.open("HEAD", videoUrl)
if (this.readyState == this.DONE) {
if (this.getResponseHeader("Content-Type") === "video/mp4") {
console.log("This is mp4")
} else {
console.log("This is m3u8")
const videoElement = videoPlayer.current.plyr.media
const hls = new Hls()
hls.loadSource(videoUrl)
hls.attachMedia(videoElement)
}
}
}
xhttp.send()