videojs / http-streaming

HLS, DASH, and future HTTP streaming protocols library for video.js
https://videojs-http-streaming.netlify.app/
Other
2.52k stars 424 forks source link

HEVC support in codecs logic #293

Open daniel-vanveen opened 5 years ago

daniel-vanveen commented 5 years ago

Please do not delete the template, by filling out the required information we can investigate your issue more quickly.

Before opening an issue see if your problem can be resolved with the troubleshooting guide.

Description

The implementation of codecs.js assumes videos are always AVC so HEVC playlists are incorrectly represented as not containing video. This is probably more of an "enhancement" than an issue.

Sources

Try http://dash.akamaized.net/dash264/TestCasesHEVC/1b/1/TOS_Live_HEVC_MultiRate.mpd

Steps to reproduce

Explain in detail the exact steps necessary to reproduce the issue.

  1. Enable debug level logs in video-js object.
  2. Play http://dash.akamaized.net/dash264/TestCasesHEVC/1b/1/TOS_Live_HEVC_MultiRate.mpd
  3. Observe logs

In util/codecs.js, it is assumed that all video codecs begin with avc1 and that all audio codecs begin mp4a (AAC). This can affect playlist selection (although not always). i.e. a DASH manifest specifying an HEVC video track and an AAC audio track will incorrectly be parsed as an audio only playlist. With default settings, this still allows the video to play (assuming the browser reports H.265 support) however it won't if enableLowInitialPlaylist is set to true.

In playlist-selector.js (lowestBitrateCompatibleVariantSelector) // Parse and assume that playlists with no video codec have no video // (this is not necessarily true, although it is generally true). // // If an entire manifest has no valid videos everything will get filtered // out.

This results in nothing playing back, even though the browser and OS support HEVC playback.

Results

Expected

Expect that if a format is supported by the browser, it is playable through Video.js http streaming.

Error output

If there are any errors in the console, from the player, or anywhere else please include them here:

Additional Information

Please include any additional information necessary here. Including the following:

videojs-http-streaming version

what version of videojs-http-streaming does this occur with? videojs-http-streaming 1.2.6

videojs version

what version of videojs does this occur with? video.js v7.2.4

Browsers

what browsers are affected? please include browser and version for each

Platforms

what platforms are affected? please include operating system and version or device and version for each

Other Plugins

are any other videojs plugins being used on the page? If so, please list them with version below. *

Other JavaScript

are you using any other javascript libraries or frameworks on the page? if so please list them below. *

welcome[bot] commented 5 years ago

👋 Thanks for opening your first issue here! 👋

If you're reporting a 🐞 bug, please make sure you include steps to reproduce it. We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can. To help make it easier for us to investigate your issue, please follow the contributing guidelines.

andrewaggb commented 4 years ago

I've run into this as well and would like it to work.

Here are some more sample streams (https works as well) http://bitmovin-a.akamaihd.net/content/dataset/multi-codec/hevc/stream_fmp4.m3u8 http://bitmovin-a.akamaihd.net/content/dataset/multi-codec/hevc/stream.mpd Or a simpler scenario without a master playlist (1080p hevc) taken from the first link. https://bitmovin-a.akamaihd.net/content/dataset/multi-codec/hevc/v1080p_1_fmp4.m3u8

Did you try changing the function you identified to also look for hev1?

export const isVideoCodec = function(codec) { return (/avc1.[\da-f]+/i).test(codec); };

Also it probably is a bit late for your purposes, but videojs with the dash contrib can play hevc fine in supported browsers. http://videojs.github.io/videojs-contrib-dash/

I want to use hls + fmp4.

daniel-vanveen commented 4 years ago

If I recall correctly, I forced that function to return true hoping that would be an easy fix (and it didn't help). Unfortunately I was also needing to use fmp4 so was not using dash contrib.

andrewaggb commented 4 years ago

I'm zoning in a solution.
I've played around with the code a bit and if I change the mimeType in the function below to an hevc one I can play a test file. Appears to simply be a case of the initial mimeType being wrong so the wrong codec is selected in the decoder. I'm trying to figure out if it parses it from the init.mp4 or just uses the same default avc1 one every time. Either way it's probably not too hard to fix.

createClass$1(SourceUpdater, [{ key: 'createSourceBuffer', value: function createSourceBuffer(mimeType, sourceBufferEmitter) { var _this = this;
mimeType = 'video/mp4; codecs="hev1.1.6.L93.B0, mp4a.40.2"';

andrewaggb commented 4 years ago

Well a bit more testing. If you use a master playlist for hls and specify codec's in the EXT-X-STREAM-INF, that codec string is used, otherwise it falls back on the default which is defined as avc1.

  var defaultCodecs = {
    videoCodec: 'avc1',
    videoObjectTypeIndicator: '.4d400d',
    // AAC-LC
    audioProfile: '2'
  };

The only actual code change I needed to make was one line of regex from: parsed = /(^|\s|,)+(avc[13])([^ ,]*)/i.exec(codecs); to parsed = /(^|\s|,)+(avc[13]|hev1)([^ ,]*)/i.exec(codecs);

Assuming you can use a master playlist so you can provide a codec string, the single change above got hevc working for me.

gkatsev commented 4 years ago

We have some work to fix this in https://github.com/videojs/vhs-utils/pull/10 and https://github.com/videojs/http-streaming/pull/762. Though, we're unlikely going to make this change in the current 1.x branch but hopefully, we'll be confident in the changes in master soon.

gkatsev commented 4 years ago

VHS 2.1 supports HEVC in fmp4 and will play it back if the browser supports it.

gkatsev commented 4 years ago

This is coming to Video.js 7 soon.

RafalLukawiecki commented 4 years ago

@gkatsev I just noticed your reply here, having posted a generic HEVC question at https://github.com/videojs/video.js/issues/6889

Will VHS 2.2.1 play HEVC and does it work with vidoejs 7.8.4? Is there a reason 7.8.4 is bundled with 1.x of VHS? Sorry for all the questions, but I could not find any roadmaps, blogs or other resources explaining the relationship between 2.x VHS and the current videojs. I will be soon releasing a new update to our site and as we are re-encoding all videos it would be great to support HEVC with this update—we don’t get to make a major change like that often.

Thank you.

gkatsev commented 4 years ago

VHS 2.2.3 has shipped in Video.js 7.10 which supports HEVC if the browser supports it and if it is packaged in an mp4.

ghost commented 3 years ago

While trying to use HEVC in Edge i found that using videojs to play HEVC in an mp4 container works. But generating a HLS playlist (using ffmpeg hls muxer with fmp4) and playing it with http-streaming and Edge fails.

VIDEOJS: ERROR: (CODE:3 MEDIA_ERR_DECODE) Playback cannot continue. No available working or supported playlists.

daveisfera commented 10 months ago

It appears there's a hard coded value in ffmpeg that makes it so Chrome doesn't want to play the video when it may be able to do so: https://github.com/videojs/video.js/issues/8549#issuecomment-1883831468