gliese1337 / HLS.js

Pure Javascript HTTP Live Streaming Client
Mozilla Public License 2.0
53 stars 11 forks source link

Unable to play in Firefox #1

Open peterbe opened 9 years ago

peterbe commented 9 years ago

Here's a m3u8 URL that has CORS headers on it and uses mp4 chunks https://mozillalive-a.akamaihd.net/Akamai_Public/ngrp:MTV-Commons_all/playlist.m3u8

I put this into the index.html template but when I try to load it I get

uncaught exception 2

...after waiting about 5-10 seconds.

screenshot 2015-06-18 14 49 07

That feed won't be available forever but it will now for a couple of days I hope.

gliese1337 commented 9 years ago

Looks like that's a link to a Master Playlist, rather than a Media Playlist. Sadly, we do not handle Master Playlists yet. :(

If you open it up in a text editor, you can pull out the URLs for the individual Media Playlists, like https://mozillalive-a.akamaihd.net/Akamai_Public/ngrp:MTV-Commons_all/chunklist_w1074266747_b2121728.m3u8 . That should work. Or maybe not! It might produce new and interesting errors of its own. I'll have to try it out and see....

Eventually I should implement support for Master Playlists, but it was not immediately necessary for our original use case, and I haven't had the time to get around to it yet. In the meantime, I'll see what I can do about providing more useful error messages than just "exception 2". I'm probably accidentally treating the Master Playlist as if it were a Media Playlist somewhere along the way and ending up passing junk data to the MPEG-TS demuxer as a result.

Thanks for your interest! I had no idea anyone else would ever actually try to use this. It's a pleasant surprise. :)

peterbe commented 9 years ago

Yeah, that didn't work either :( Now I get

Media resource blob:http://localhost:10000/4e66a94a-e38c-304d-89d5-a1cfaee3e123 could not be decoded.

screenshot 2015-06-18 15 30 04

Do you know of any other way to play HLS without Flash? We're getting desperate :)

gliese1337 commented 9 years ago

Well, dang. I'll definitely look in to that.

