New issue
Advanced search Search tips

Issue 670086 link

Starred by 2 users

Issue metadata

Status: WontFix
Owner: ----
Closed: Nov 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Android
Pri: 2
Type: Bug



Sign in to add a comment

E! Online has found a bug with video playback on Google Chrome due to CORS headers.

Reported by joshsmit...@gmail.com, Nov 30 2016

Issue description

Example URL:
http://www.eonline.com/videos/254752/kyra-sedgwick-and-matthew-broderick-dated

Steps to reproduce the problem:
1. Using an Android open the following link in Chrome:
2. http://www.eonline.com/videos/254752/kyra-sedgwick-and-matthew-broderick-dated
3. Try to play the video and although pre-roll may load, the actual video will not

What is the expected behavior?
The video should play (not just pre-roll)

What went wrong?
Currently our videos won’t play on Android devices using the Chrome browser.  It’s not clear when this issue began, but it was discovered in October 2016. We created an internal ticket and a ticket with Akamai (our CDN) to investigate and discovered that the issue is caused by having crossorigin="anonymous” or crossorigin= "use-credentials” on the video tag element for CORS. When we remove that cross origin line, the video plays fine. However, we need to use the cross origin option in order to access side-car files for captioning, so removing this is not an option due to the FCC mandate. 

Did this work before? No 

Is it a problem with Flash or HTML5? HTML5

Does this work in other browsers? Yes

Chrome version:   Channel: stable
OS Version: 
Flash Version:
 
What type of content is this? HLS?
Status: WontFix (was: Unconfirmed)
Unfortunately there's not much we can do then, HLS playback is provided directly by Android OS - this is out of Chrome's control I recommend switching to an HLS.js to MediaSource adapter with mp4 based segments if you must continue to use HLS.
I'm not completely clear on your response.

Here's the issue:

On mobile web we use the native video player, not a custom player, so the
M3U8 *should* be provided directly to the player.

   - When the CORS headers are present: Desktop, iOS devices and Android
   native browsers allow the video to play as expected.
   - When the CORS headers are present: Android devices in Chrome the M3U8
   does not play.
   - When we removed the CORS headers, videos on Android devices in Chrome
   play fine.
   - However, we cannot remove the CORS headers because we need to provide
   side-car files for closed captioning purposes.

I created a ticket with Akamai to confirm we had the CORS headers
configured properly and they have confirmed this. This is why I think this
is a Chrome bug.

Let me know if that makes sense.
Sorry, I wasn't clear; the detail is technical. Chrome does not implement HLS (m3u8) playback support; instead it delegates to the Android OS. Since the OS is handling the playback for Chrome, if it's failing in this case we can't do anything to resolve it. We'll need to file an Android bug instead of a Chrome bug.

To resolve this most expediently you'll likely need to switch to the same player you use on desktop instead of HLS. I.e serve a .mp4 instead of HLS.
Cc: tguilbert@chromium.org
+tguilbert in case I'm forgetting something.
The thing is, the video plays on Android native browsers and on Firefox.  I
just tested it.

If it's an Android issue, shouldn't it be universal?
Not necessarily for Android native browser, I don't believe it even has full (any?) CORS support.

If it was playing in Firefox that'd be telling, but Firefox mobile doesn't support HLS; so it's likely using the mp4 fallback.
HLS playback is supported on newer Androids (4.4 and above). That's what
we've been delivering. 4.4 and below receive the MP4.

HLS playback works on Chrome when we remove the CORS headers. Any insight
into why?
I defer to tguilbert@ on the technical specifics of how CORS affects MediaPlayer, but to your first point:

HLS playback may work on Android 4.4+, but it's not recommended for the best experience; it's only works in Chrome on Android for historical reasons and will not be supported on the desktop.

We instead recommend using Media Source Extensions with fragmented mp4 (h264) or webm (vp9) -- these are the technologies used by YouTube, Netflix, Facebook, Vimeo, etc. You can either use one of the existing DASH based solutions or your own ABR algorithm. If you must stick with HLS we recommend using mp4 based segments so that a simple HLS.js ABR algorithm will work with the least overhead.

We use Akamai for encoding and they create MP4 (h.264) renditions that are
used in the HLS stream, so I think we're good there, but I'll double check
with Akamai about the specifics of that tomorrow.

While I wasn't aware that using HLS on Android devices was not an ideal
method, besides this CORS header issue, we've never had any other playback
issues. And as I noted, without the headers, HLS plays fine on Android
devices (+4.4) in Chrome.
Following up on this.

I'm reaching out to Akamai to confirm our delivery configuration, but as
I've stated, we haven't seen any playback issues when the CORS headers
aren't present.

Any insight into why this would be the case?
So when CORS is active, does the remote server respond with the correct cross-origin headers? (Both for the media and for the subtitles.)


Yup, Akamai is our remote server and they've confirmed they are sending the
correct cross-origin headers.
Following up on this. Any update?

