0

我正在尝试在我的 React 中实现 Plyr 以支持我播放视频。

这是我目前正在尝试使用的节点包:PLYR REACT

我得到了一个video来自 URL,它将是 mp4 或 HLS - 具体是m3u8URL。

我已成功附加它并播放了视频(但只有 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()
4

0 回答 0