0

我通过将 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 中播放时有效。即使使用“网络源”在 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

视频信息 VLC

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

直接视频流 HTTP 响应

M3U 播放列表 HTTP 响应

M3U 播放列表 HTTP 响应

4

1 回答 1

1

我个人没有使用 HLS 的经验,但即使是对RFC 草案的广泛概述也显示您违反了协议。

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

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

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

于 2016-07-17T16:11:19.787 回答