If it's easier, I can set-up a conference call. We need to escalate this
ticket as currently not getting any playback views from Android users on
the Chrome browser.
Even if it turns out to be a Chrome issue, we won't be able to affect a fix for at least ~2-3 weeks; so you should use one of the workarounds I suggested earlier. Probably the easiest is to switch to mp4 based playbacks for Android at present.

tguilbert@ is still digging in to see if there's anything we can do.
At this point, if we can confirm the exact issue. 2-3 weeks is fine.

We are currently using MP4 based playback in the HLS stream.  Do you mean
delivering MP4s directly to Android?
Yes, just set src=mp4 url (like you do on desktop). From the .m3u8 link in c#2, it looks like you're using MPEG2-TS segments, not MP4 segments; so if you do go with an HLS.js layer, it'll need to do transmuxing.

See this link for more details on mp4 segments, along with an example player. https://bitmovin.com/hls-news-wwdc-2016/
Thanks for the link. I'll follow up with Akamai on this.

Are you available for a call with them? In terms of how we're delivering
content, I want to make sure we're all on the same page.
After digging for some time, I have an update.

Playing HLS content works regardless of the crossOrigin attribute (the link in c#2 plays regardless of crossOrigin being specified or not).

The problem is that the final redirected URL seems to be different based off of the presence or not of the crossOrigin attribute:
m.eonline.com is using <video src="http://link.theplatform.com/..."/> (as opposed to a .m3u8 file directly). When there is no crossorigin attribute, the final redirected url is the proper .m3u8 file. When there is any crossOrigins attribute, the final redirected url returned by our resource loader is the same "link.theplatform.com/..." link.

I am not a network expert, but a quick search for "302 CORS redirect" comes up with a lot of questions such as this one (http://stackoverflow.com/questions/28917489/http-302-redirect-to-a-cors-request-is-dropped-by-browsers) which seems like the browser is behaving according to standards.

Now, as to why we can't play the actual HLS is a bit beyond the scope of this bug. The short version is that on older devices, the "link.theplatform.com" is given to the Android MediaPlayer directly, and the performance seems to be horrible, compared to the .m3u8 directly. On newer devices, not having the final redirected URL early enough prevents us from knowing that we are dealing with an HLS stream, and we can't send it to the Android MediaPlayer.

I am currently working on the new HLS playback path, which should be available in M57 if everything goes well. This in and of itself will not fix the issue, but it is the necessary first step to fix 663503, which should fix this issue (and if it doesn't, it will be because of Android MediaPlayer's performance, which I can't do much about).

In the mean time, as dalecurtis@ suggested, serving .mp4 is the preferred way of moving forward.
Thanks!

So just to be clear, the issue is that no actual media file is delivered
when we're using thePlatform link (due to the necessary redirect) when CORS
headers are present.

So even if we used thePlatform link to deliver MP4s instead of M3U8s, the
issue is still the actual thePlatform link itself not which type of media
it delivers.

There's also a separate issue where delivering an M3U8 to newer Androids
will time-out before the media is delivered to the Android MediaPlayer.
You're working on a fix for this in M57. However the general recommendation
is to avoid HLS (M3U8s) on Android devices and just deliver MP4s.

Do I understand this correctly? Am I missing something?
I think your assessment is mostly correct, but I will re-phrase it to be extra-clear :)

Older Android devices (edge cases):
100% of playback is done via Android MediaPlayer.
- Without CORS headers: url load redirects properly, MediaPlayer receives a .m3u8
- With CORS: url load doesn't fully redirect, MediaPlayer receives thePlatform link and performance suffers (from what I've seen, I'm not sure why)

Almost all Android devices (default case):
Only HLS playback is sent to the Android MediaPlayer.
- Without CORS headers: url redirects properly, unified media stack detects HLS and requests the Android MediaPlayer to start playing the .m3u8 instead.
- With CORS headers: url doesn't fully redirect, unified media stack starts demuxing thePlatform link and can't play thePlatform link.

Future:
With or without CORS header: Attempt demuxing on pre-redirect/post-redirect link to find proper media type. Route HLS to MediaPlayer; route everything else to unified media stack.


If you serve a .mp4 instead of an .m3u8 after redirection, there is a chance that the newer unified media stack (as opposed to the older MediaPlayer based one) will be able to handle the playback with CORS headers, but I have not verified it.

If you were to directly use the final .mp4 or the .m3u8 in your src= attribute (as opposed to the thePlatform link) everything should work, but I understand this might not be what you want.
Thanks for the summary!

I ran a few test with thePlatform and had them serve an MP4 after the
redirect instead of an M3U8 and thankfully that worked with the CORS
headers!

As was noted earlier, HLS is not recommended on Android devices, so my
proposed solution is to set the redirect to serve MP4s for all Android
(regardless of browser) request. I know it would be better to serve the MP4
directly, but our workflow is built on thePlatform link.

Let me know if this is a sustainable solution from your perspective.

Also, one of the aspects I liked about using the M3U8 is the adaptive
bitrate, should I expect some slowdown/performance issues when using the
MP4?

Sign in to add a comment