JW Player 中 S3 托管的 HLS 视频的 CORS 配置
CORS configuration for S3-hosted HLS video in JW Player
我在投射自托管 JW Player 视频时遇到问题。这里是 Javascript API 中用于配置播放器的相关参考。
https://developer.jwplayer.com/jw-player/docs/developer-guide/customization/configuration-reference/#casting
以下是有关我的设置的一些详细信息:
1)视频为HLS流格式。因此,我传递给 JW Player Javascript API 的文件具有 .m3u8 扩展名。
2) 视频托管在 S3 上。
3) 视频通过 CloudFront 提供。
这是我用来在 JW Player 中加载视频的代码:
<div id="jwplayer"></div>
var playerInstance = jwplayer('jwplayer');
playerInstance.setup({
file: <cloudfront-path-to-m3u8-file>,
androidhls: true,
cast: {},
});
当我使用 JW Player Javascript 库的 7.12.13 版时,这是我观察到的:
1) 视频在浏览器中加载正常。
2) 当我尝试投射时,我在浏览器的视频中看到一个旋转器,表明它即将通过 Chromecast.
开始播放
3) Chromecast 看起来要开始在电视上播放视频了。我看到带有微调器的 Chromecast 符号,然后是视频时间轴栏。
4) 在几秒内,我看到了 Chromecast 主屏幕。视频从不在电视上播放。
5) 此时,视频开始在浏览器中播放。
6) 我在浏览器调试控制台看到如下错误信息:
provider.cast.js:1 Error: {code: "session_error", description:
"LOAD_FAILED", details: {…}}code: "session_error"description:
"LOAD_FAILED"details: {type: "LOAD_FAILED"}__proto__: Object
d.error @ provider.cast.js:1
(anonymous) @ cast_sender.js:70
U.onMessage @ cast_sender.js:76
M.i @ cast_sender.js:56
当我使用 JW Player Javascript 库的 8.6.3 版时,这是我观察到的:
1) 视频在浏览器中加载正常。
2) 当我尝试投射时,我在浏览器的视频中看到一个旋转器,表明它即将通过 Chromecast.
开始播放
3) Chromecast 看起来要开始在电视上播放视频了。我看到带有微调器的 Chromecast 符号,然后是视频时间轴栏。
4) 几秒钟后,我只在电视上看到 Chromecast 符号。
5) 浏览器视频播放器中的旋转器无限旋转。
6) 我在浏览器调试控制台看到如下错误信息:
provider.cast.js:10 Uncaught TypeError: Cannot read property 'trigger' of undefined
at c.<anonymous> (provider.cast.js:10)
at s (application-0a118d5fa8c4bb8de5f5da2cc04ef8c3a0cc5bf84da710890d3a90e9c79a04ee.js:3)
at c.a [as trigger] (application-0a118d5fa8c4bb8de5f5da2cc04ef8c3a0cc5bf84da710890d3a90e9c79a04ee.js:3)
at t.error (provider.cast.js:10)
at cast_sender.js:70
at U.onMessage (cast_sender.js:76)
at M.i (cast_sender.js:56)
(anonymous) @ provider.cast.js:10
s @ application-0a118d5fa8c4bb8de5f5da2cc04ef8c3a0cc5bf84da710890d3a90e9c79a04ee.js:3
a @ application-0a118d5fa8c4bb8de5f5da2cc04ef8c3a0cc5bf84da710890d3a90e9c79a04ee.js:3
t.error @ provider.cast.js:10
(anonymous) @ cast_sender.js:70
U.onMessage @ cast_sender.js:76
M.i @ cast_sender.js:56
关于这些错误的含义或如何调试此问题的任何想法?
请注意,我 运行 在 Ubuntu 14.04 上 Chrome(版本 71.0.3578.98 64 位)中进行了上述测试。我也尝试从 Android 设备投射这些页面,但得到了相同的结果。
我试过的一些东西:
- 已在 S3 存储桶中配置 CORS 以允许从这些域进行访问。
- 已将 crossdomain.xml 添加到 S3 存储桶以允许从这些域进行访问。
- 使 CloudFront 边缘中的缓存对象失效。
- 正在清除浏览器缓存。
为了找出问题所在,我还尝试了以下方法:
- 用webm文件替换m3u8文件。我可以使用此设置成功投射。
- 用mp4文件替换m3u8文件。我可以使用此设置成功投射。
- 用直接 S3 路径替换 CloudFront 路径。我观察到与上面描述的相同的问题行为(即无法投射并在控制台中看到错误)。
我发现更改 S3 存储桶的 CORS 配置以允许从所有来源访问可以解决问题:
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<ExposeHeader>ETag</ExposeHeader>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
然而,这肯定不是理想的,因为它打开了从任何域访问的存储桶。我试图通过为我用来为视频播放器提供服务的域明确指定 CORSRule
块来限制访问。我还尝试添加 http://*.jwpcdn.com
和 https://*.jwpcdn.com
作为允许的来源,因为我相信这是托管 JWPlayer 的 Chromecast 接收器的地方。
https://support.jwplayer.com/articles/cross-domain-file-loading-reference
None 这些组合有效。让 JW Player 成功投射 HLS 视频的唯一方法是允许从 all 来源访问。
知道如何配置 CORS 以在不牺牲存储桶隐私的情况下获得所需的行为。
谢谢!
原来我还需要允许从 https://*.gstatic.com 访问。这是除了 http://*.jwpcdn.com 和托管视频播放器的域之外的内容。我现在可以从 JW Player 版本 7 和 8 成功投射 HLS 视频!
进行这些更改后,我的 S3 存储桶的 CORS 配置如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>http://my-domain-with-video-player.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>http://*.jwpcdn.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>https://*.gstatic.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
我在投射自托管 JW Player 视频时遇到问题。这里是 Javascript API 中用于配置播放器的相关参考。
https://developer.jwplayer.com/jw-player/docs/developer-guide/customization/configuration-reference/#casting
以下是有关我的设置的一些详细信息:
1)视频为HLS流格式。因此,我传递给 JW Player Javascript API 的文件具有 .m3u8 扩展名。
2) 视频托管在 S3 上。
3) 视频通过 CloudFront 提供。
这是我用来在 JW Player 中加载视频的代码:
<div id="jwplayer"></div>
var playerInstance = jwplayer('jwplayer');
playerInstance.setup({
file: <cloudfront-path-to-m3u8-file>,
androidhls: true,
cast: {},
});
当我使用 JW Player Javascript 库的 7.12.13 版时,这是我观察到的:
1) 视频在浏览器中加载正常。
2) 当我尝试投射时,我在浏览器的视频中看到一个旋转器,表明它即将通过 Chromecast.
开始播放
3) Chromecast 看起来要开始在电视上播放视频了。我看到带有微调器的 Chromecast 符号,然后是视频时间轴栏。
4) 在几秒内,我看到了 Chromecast 主屏幕。视频从不在电视上播放。
5) 此时,视频开始在浏览器中播放。
6) 我在浏览器调试控制台看到如下错误信息:
provider.cast.js:1 Error: {code: "session_error", description:
"LOAD_FAILED", details: {…}}code: "session_error"description:
"LOAD_FAILED"details: {type: "LOAD_FAILED"}__proto__: Object
d.error @ provider.cast.js:1
(anonymous) @ cast_sender.js:70
U.onMessage @ cast_sender.js:76
M.i @ cast_sender.js:56
当我使用 JW Player Javascript 库的 8.6.3 版时,这是我观察到的:
1) 视频在浏览器中加载正常。
2) 当我尝试投射时,我在浏览器的视频中看到一个旋转器,表明它即将通过 Chromecast.
开始播放
3) Chromecast 看起来要开始在电视上播放视频了。我看到带有微调器的 Chromecast 符号,然后是视频时间轴栏。
4) 几秒钟后,我只在电视上看到 Chromecast 符号。
5) 浏览器视频播放器中的旋转器无限旋转。
6) 我在浏览器调试控制台看到如下错误信息:
provider.cast.js:10 Uncaught TypeError: Cannot read property 'trigger' of undefined
at c.<anonymous> (provider.cast.js:10)
at s (application-0a118d5fa8c4bb8de5f5da2cc04ef8c3a0cc5bf84da710890d3a90e9c79a04ee.js:3)
at c.a [as trigger] (application-0a118d5fa8c4bb8de5f5da2cc04ef8c3a0cc5bf84da710890d3a90e9c79a04ee.js:3)
at t.error (provider.cast.js:10)
at cast_sender.js:70
at U.onMessage (cast_sender.js:76)
at M.i (cast_sender.js:56)
(anonymous) @ provider.cast.js:10
s @ application-0a118d5fa8c4bb8de5f5da2cc04ef8c3a0cc5bf84da710890d3a90e9c79a04ee.js:3
a @ application-0a118d5fa8c4bb8de5f5da2cc04ef8c3a0cc5bf84da710890d3a90e9c79a04ee.js:3
t.error @ provider.cast.js:10
(anonymous) @ cast_sender.js:70
U.onMessage @ cast_sender.js:76
M.i @ cast_sender.js:56
关于这些错误的含义或如何调试此问题的任何想法?
请注意,我 运行 在 Ubuntu 14.04 上 Chrome(版本 71.0.3578.98 64 位)中进行了上述测试。我也尝试从 Android 设备投射这些页面,但得到了相同的结果。
我试过的一些东西:
- 已在 S3 存储桶中配置 CORS 以允许从这些域进行访问。
- 已将 crossdomain.xml 添加到 S3 存储桶以允许从这些域进行访问。
- 使 CloudFront 边缘中的缓存对象失效。
- 正在清除浏览器缓存。
为了找出问题所在,我还尝试了以下方法:
- 用webm文件替换m3u8文件。我可以使用此设置成功投射。
- 用mp4文件替换m3u8文件。我可以使用此设置成功投射。
- 用直接 S3 路径替换 CloudFront 路径。我观察到与上面描述的相同的问题行为(即无法投射并在控制台中看到错误)。
我发现更改 S3 存储桶的 CORS 配置以允许从所有来源访问可以解决问题:
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<ExposeHeader>ETag</ExposeHeader>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
然而,这肯定不是理想的,因为它打开了从任何域访问的存储桶。我试图通过为我用来为视频播放器提供服务的域明确指定 CORSRule
块来限制访问。我还尝试添加 http://*.jwpcdn.com
和 https://*.jwpcdn.com
作为允许的来源,因为我相信这是托管 JWPlayer 的 Chromecast 接收器的地方。
https://support.jwplayer.com/articles/cross-domain-file-loading-reference
None 这些组合有效。让 JW Player 成功投射 HLS 视频的唯一方法是允许从 all 来源访问。
知道如何配置 CORS 以在不牺牲存储桶隐私的情况下获得所需的行为。
谢谢!
原来我还需要允许从 https://*.gstatic.com 访问。这是除了 http://*.jwpcdn.com 和托管视频播放器的域之外的内容。我现在可以从 JW Player 版本 7 和 8 成功投射 HLS 视频!
进行这些更改后,我的 S3 存储桶的 CORS 配置如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>http://my-domain-with-video-player.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>http://*.jwpcdn.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>https://*.gstatic.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>