简体   繁体   English

HTML5 视频:Android 无法通过 CloudFront 播放 MP4

[英]HTML5 Video: Android not playing MP4 Through CloudFront

We are in the process of implementing mobile video functionality on our site, and have been having difficulties getting video (living on S3) to play on the Android through CloudFront.我们正在我们的网站上实现移动视频功能,并且一直难以通过 CloudFront 在 Android 上播放视频(生活在 S3 上)。

We're using generic 'Video For Everybody'-style markup for the player, using 3 video encodings (mp4/webm/ogv programatically encoded using Zencoder) with a Flash fallback.我们为播放器使用通用的“Video For Everyone”风格标记,使用 3 种视频编码(使用 Zencoder 以编程方式编码的 mp4/webm/ogv)和 Flash 后备。 This seems to work for iPhones, but not for the Android.这似乎适用于 iPhone,但不适用于 Android。

From our testing using a flat HTML file, it appears that the Android will not display a 'play' button unless there are no query string parameters on the mp4 (like those on the CloudFront URLs below).根据我们使用平面 HTML 文件进行的测试,Android 似乎不会显示“播放”按钮,除非 mp4 上没有查询字符串参数(如下面的 CloudFront URL 上的参数)。 If these querystring variables are removed, the 'play' button will appear.如果这些查询字符串变量被删除,“播放”按钮将出现。 The video will not play if clicked however, of course.当然,如果单击该视频将不会播放。

We are thinking encoding settings are not the culprit as mp4s we have encoded will play in the Android in an HTML test page, inside a video tag with a source pointed at the mp4 file locally.我们认为编码设置不是罪魁祸首,因为我们编码的 mp4 将在 HTML 测试页面的 Android 中播放,在视频标签内,源指向本地 mp4 文件。

Here is some sample markup (parameter values Xed out).这是一些示例标记(已删除的参数值)。 Thanks very much in advance for any insight or suggestions you can provide.非常感谢您提供的任何见解或建议。


<video id="videoTag" class="video-js" width="640" height="480" controls poster='/images/poster.gif'>
<source src="https://di8df8d1ooc3o.cloudfront.net/43391_1309888197/video.mp4?Expires=XXXXXXXXXX&Policy=XXXXXXXXXX&Signature=XXXXXXXXXX&Key-Pair-Id=XXXXXXXXXX" />
<source src="https://di8df8d1ooc3o.cloudfront.net/43391_1309888197/video.webm?Expires=1XXXXXXXXXX&Policy=XXXXXXXXXX&Signature=XXXXXXXXXX&Key-Pair-Id=XXXXXXXXXX" />
<source src="https://di8df8d1ooc3o.cloudfront.net/43391_1309888197/video.ogv?Expires=XXXXXXXXXX&Policy=XXXXXXXXXX&Signature=XXXXXXXXXX&Key-Pair-Id=XXXXXXXXXX" />
<object id='flash_fallback_1' class='vjs-flash-fallback' width='640' height='480' type='application/x-shockwave-flash' data='http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf'>
<param name='movie' value='http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf' />
<param name='allowfullscreen' value='true' />
<param name='flashvars' value='config={"playlist":["%2fimages%2fspacer.gif", {"url": "https%3a%2f%2fdi8df8d1ooc3o.cloudfront.net%2f43391_1309888197%2fvideo.mp4%3fExpires%3d1309892359%26Policy%3deyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9kaThkZjhkMW9vYzNvLmNsb3VkZnJvbnQubmV0LzQzMzkxXzEzMDk4ODgxOTcvZWNoby1oZXJld2VhcmUubXA0IiwiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6eyJBV1M6RXBvY2hUaW1lIjoxMzA5ODkyMzU5fX19XX0_%26Signature%3dcp-wUUSN3EqQ0A%7ewaa5VitBeoMf0wjf5kELID9w8pP8kLp6dkZ3%7ea7H9Sp6uqBrNOkMDr4dMuvwnICBozH0eLLcc4LA7fd2jX5hMru1ORVjc8B%7ey1zNaj1ZlLeuCy6YV5zfBAzd9jVh6DGKVadp-S%7eLHXQiVin3N4GXwBnxZ-No_%26Key-Pair-Id%3dAPKAIAAZWMFF53NY4OMA","autoPlay":false,"autoBuffering":true}]}' />
<img src='/images/poster.gif' alt='Poster Image' title='No video playback capabilities.' />

