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')
相关推荐
waterHBO14 分钟前
清理 pycharm 无效解释器
ide·python·pycharm
Code_流苏26 分钟前
Python趣学篇:用Pygame打造绚烂流星雨动画
开发语言·python·pygame·图形编程·粒子系统·流星雨特效
胖哥真不错34 分钟前
Python实现HPSO-TVAC优化算法优化支持向量机SVC分类模型项目实战
python·机器学习·支持向量机·毕业设计·项目实战·hpso-tvac优化算法·支持向量机svc分类模型
小眼睛羊羊41 分钟前
记一次renderdoc自动截帧
python
deephub1 小时前
BayesFlow:基于神经网络的摊销贝叶斯推断框架
人工智能·python·深度学习·神经网络·机器学习·贝叶斯
茶本无香1 小时前
HTTP协议接口三种测试方法之-JMeter(保姆教程)
网络协议·jmeter·http
蜗牛的旷野1 小时前
华为OD机试_2025 B卷_小华地图寻宝(Python,100分)(附详细解题思路)
开发语言·python·华为od
勤奋的小王同学~1 小时前
(javaSE)Java数组进阶:数组初始化 数组访问 数组中的jvm 空指针异常
开发语言·python
张海森-1688201 小时前
isp中的 ISO代表什么意思
音视频
哆啦A梦的口袋呀2 小时前
基于Python学习《Head First设计模式》 第一章 策略模式
python·学习·设计模式