关于前端video标签视频无法拖动进度条快进问题(Django)

Posted 骑着哈哥去旅行

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于前端video标签视频无法拖动进度条快进问题(Django)相关的知识,希望对你有一定的参考价值。

因为后端返回的是视频的文件流,并不是视频文件地址。后端返回流的时候要为header设置一些参数,否则部分浏览器会出现问题(如Google Chrome...)。

django中常用返回文件流写法:

class VideoAPIView(APIView):
    """
    视频视图  

    - 参数位置:
            查询参数

        - 请求参数:
            - 路径参数:
                - `id`: 文件id 必传

        - 成功返回参数:
            ```
            文件下载到本地
            ```

        - 失败返回参数:
            ```
            
                "rtCode": 0,
                "rtMsg": "异常信息",
                "rtData": ""
            
            ```
    """
    def get(self, request, file_info_id):
        try:
            contents_post = 
                "query": 
                    "match": 
                        "_id": file_info_id
                    
                ,
                "script": 
                    "source": "ctx._source['visits_nums'] = ctx._source['visits_nums']+1"
                
            
            elasticsearch.update_by_query(index=constants.ELASTICSEARCH_INDEX, body=contents_post)
            fileinfo_obj = models.FileInfo.objects.filter(file_info_id=file_info_id, delete_flag=FileInfo.DeleteFlagEnum.NOT_DELETE.value, file_type=FileInfo.FileTypeEnum.VIDEO.value)
            video_name = fileinfo_obj.first().file_url
        except models.FileInfo.DoesNotExist:
            raise exceptions.ValidationError("数据不存在")
        photo_path = constants.VIDEO_PATH
        file_url_path = os.path.join(photo_path, video_name)
        file_size = os.path.getsize(file_url_path)
        response = FileResponse(open(file_url_path, 'rb'))
        response['Content-Length'] = str(file_size)
        response['Content-Type'] = 'application/octet-stream'
        response['Content-Disposition'] = "attachment; filename=".format(urlquote(video_name))
        return response

这么写对于返回视频文件流,前端使用video标签展示时,就会出现部分浏览器无法拖动进度条快进问题。

解决:在返回的header中添加Content-Range和Accept-Ranges参数

class VideoAPIView(APIView):
    """
    视频视图

    - 参数位置:
            查询参数

        - 请求参数:
            - 路径参数:
                - `id`: 文件id 必传

        - 成功返回参数:
            ```
            文件下载到本地
            ```

        - 失败返回参数:
            ```
            
                "rtCode": 0,
                "rtMsg": "异常信息",
                "rtData": ""
            
            ```
    """
    def get(self, request, file_info_id):
        try:
            contents_post = 
                "query": 
                    "match": 
                        "_id": file_info_id
                    
                ,
                "script": 
                    "source": "ctx._source['visits_nums'] = ctx._source['visits_nums']+1"
                
            
            elasticsearch.update_by_query(index=constants.ELASTICSEARCH_INDEX, body=contents_post)
            fileinfo_obj = models.FileInfo.objects.filter(file_info_id=file_info_id, delete_flag=FileInfo.DeleteFlagEnum.NOT_DELETE.value, file_type=FileInfo.FileTypeEnum.VIDEO.value)
            video_name = fileinfo_obj.first().file_url
        except models.FileInfo.DoesNotExist:
            raise exceptions.ValidationError("数据不存在")
        photo_path = constants.VIDEO_PATH
        file_url_path = os.path.join(photo_path, video_name)
        file_size = os.path.getsize(file_url_path)
        response = FileResponse(open(file_url_path, 'rb'))
        response['Content-Length'] = str(file_size)
        response['Content-Type'] = 'application/octet-stream'
        response['Content-Range'] = f'bytes 0-str(file_size)/str(file_size)'
        response['Accept-Ranges'] = 'bytes'
        response['Content-Disposition'] = "attachment; filename=".format(urlquote(video_name))
        return response

关于Content-Range参数

用于响应头中,在发出带 Range 的请求后,服务器会在 Content-Range 头部返回当前接受的范围和文件总大小。一般格式:

Content-Range: bytes (unit first byte pos) - [last byte pos]/[entity legth]

例如:

Content-Range: bytes 0-499/22400

0-499 是指当前发送的数据的范围,而 22400 则是文件的总大小。

而在响应完成后,返回的响应头内容也不同:

HTTP/1.1 200 Ok(不使用断点续传方式) 
HTTP/1.1 206 Partial Content(使用断点续传方式)

以上是关于关于前端video标签视频无法拖动进度条快进问题(Django)的主要内容,如果未能解决你的问题,请参考以下文章

关于前端video标签视频无法拖动进度条快进问题(Django)

html+原生js做一个html5视频播放器

腾讯视频怎么快进

AVProVideo⭐️获取视频的进度,与快进和快退

html5 video 标签 怎样禁止拖动或者点击进度条

python-----opencv读视频循环读图片显示进度条