can you try this:你能试试这个:

<video id="video" autobuffer height="240" poster="bbb_poster-360x240.jpg" width="360">
        <source src="BigBuck.m4v">
        <source src="BigBuckBunny.mp4" type="video/mp4">
        <source src="BigBuck.webm" type="video/webm">
        <source src="BigBuck.theora.ogv" type="video/ogv">
        <source src="BigBuckBunny.ogg" type="video/ogg">
</video>

Android Chrome (4.2) won't play an MP4 located on a server requiring authentication or in a password protected folder. Android Chrome (4.2) 无法播放位于需要身份验证的服务器或受密码保护的文件夹中的 MP4。 MP4 will play from an HTTPS server if it does not require authentication.如果不需要身份验证,MP4 将从 HTTPS 服务器播放。

Furthermore, you can serve up an HTML page that is protected (requiring log in) and if it has a video tag that points to another folder that does not require a password, the MP4 will play.此外,您可以提供受保护(需要登录)的 HTML 页面,如果它有指向另一个不需要密码的文件夹的视频标签,则 MP4 将播放。

I have not been able to find a solution except to tell people to use Firefox for Android - it will play the WebM video even from a protected location.除了告诉人们将 Firefox 用于 Android 之外,我找不到解决方案 - 它甚至可以从受保护的位置播放 WebM 视频。

Not sure if this is the problem, but your HTML syntax is incorrect.不确定这是否是问题所在,但您的 HTML 语法不正确。 You need to HTML encode the ampersands when within attribute quotes.您需要在属性引号内时对 HTML 进行编码。 Try this:尝试这个:

<video id="videoTag" class="video-js" width="640" height="480" controls poster='/images/poster.gif'>
<source src="https://di8df8d1ooc3o.cloudfront.net/43391_1309888197/video.mp4?Expires=XXXXXXXXXX&amp;Policy=XXXXXXXXXX&amp;Signature=XXXXXXXXXX&amp;Key-Pair-Id=XXXXXXXXXX" />
<source src="https://di8df8d1ooc3o.cloudfront.net/43391_1309888197/video.webm?Expires=1XXXXXXXXXX&amp;Policy=XXXXXXXXXX&amp;Signature=XXXXXXXXXX&amp;Key-Pair-Id=XXXXXXXXXX" />
<source src="https://di8df8d1ooc3o.cloudfront.net/43391_1309888197/video.ogv?Expires=XXXXXXXXXX&amp;Policy=XXXXXXXXXX&amp;Signature=XXXXXXXXXX&amp;Key-Pair-Id=XXXXXXXXXX" />
<object id='flash_fallback_1' class='vjs-flash-fallback' width='640' height='480' type='application/x-shockwave-flash' data='http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf'>
<param name='movie' value='http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf' />
<param name='allowfullscreen' value='true' />
<param name='flashvars' value='config={"playlist":["%2fimages%2fspacer.gif", {"url": "https%3a%2f%2fdi8df8d1ooc3o.cloudfront.net%2f43391_1309888197%2fvideo.mp4%3fExpires%3d1309892359%26Policy%3deyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9kaThkZjhkMW9vYzNvLmNsb3VkZnJvbnQubmV0LzQzMzkxXzEzMDk4ODgxOTcvZWNoby1oZXJld2VhcmUubXA0IiwiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6eyJBV1M6RXBvY2hUaW1lIjoxMzA5ODkyMzU5fX19XX0_%26Signature%3dcp-wUUSN3EqQ0A%7ewaa5VitBeoMf0wjf5kELID9w8pP8kLp6dkZ3%7ea7H9Sp6uqBrNOkMDr4dMuvwnICBozH0eLLcc4LA7fd2jX5hMru1ORVjc8B%7ey1zNaj1ZlLeuCy6YV5zfBAzd9jVh6DGKVadp-S%7eLHXQiVin3N4GXwBnxZ-No_%26Key-Pair-Id%3dAPKAIAAZWMFF53NY4OMA","autoPlay":false,"autoBuffering":true}]}' />
<img src='/images/poster.gif' alt='Poster Image' title='No video playback capabilities.' />

Update:更新:

