Sanic 实现 HTTP Range,解决前端视频无法拖动问题

python 复制代码
from sanic import Sanic, response
from sanic.response import json
from sanic.response.types import HTTPResponse, JSONResponse, ResponseStream
from mimetypes import guess_type
from sanic.compat import Header, open_async, stat_async
from sanic.response import file_stream
from urllib.parse import quote, unquote
import os


app = Sanic("private-web")

def parse_range_header(range_header, file_size):
    # 解析Range参数
    start, end = range_header.split('=')[1].split('-')
    start = int(start)
    end = int(end) if end else file_size - 1

    # 确保范围在文件大小范围内
    start = min(max(start, 0), file_size - 1)
    end = min(end, file_size - 1)

    return start, end

@app.route('/video/<vid:str>')
async def videoRange(request, vid):
    # 网址中文转码
    vid = unquote(vid)
    # 视频路径
    file_path = f"{vid}.mp4"
    # 获取文件大小
    file_size = os.path.getsize(file_path)
    # 获取请求头Range参数
    range_header = request.headers.get("Range")
    headers = {}

    if range_header:
        # 解析Range参数
        start, end = parse_range_header(range_header, file_size)
        status = 206
        headers["Content-Range"] = f"bytes {start}-{end}/{file_size}"
        headers['Content-Length'] = str(end - start + 1)
        chunk_size: int = 4096
        mime_type = None
        mime_type = mime_type or guess_type(file_path)[0] or "text/plain"
        # 这段代码就是拿 file_stream 里的源码改的,直接使用file_stream总是报错,有大佬帮忙解释并实现下吗
        async def _streaming_fn(response):
            async with await open_async(file_path, mode="rb") as f:
                await f.seek(start)
                to_send = end - start + 1
                while to_send > 0:
                    content = await f.read(min((to_send, chunk_size)))
                    if len(content) < 1:
                        break
                    to_send -= len(content)
                    await response.write(content)

        return ResponseStream(
            streaming_fn=_streaming_fn,
            status=status,
            headers=headers,
            content_type=mime_type,
        )
    else:
        return await file_stream(file_path, headers=headers)

if __name__ == '__main__':
    app.run(host='0.0.0.0')
相关推荐
DogDaoDao7 小时前
Android 硬件编码器参数完全指南:MediaCodec 深度解析
android·音视频·视频编解码·h264·硬编码·视频直播·mediacodec
wj3055853788 小时前
课程 9:模型测试记录与 Prompt 策略
linux·人工智能·python·comfyui
星寂樱易李8 小时前
iperf3 + Python-- 网络带宽、网速、网络稳定性
开发语言·网络·python
qingfeng154158 小时前
企业微信机器人开发:如何实现自动化与智能运营?
人工智能·python·机器人·自动化·企业微信
音视频牛哥8 小时前
大牛直播SDK(SmartMediaKit)Windows平台RTSP/RTMP直播播放SDK集成说明(C#版)
音视频·低延迟rtsp播放器·windows rtsp播放器·windows rtmp播放器·低延迟rtmp播放器·c# rtsp播放器·c# rtmp播放器
薛定猫AI11 小时前
【深度解析】Gemini Omni 多模态生成与 Agent 化创作工作流:从视频编辑到 UI 生成的技术演进
人工智能·ui·音视频
彦为君11 小时前
Agent 安全:从权限提示到沙箱隔离
python·ai·ai编程
PILIPALAPENG12 小时前
Python 语法速成指南:前端开发者视角(JS 类比版)
前端·人工智能·python
用户83562907805113 小时前
Python 操作 PowerPoint 页眉与页脚指南
后端·python