Chrome HTML5视频未加载

zpf6vheq  于 2023-09-28  发布在  Go
关注(0)|答案(2)|浏览(112)

我在React中有一个视频组件,可以在Firefox和Safari上使用,但在Chrome中不起作用。作为一个合理性检查,我创建了一个新的React应用程序(见下图),并添加了一个简单的视频标签,但视频不会在Chrome中加载,只能在Firefox中加载。我该如何解决此问题?

import './App.css';

function App() {
  return (
    <div className="App">
      <h1>Test</h1>
      <video
        muted
        preload="metadata"
      >
        <source
          src={`http://localhost:8005/video/test.mp4`}
          type="video/mp4"
        />
      </video>
    </div>
  );
}

export default App;

FastAPI端点

@router.get("/video/{file}", tags=["video"])
async def get_video_stream(file: str, range: str = Header(None)):
    if range is None:
        raise HTTPException(status_code=400, detail="Range header required")

    start, end = range.replace("bytes=", "").split("-")
    start = int(start)
    end = int(end) if end else start + CHUNK_SIZE
    video_path = Path(f"/app/videos/{file}")

    try:
        with open(video_path, "rb") as video:
            video.seek(start)
            data = video.read(end - start)
            filesize = str(video_path.stat().st_size)
            headers = {
                "Content-Range": f"bytes {str(start)}-{str(end)}/{filesize}",
                "Accept-Ranges": "bytes",
            }
            return Response(
                data, status_code=206, headers=headers, media_type="video/mp4"
            )
    except FileNotFoundError:
        logger.error(f"File not found: {video_path}")
        raise HTTPException(status_code=404, detail="Video not found")
vltsax25

vltsax251#

使用HTTPS:如果您在本地服务器上进行测试,请尝试对视频URL使用HTTPS而不是HTTP。Chrome对HTTP内容有更严格的规定。

oprakyz7

oprakyz72#

原来我的问题是我需要使用fastapi.responses.StreamResponse。以前我使用Response发送回视频块。我注意到,在Chrome浏览器的网络选项卡中,它向后端发送了相同的两个请求,Firefox和Safari在Chrome停止发送视频数据请求之前发送。这让我想到,在这两个初始请求中,它没有从后端得到预期的响应--就像一个preflight选项请求--所以我考虑了改变后端的方法,然后找到了StreamResponse

import mimetypes
from pathlib import Path
from fastapi import APIRouter, HTTPException
from fastapi.responses import StreamingResponse

router = APIRouter()
CHUNK_SIZE = 1024 * 1024

@router.get("/video/{file}", tags=["video"])
async def get_video_stream(file: str):
    video_path = Path(f"/app/videos/{file}")
    mime_type = mimetypes.types_map[video_path.suffix]

    if not video_path.exists():
        logger.error(f"File not found: {video_path}")
        raise HTTPException(status_code=404, detail="Video not found")

    async def iterfile():
        with open(video_path, mode="rb") as file:
            while chunk := file.read(CHUNK_SIZE):
                yield chunk

    return StreamingResponse(iterfile(), media_type=mime_type)

相关问题