The answer from @ania points to this link from DiveIntoHTML5 , which indeed confirms my guess that Android is trying to determine the right source element from the file extension of the URL. @ania 的答案指向DiveIntoHTML5的这个链接,这确实证实了我的猜测,即 Android 正试图从 URL 的文件扩展名中确定正确的元素。 The article does mention that there was a bug where the extension will be used instead of the type attribute, but it was fixed in Android 2.3.文章确实提到了使用扩展名而不是类型属性的错误,但它已在 Android 2.3 中修复。 However, your HTML does not include the type attribute, so I guess even Android 2.3 will fall back to the extension hack, in which case it likely hits the query params bug I suspect below.但是,您的 HTML 不包含type属性,所以我想即使是 Android 2.3 也会退回到扩展黑客,在这种情况下,它可能会遇到我在下面怀疑的查询参数错误。

You can quickly test this by adding the type attribute to the.mp4 source element and verifying if it now works on Android 2.3.您可以通过将type属性添加到 .mp4元素并验证它现在是否适用于 Android 2.3 来快速测试这一点。 However, even if it does, it still does not solve your issue on Android 2.2 and lower.但是,即使这样,它仍然不能解决您在 Android 2.2 及更低版本上的问题。 For that you might still try the approach below.为此,您仍然可以尝试以下方法。


I wouldn't be surprised if Android code looks at the file extension in the URL to determine which source element to use.如果 Android 代码查看 URL 中的文件扩展名以确定要使用的元素,我不会感到惊讶。 If the code that does this does not strip the query parameters (as it should) before it searches for the file extension, it'll get confused as it won't find any extension it recognizes.如果执行此操作的代码在搜索文件扩展名之前没有去除查询参数(应该如此),它会感到困惑,因为它不会找到它识别的任何扩展名。 This would explain the symptoms you are observing (the absence of the Play button).这可以解释您观察到的症状(没有播放按钮)。

One way to verify this would be to change this line:验证这一点的一种方法是更改此行:

<source src="https://di8df8d1ooc3o.cloudfront.net/43391_1309888197/video.mp4?Expires=XXXXXXXXXX&Policy=XXXXXXXXXX&Signature=XXXXXXXXXX&Key-Pair-Id=XXXXXXXXXX" />

to

<source src="https://di8df8d1ooc3o.cloudfront.net/43391_1309888197/video.mp4?Expires=XXXXXXXXXX&Policy=XXXXXXXXXX&Signature=XXXXXXXXXX&Key-Pair-Id=XXXXXXXXXX&__bogusparam=.mp4" />

If I have guessed it properly, this should cause the Android code to show the Play button properly.如果我猜对了,这应该会导致 Android 代码正确显示播放按钮。 Of course, I don't know if the presence of this bogus parameter would confuse CloudFront, so the video still might not play.当然,我不知道这个虚假参数的存在是否会混淆 CloudFront,因此视频仍然可能无法播放。 However, there's a chance CloudFront would just ignore that query parameter.但是,CloudFront 有可能会忽略该查询参数。

Look at this page: http://diveintohtml5.ep.io/video.html#android看这个页面: http://diveintohtml5.ep.io/video.html#android
And here: http://www.broken-links.com/2010/07/30/encoding-video-for-android/在这里: http://www.broken-links.com/2010/07/30/encoding-video-for-android/
Hope it will help!!希望它会有所帮助!

Update: Check on android developer site with video formats supported by android.更新:在 android 开发者网站上查看 android 支持的视频格式。 You are trying to show *.mp4 video but it is not enough.您正在尝试显示 *.mp4 视频,但这还不够。 Try to convert your video to lower quality(as shown on the website on the bottom).尝试将您的视频转换为较低质量(如底部网站所示)。 It depends on device - sometimes resolution or frame rate is too high and still - video which has good format cannot be shown.这取决于设备 - 有时分辨率或帧速率太高而且静止 - 无法显示具有良好格式的视频。

Those links provided by ania above (or below - wherever this post ends up,) will help.上面(或下面——无论这篇文章在哪里结束)由 ania 提供的那些链接都会有所帮助。 especially the last one.尤其是最后一个。

Android support MP4 playback but you must remove the type attribute and I think put the MP4 source first. Android 支持 MP4 播放,但您必须删除类型属性,我认为将 MP4 源放在首位。 Play also needs to be implemented via JavaScript.播放也需要通过 JavaScript 实现。 Android will not display the first still of the video either, just a video icon, but it does support the poster attribute. Android 也不会显示视频的第一个静止图像,只是一个视频图标,但它确实支持海报属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM