浏览器取消 HLS Stream 而 VLC 接受它
Browser cancels HLS Stream while VLC accepts it
我通过将 MPEG-TS 流内容写入 GridFS 文件系统来录制 HSL 流。
我现在正在尝试使用 aiohttp
s 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*
标志的新数据部分的请求,服务器应正确响应。一开始客户端请求播放列表,服务器应该回答正确的数据。
通信协议够复杂,抱歉。
我不能只修改您的代码段中的几行以使其正常工作。
我通过将 MPEG-TS 流内容写入 GridFS 文件系统来录制 HSL 流。
我现在正在尝试使用 aiohttp
s 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*
标志的新数据部分的请求,服务器应正确响应。一开始客户端请求播放列表,服务器应该回答正确的数据。
通信协议够复杂,抱歉。 我不能只修改您的代码段中的几行以使其正常工作。