Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make accommodations necessary for iOS 10 HLS #2597

Merged
merged 6 commits into from
May 12, 2017

Conversation

machenmusik
Copy link
Contributor

Provides core support needed for iOS 10 HLS playback discussed in #1416.

Note that this leaves video flipped in Y dimension and also with B and R color channels reversed.
It is expected that corrections can be applied using custom shaders.
(Accommodating those corrections using the built-in shaders is outside the scope of this PR.)

@machenmusik
Copy link
Contributor Author

(Due to the current Mobile Safari CORS issue, this is a bit of a PITA to diagnose / address / test as the A-Frame page and the HLS content must have the same domain.)

@dmarcos
Copy link
Member

dmarcos commented Apr 19, 2017

So with PR the video at least plays but flipped and with wrong color? :)

@dmarcos
Copy link
Member

dmarcos commented Apr 19, 2017

Is that better than the video not playing at all?

@machenmusik
Copy link
Contributor Author

machenmusik commented Apr 19, 2017

Is that better than the video not playing at all?

Without this change, there is no way to make it work at all.
With this change, it is actually simple to use custom shader to fix flip and channel order.

So yes, this change is much better than the video not playing at all... see discussion in #1416

@dmarcos
Copy link
Member

dmarcos commented Apr 19, 2017

Can we add add a custom shader that it's set automatically when playing on iOS?

@machenmusik
Copy link
Contributor Author

ok, the switching could probably use a little better guard (e.g. auto-switch if it's a shader like standard or flat we know won't work) if you wanted to touch up the PR

if (utils.device.isIOS() && isHLS(videoEl)) {
// really it's BGRA, so this needs correction in shader
texture.format = THREE.RGBAFormat;
texture.needsCorrectionBGRA = true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add this to the this instead of the texture?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so - this is the system, not a given video texture, right? Complicating things is the fact that iOS 10 MP4 playback does not need any of these workarounds, so needs to be done on a per-video-texture basis.

texture.needsCorrectionBGRA = true;
// apparently this is needed for HLS, so this needs correction in shader
texture.flipY = false;
texture.needsCorrectionFlipY = true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add this to the this instead of the texture?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(see above)

@machenmusik
Copy link
Contributor Author

due to CORS issues with Mobile Safari, in order to test this, your HTML page must be in the same exact domain as the IDevice-compatible video content (m3u8 manifests and ts / aac files), Subdomains will not work at present.

@cvan
Copy link
Contributor

cvan commented May 3, 2017

due to CORS issues with Mobile Safari, in order to test this, your HTML page must be in the same exact domain as the IDevice-compatible video content (m3u8 manifests and ts / aac files), Subdomains will not work at present.

can you point me to a sample video you're using as a test case?

@@ -195,6 +205,12 @@ module.exports.System = registerSystem('material', {
}
});

function isHLS (videoEl) {
if (videoEl.type === 'application/x-mpegurl') return true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do MIME types get lowercased automatically when calling the type getter?

I notice in Apple's docs, it appears as application/x-mpegURL.

  • also, do you want to check vnd.apple.mpegURL as well?
  • and what about video/MP2T (.ts)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i've only seen lowercase, but good question.

not sure on your other two points

@@ -195,6 +205,12 @@ module.exports.System = registerSystem('material', {
}
});