In the meantime, THEOPlayer (http://www.theoplayer.com/) seems to do a pretty good job. I'm not sure how they manage it on Firefox (they use Media Source Extensions in Chrome), but somehow they've managed to eliminate the popping audio artifacts that I get on segment boundaries.

I started working on this because our trial period ran out and we didn't want to deal with THEOPlayer's licensing requirements (and partially because I found THEOPlayer's embedding system & JS API to be Less Than Ideal, but would've worked around that if it weren't for the licensing issues). But I can't say how that would affect your use case. (I assume you're looking for something to use on Air Mozilla?)

There's also an HLS add-on for Video.js (https://github.com/videojs/videojs-contrib-hls), which I believe THEOPlayer is based on (and I know Brightcove's proprietary video player is), but that works by transmuxing into FLV format, and I'm pretty sure it still uses a Flash fallback instead of HTML5 video (or drawing directly to a canvas like Broadway.js does) to actually put pixels on the screen.

peterbe commented 9 years ago

I'll definitely investigate this THEOPlayer. It's not the first proprietary js lib we've used. We're currently using JWPlayer to play our HLS but it, just like Video.js ultimately requires Flash.

I get the feeling that video.js is a Polyfill for native support of HLS and it polyfills "to" Flash.

What we want is a polyfill lib that simulates what Safari can do natively but entirely without Flash.

Yes, this is for Air Mozilla. We're currently 100% HTML5 JS playing archived videos but we're now in the kill-flash battle on the live streams.

gliese1337 commented 9 years ago

Upon a little bit more investigation, I have not been able to replicate your second error. Loading any of the Media Playlists:

https://mozillalive-a.akamaihd.net/Akamai_Public/ngrp:MTV-Commons_all/chunklist_w1074266747_b2121728.m3u8 https://mozillalive-a.akamaihd.net/Akamai_Public/ngrp:MTV-Commons_all/chunklist_w1074266747_b923728.m3u8 https://mozillalive-a.akamaihd.net/Akamai_Public/ngrp:MTV-Commons_all/chunklist_w1074266747_b423728.m3u8 https://mozillalive-a.akamaihd.net/Akamai_Public/ngrp:MTV-Commons_all/chunklist_w1074266747_b273728.m3u8

individually works fine. Not that I doubt you encountered the error, but I'm not seeing it anymore.

Since this is a live stream, it's possible that some part of my MPEG-TS-to-MP4 transmuxing pipeline was choking on some specific chunk that isn't present in the playlist anymore, since the playlists are constantly updating with new stream chunks. I attempted to download some of the old chunks so I could inspect the bytes as the flow through the transmuxer and find out exactly which one was causing the error and why, but it looks like they are garbage collected relatively quickly; I just get 404s. :(

The demo page will only, however, display whatever chunks happen to be listed in the manifest at the time that you load it, though. Actually updating to keep up with a live stream is another feature that is as yet unimplemented. This is all great for my own testing, though. Part of the reason these features aren't implemented yet is that, since the guy paying me doesn't need 'em, I don't have access to any Master Playlist or live streams to test with. Is there an easy way to get a hold of more of more streams from Air Mozilla for future use, and if so would you mind at all if I did use them for continuing testing & development?

With any luck, I might be able to get this to a point where it's useable for you in a couple weeks or so, if I have data streams to test with.

RAMilewski commented 9 years ago

We're in the process of switching from adaptive bitrate RTMP to HLS for the live streams on AirMo. There are a couple of test pages on our staging server that carry public live content from our Mountain View venue whenever there's a live event there.

One on the Edgecast Network: https://air.allizom.org/mtv-commons-public-hls-wowza1-check/ and on the Akamai Network: https://air.allizom.org/mtv-commons-public-hls-wowza1-check/

These are links to pages with JWPlayer instances looking at the streams. With the developer tools in Firefox or Chrome you can extract the paths to the .m3u8 HLS manifest files.

Those streams will go dark anytime there is a non-plublic event streamed from that venue, but there are none on the schedule before the first of July. I'll try to keep at least something nailed up on that stream 24/7 until then.

Are you doing any work on MPEG-DASH players? That is also of interest here.

gliese1337 commented 9 years ago

Thanks. That'll be quite helpful.

We have looked at MPEG-DASH, and considered adopting it alongside HLS in the future, but at the moment we don't have the manpower available to dedicate to it. I've been told there's a parallel project to mine that's working on transmuxing MPEG-TS segments to DASH-compatible segmented MP4 on the fly specifically so that we can use a single stream source to feed either an HLS or MPEG-DASH player.

Incidentally, I'm now getting the "Media resource blob: ... could not be decoded." error myself. This does seem to be restricted to Firefox. I've tried to construct the absolute simplest MP4 files possible for the sake of greater efficiency, so it is quite possible that in that quest I introduced an error in the muxer somewhere that produces technically-invalid MP4s. Chrome plays them fine, but I guess Firefox must have a stricter MP4 decoder.

peterbe commented 9 years ago

@gliese1337 FYI, we've contacted THEOPlayer. Apparently they support Flash-free HLS decoding plus player. We're going to give it a try to see if it works. It's proprietary which is a bummer but if it works, it might be worth setting up for reals. Thanks for the tip. Just trying to keep you informed where our heads are.

gliese1337 commented 9 years ago

Thanks for the update. I expect THEOPlayer really will be your best option. Eve after I get Master Playlist support done, and fix the data corruption issues that are currently plaguing Firefox, there are some inter-segment stuttering problems (like the audio artifacts I already mentioned) that might keep this from meeting the standard of quality you need, and fixing those may take a good long time.

Good news, however, is that I am making steady progress on implementing Master Playlist support, and I've got video consistently working in Firefox now (tested on one of the sub-streams from https://mozillalive-a.akamaihd.net/Akamai_Public/ngrp:MTV-Commons_all/playlist.m3u8). Audio isn't quite working right, but that should be fixed up shortly as well.

gliese1337 commented 9 years ago

Videos now play consistently in Firefox, tested with all of my original 3 streams as well as the substreams from https://mozillalive-a.akamaihd.net/Akamai_Public/ngrp:MTV-Commons_all/playlist.m3u8.

Unfortunately, the audio is all messed up for some videos (but not all!). It's also all messed up in Windows Media Player, so this probably isn't a Firefox-specific issue, but things play fine in Chrome, and one of the streams where I see the error is the one from Mozilla, so for practical purposes it is a Firefox problem and I'm gonna leave this issue open a little longer....

peterbe commented 9 years ago

So, Firefox is struggling more than Chrome? (...with the Audio) That's bad. We should file bugs about that in Bugzilla so it can be fixed. Do you know a good way of setting up a semi-permanent demo using a public .m3u8 file?

gliese1337 commented 9 years ago

I suppose that's one way of looking at it. But, as noted, the segments which I'm seeing problems with in Firefox are also causing problems for Windows Media Player, so I don't think I can fault Firefox for not playing them either. Setting up a (semi-)permanent demo should be as easy as simply putting up a static .m3u8 file that points to a static collection of .ts files on a file server somewhere. That's how the ODH video is set up- everything was pre-segmented and then just dumped on Amazon S3.

I could put together a collection of MP4 video segments that demonstrate the problem (play fine in Chrome, have weird audio in Windows Media & Firefox) if you like.

Speaking of which, playback now seems not as consistent as it did last night. Videos that load do play, but it seems to just stop trying to load new segments after a while, with no errors, and where exactly it stops is different every time. Manually seeking the video or hitting pause and then play again gets it restarted.

Well, this is why we test multiple times and with lots of different inputs....

gliese1337 commented 9 years ago

Well, I've gotten it to the point where it behaves identically in Chrome, Firefox, and Windows Media Player for all the test segments I've got.

Unfortunately, this comes at the cost of a weird regression where some segments (not just some streams, but rather specific segments in streams) end up freeze-framed- the first frame comes up, but it doesn't animate until the next segment replaces it. Audio plays fine.

I do not know why fixing the audio should have messed up the video sometimes, but it did. So, still not quite there yet....

peterbe commented 9 years ago

Go go go! It's great to hear that you're making progress. You're pushing the envelope.

derrod commented 9 years ago

It's great to see something like this as an open source project. Viblast Player and THEOPlayer both are closed source unfortunately (and not free).

How far do you intend to take this project? Is support for live/dvr streams planned? Especially the latter is something I've been looking for for some time and neither Theoplayer nor viblast have good support for it.

gliese1337 commented 9 years ago

@derrod Support for live streams is in the pipeline; compared to just getting video on screen and audio on speakers, reliably, making it live is pretty simple, and I've got another programmer on the project who's working on the infrastructure for that.

gliese1337 commented 9 years ago

OK, this should all be fixed now. There are some playback issues with stuttering between segments, but they are all the same between browsers.

We actually managed to get to parity between browsers a couple weeks ago. However, I'm now having issues with Firefox randomly not executing certain source files. Looking at the Network tab, all sources are loaded, but they don't all show up in the debugger, and it throws ReferenceErrors when trying to call functions that were defined in those missing source files. This is causing the demos to fail in FireFox.

rebotnix commented 9 years ago

i would like to help with debugging the firefox issues. currently i received: SyntaxError: unterminated parenthetical HLSPlayer.min.js:112:97 ReferenceError: HLSPlayer is not defined browser.js:21:2 DOM-Neuberechnung: 0.29ms ReferenceError: HLSPlayer is not defined browser.js:21:2 DOM-Neuberechnung: 0.21ms

Inside the dev version i got: SyntaxError: unterminated parenthetical M3U8.js:303:20

\ this is easy to fix: please take a look at"M3U8.js:303:20" var DTCCRegExp = /"SERVICE(([1-9]|[0-5]\d|6[0-3])"/;

change var DTCCRegExp = /"SERVICE([1-9]|[0-5]\d|6[0-3])"/;

ReferenceError: fetchHLSManifests is not defined player.js:251:2 SyntaxError: expected expression, got '<'

I will try to fix the other too.

gliese1337 commented 9 years ago

@garybruckheimer Thanks for the heads-up. I should've reviewed those last few commits a bit more carefully.

Apart from some of the test streams not always bothering to properly exist, it looks like things are working (and sometimes failing) the same in both Chrome and Firefox now. Pull requests for further improvements are welcome.

rebotnix commented 9 years ago

i tested the latest version, works now in firefox. I´m starting now debugging different hls stream. i generate some test hls files. the best seems to work with byterange hls where i encode one ts file which is much better for CDN and number of server requests. with this type of HLS i do also not have any audio issues in firefox at all. When i have an better overview i will upload the files for testing for you guys.

is there a reason for using a canvas object? i´m new into javascript and it seems that the html video tag also supports blob urls, can we not merge the mp4 fragments into url blobs? i think blobs were faster then canvas.

good work so far.

please let this thread open for updates.

thanks gary

gliese1337 commented 9 years ago

@garybruckheimer The reason for using a canvas is to prevent users from being able to easily download the generated video files for each segment; it's possible to just disable right-clicking, but an attacker could in that case still view the live state of the DOM and copy-and-paste blob URLs for downloading if the image were not proxied through a canvas element, which allows us to avoid ever actually adding a video element to the DOM.

It is of course still possible for a sufficiently savvy attacker to intercept the blob URLs or the live unattached video objects in a debugger, but going through a canvas at least makes it significantly more difficult, which helps to alleviate my employers' piracy concerns, and the performance hit is negligible.

Incidentally, while I have not made any use of this possibility, proxying the image through a canvas element also provides the possibility of applying arbitrary image transforms to it. So, it might be fun to add a custom video filter feature at some future date.