浏览器取消 HLS Stream 而 VLC 接受它

Browser cancels HLS Stream while VLC accepts it

我通过将 MPEG-TS 流内容写入 GridFS 文件系统来录制 HSL 流。

我现在正在尝试使用 aiohttps SessionResponse 将此内容提供回浏览器,但由于各种原因失败了。

    async def get_video(request):
            stream_response = StreamResponse()
            stream_response.headers['Content-Type'] = 'video/mp2t'
            stream_response.headers['Cache-Control'] = 'no-cache'
            stream_response.headers['Connection'] = 'keep-alive'
            await stream_response.prepare(request)

            fd = GridFS()
            video_stream = await fd(video_id)

            while True:
                try:
                    chunk = await video_stream.readchunk()
                    if not chunk:
                        break
                    stream_response.write(chunk)
                except CancelledError as e:
                    # fails here in safari or with diff content-type also in chrome
                    break

            await stream_response.write_eof()
            return stream_response

当尝试使用 safari 访问 url 时,我显示了播放器 ui,但是在服务器抛出 CancelledError 异常试图写入已经关闭的 SessionResponse

在 Chrome 中打开 URL 会导致下载视频文件。此文件 在 VLC 中播放时有效。即使使用 "Network Source" 在 VLC 中播放 URL 也能奏效。

我也试过在这个直接 url 前面提供静态 m3u 播放列表,但没有成功(VLC 也可以使用直接流的播放列表):

    #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="medium",NAME="Medium",AUTOSELECT=YES,DEFAULT=YES
    #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=992000,RESOLUTION=852x480,CODECS="avc1.66.31,mp4a.40.2",VIDEO="medium"
    http://localhost:8080/videos/{video_id}

我不确定如何进一步调试它,希望得到任何帮助(如果我不清楚,请在评论中提问)。当直接访问文件时,这些文件不会在浏览器中播放,我错过了什么?将我的资源 url 嵌入到 html 视频标签也无济于事(显然,因为浏览器在直接访问视频时会做同样的事情)

有关视频内容和我发送的原始 http 响应的更多信息:

视频信息 VLC

直接视频流 HTTP 响应(开始)

M3U 播放列表 HTTP 响应

我个人没有使用 HLS 的经验,但即使是 RFC draft 的大量概述也表明您违反了协议。

这不是关于在单个无休止的响应中一起发送视频块,而是关于通过保持活动使用使用相同的套接字连接发送多个 http 响应。

客户端发送对提供协议特定 EXT* 标志的新数据部分的请求,服务器应正确响应。一开始客户端请求播放列表,服务器应该回答正确的数据。

通信协议够复杂,抱歉。 我不能只修改您的代码段中的几行以使其正常工作。