function isHLS (videoEl) {
if (videoEl.type === 'application/x-mpegurl') return true;
if (videoEl.src && videoEl.src.indexOf('.m3u8') > 0) return true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would check videoEl.src.toLowerCase()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we check for toLowerCase and add braces to the return?

if (videoEl.src && videoEl.src.toLowerCase().indexOf('.m3u8') > 0) { return true; }

var registerShader = require('../core/shader').registerShader;

/**
* Custom shader for iOS 10 HLS.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add a comment with a URL to a doc/spec for this API?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry which API?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some Apple docs (or Google's Web Fundamentals docs) about what HLS is

@cvan
Copy link
Contributor

cvan commented May 3, 2017

@machenmusik nice work on supporting this 👍 if you can point me to some test case URLs, I'll try this out on my end.

@machenmusik
Copy link
Contributor Author

i think i used hls urls from the prior threejs tickets on the topic

maybe should just convert the aframe 360 video from MP4 to iPhone-safe HLS?

@cvan
Copy link
Contributor

cvan commented May 9, 2017

maybe should just convert the aframe 360 video from MP4 to iPhone-safe HLS?

how about including both as <source>s?

@machenmusik
Copy link
Contributor Author

if including both as <source> works, that's fine although it complicates the example since you can't do with inline src in a-videosphere for example -- I was just trying to say that if we want HLS source, should probably make a version of the recently-iDevice-friendly MP4 example that is HLS format

@cvan
Copy link
Contributor

cvan commented May 10, 2017

awesome, thanks for making the updates 👍 btw, is there a simple test or two you can add?

@wjhtinger
Copy link

How about play the live 360 stream from webrtc?

@cvan
Copy link
Contributor

cvan commented May 10, 2017

See my comment in issue #2663. If @machenmusik has other insights, would be glad to know and discuss. Thanks, everyone 👍

@dmarcos
Copy link
Member

dmarcos commented May 12, 2017

@machenmusik I want to merge this but I would like to see it working first. Do you have any example I can try?

@machenmusik
Copy link
Contributor Author

so per discussion with @dmarcos, it seems that recent changes may have broken this somehow.., may need to do a little more investigation before merging this one :-/

@machenmusik
Copy link
Contributor Author

found the problem :-)

@dmarcos
Copy link
Member

dmarcos commented May 12, 2017

Thanks!

@dmarcos dmarcos merged commit bb2fa5a into aframevr:master May 12, 2017
@@ -206,8 +206,8 @@ module.exports.System = registerSystem('material', {
});

function isHLS (videoEl) {
if (videoEl.type === 'application/x-mpegurl') return true;
if (videoEl.src && videoEl.src.indexOf('.m3u8') > 0) return true;
if (videoEl.type.toLowerCase() === 'application/x-mpegurl') { return true; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

per my earlier comment re: Apple's docs, I'd also check for vnd.apple.mpegurl and video/mp2t

if (videoEl.type === 'application/x-mpegurl') return true;
if (videoEl.src && videoEl.src.indexOf('.m3u8') > 0) return true;
if (videoEl.type.toLowerCase() === 'application/x-mpegurl') { return true; }
if (videoEl.src && videoEl.src.toLowerCase().indexOf('.m3u8') > 0) { return true; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

per my earlier comment re: Apple's docs, I'd also check for .ts

@@ -1,7 +1,8 @@
var registerShader = require('../core/shader').registerShader;

/**
* Custom shader for iOS 10 HLS.
* Custom shader for iOS 10 HTTP Live Streaming (HLS).
* For more information on HLS, see https://datatracker.ietf.org/doc/draft-pantos-http-live-streaming/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -127,3 +131,9 @@ function handleTextureEvents (el, texture) {
});
}
module.exports.handleTextureEvents = handleTextureEvents;

module.exports.isHLS = function (videoEl) {
if (videoEl.type && videoEl.type.toLowerCase() in ['application/x-mpegurl', 'application/vnd.apple.mpegurl']) { return true; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

arrays don't work like this. you've got to use includes or indexOf (which has better compatibility across the board). test for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting, as it does work?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe it only works based on src. i do owe some tests (as subsequent PR) so will fix there as needed

Copy link
Contributor

@cvan cvan May 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it doesn't work for me in Chrome nor Safari on iOS - you sure?

screenshot of Chrome

here's a test case I tested on iOS.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think the test page i was using was matching on src (masking broken type check) - will fix when i add isHLS tests as mentioned above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see #2668

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome! thanks


module.exports.isHLS = function (videoEl) {
if (videoEl.type && videoEl.type.toLowerCase() in ['application/x-mpegurl', 'application/vnd.apple.mpegurl']) { return true; }
if (videoEl.src && videoEl.src.toLowerCase().indexOf('.m3u8') > 0) { return true; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about checking for .ts too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.ts is not HLS, it is not clear that either .ts playback works or that it needs the workaround (MP4 does not)

if you'd like to add .ts, and it needs this workaround, perhaps you'd like to do in separate PR as this one is merged now?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll test it some time to see - I just need to do some investigation there

@@ -144,6 +145,16 @@ module.exports.System = registerSystem('material', {
texture.minFilter = THREE.LinearFilter;
setTextureProperties(texture, data);

// if we're on iOS, and the video is HLS, we currently need to do some hacks
if (utils.device.isIOS() && isHLS(videoEl)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have you tested this on Edge (which supports WebVR in release channel)? Edge supports HLS too; it may or may not have the same bugs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it does not.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it does not have the bugs, or it does not have proper HLS support?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it does not appear to have the bugs.

@machenmusik machenmusik mentioned this pull request May 13, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants