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')
相关推荐
0思必得020 分钟前
[Web自动化] Selenium处理滚动条
前端·爬虫·python·selenium·自动化
沈浩(种子思维作者)33 分钟前
系统要活起来就必须开放包容去中心化
人工智能·python·flask·量子计算
2301_7903009638 分钟前
Python数据库操作:SQLAlchemy ORM指南
jvm·数据库·python
美狐美颜SDK开放平台1 小时前
多终端适配下的人脸美型方案:美颜SDK工程开发实践分享
人工智能·音视频·美颜sdk·直播美颜sdk·视频美颜sdk
m0_736919101 小时前
用Pandas处理时间序列数据(Time Series)
jvm·数据库·python
getapi1 小时前
实时音视频传输与屏幕共享(投屏)
python
java干货1 小时前
为什么 “File 10“ 排在 “File 2“ 前面?解决文件名排序的终极算法:自然排序
开发语言·python·算法
机器懒得学习1 小时前
智能股票分析系统
python·深度学习·金融
毕设源码-郭学长1 小时前
【开题答辩全过程】以 基于python的二手房数据分析与可视化为例,包含答辩的问题和答案
开发语言·python·数据分析
SR_shuiyunjian2 小时前
Python第三次作业
python