current position:Home>About the problem that the front-end video tag video cannot drag the progress bar fast forward (Django)

About the problem that the front-end video tag video cannot drag the progress bar fast forward (Django)

2022-07-25 09:27:23Ride Hago to travel

Because the back end returns the file stream of the video , Not the video file address . When the back-end returns the flow, it should be header Set some parameters , Otherwise, some browsers will have problems ( Such as Google Chrome...).

django Commonly used return file stream writing method :

class VideoAPIView(APIView):
    """
     Video view   

    -  Parameter position :
             Query parameters 

        -  Request parameters :
            -  Path parameter :
                - `id`:  file id  Will pass 

        -  Parameters returned successfully :
            ```
             Download the file locally 
            ```

        -  Failure return parameters :
            ```
            {
                "rtCode": 0,
                "rtMsg": " Abnormal information ",
                "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(" The data doesn't exist ")
        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

This is for returning the video file stream , Front end use video When displaying labels , There will be a problem that some browsers cannot drag the progress bar fast forward .

solve : In the returned header Add Content-Range and Accept-Ranges Parameters

class VideoAPIView(APIView):
    """
     Video view 

    -  Parameter position :
             Query parameters 

        -  Request parameters :
            -  Path parameter :
                - `id`:  file id  Will pass 

        -  Parameters returned successfully :
            ```
             Download the file locally 
            ```

        -  Failure return parameters :
            ```
            {
                "rtCode": 0,
                "rtMsg": " Abnormal information ",
                "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(" The data doesn't exist ")
        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

About Content-Range Parameters

Used in response header , In the hair belt Range After request , The server will be in Content-Range The header returns the currently accepted range and the total size of the file . General format :

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

for example :

Content-Range: bytes 0-499/22400

0-499 It refers to the range of data currently sent , and 22400 Is the total size of the file .

And after the response , The returned response header content is also different :

HTTP/1.1 200 Ok( Do not use breakpoint continuation ) 
HTTP/1.1 206 Partial Content( Use breakpoint continuation )

copyright notice
author[Ride Hago to travel],Please bring the original link to reprint, thank you.
https://en.pythonmana.com/2022/206/202207250919016090.html

Random recommended