Skip to content

Commit

Permalink
fix: update check for HLS support to better handle google chrome mobile
Browse files Browse the repository at this point in the history
  • Loading branch information
jkeen committed Sep 30, 2024
1 parent 06b47e3 commit 14a7acf
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 18 deletions.
2 changes: 2 additions & 0 deletions ember-stereo/src/services/stereo.js
Original file line number Diff line number Diff line change
Expand Up @@ -394,9 +394,11 @@ export default class Stereo extends Service.extend(EmberEvented) {
try {
var strategies = this._buildStrategies(urlsToTry, options);
if (strategies.filter((s) => s.canPlay).length == 0) {
debug('ember-stereo')('all strategies reported canPlay = false');
return this._handlePreloadError({ urlsToTry, options, strategies });
}
} catch (e) {
debug('ember-stereo')('error building strategies', e);
return this._handlePreloadError({
urlsToTry,
options,
Expand Down
67 changes: 49 additions & 18 deletions ember-stereo/src/stereo-connections/hls.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,68 @@ import { waitFor } from '@ember/test-waiters';
* @constructor
*/

export function getMediaSource() {
function getMediaSource(
preferManagedMediaSource = true,
) {
if (typeof self === 'undefined') return undefined;
return self.MediaSource || self.WebKitMediaSource;
const mms =
(preferManagedMediaSource || !self.MediaSource) &&
(self.ManagedMediaSource );
return (
mms ||
self.MediaSource ||
(self.WebKitMediaSource)
);
}

function mimeTypeForCodec(codec, type) {
return `${type}/mp4;codecs="${codec}"`;
}

function getSourceBuffer() {
return self.SourceBuffer || self.WebKitSourceBuffer;
}

function isMSESupported() {
const mediaSource = getMediaSource();
if (!mediaSource) {
return false;
}

// if SourceBuffer is exposed ensure its API is valid
// Older browsers do not expose SourceBuffer globally so checking SourceBuffer.prototype is impossible
const sourceBuffer = getSourceBuffer();
return (
!sourceBuffer ||
(sourceBuffer.prototype &&
typeof sourceBuffer.prototype.appendBuffer === 'function' &&
typeof sourceBuffer.prototype.remove === 'function')
);
}

export default class HLSSound extends BaseSound {
static acceptMimeTypes = ['application/vnd.apple.mpegurl'];
static canUseConnection() {
// This is copied from the HLS source. We don't want to load all of HLS.js just to check if it can be used
const mediaSource = getMediaSource();
if (!mediaSource) {
if (!isMSESupported()) {
return false;
}
const sourceBuffer = getSourceBuffer();
const isTypeSupported =
mediaSource &&
typeof mediaSource.isTypeSupported === 'function' &&
mediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E,mp4a.40.2"');

// if SourceBuffer is exposed ensure its API is valid
// Older browsers do not expose SourceBuffer globally so checking SourceBuffer.prototype is impossible
const sourceBufferValidAPI =
!sourceBuffer ||
(sourceBuffer.prototype &&
typeof sourceBuffer.prototype.appendBuffer === 'function' &&
typeof sourceBuffer.prototype.remove === 'function');
return !!isTypeSupported && !!sourceBufferValidAPI;

const mediaSource = getMediaSource();
return (
typeof mediaSource?.isTypeSupported === 'function' &&
(['avc1.42E01E,mp4a.40.2', 'av01.0.01M.08', 'vp09.00.50.08'].some(
(codecsForVideoContainer) =>
mediaSource.isTypeSupported(
mimeTypeForCodec(codecsForVideoContainer, 'video'),
),
) ||
['mp4a.40.2', 'fLaC'].some((codecForAudioContainer) =>
mediaSource.isTypeSupported(
mimeTypeForCodec(codecForAudioContainer, 'audio'),
),
))
);
}

static key = 'HLS';
Expand Down

0 comments on commit 14a7acf

Please sign in to comment.