Skip to content

Commit

Permalink
Add disableRemotePlayback to allow ManagedMediaSource to open
Browse files Browse the repository at this point in the history
  • Loading branch information
robwalch committed Jun 28, 2023
1 parent d99e282 commit 754951b
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 18 deletions.
53 changes: 41 additions & 12 deletions src/controller/buffer-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import type {
BufferFlushingData,
FragParsedData,
FragChangedData,
ManifestLoadingData,

Check warning on line 27 in src/controller/buffer-controller.ts

View workflow job for this annotation

GitHub Actions / build

'ManifestLoadingData' is defined but never used
} from '../types/events';
import type { ComponentAPI } from '../types/component-api';
import type { ChunkMetadata } from '../types/transmuxer';
Expand Down Expand Up @@ -168,20 +169,26 @@ export default class BufferController implements ComponentAPI {
);
if (media && MediaSource) {
const ms = (this.mediaSource = new MediaSource());
this.log(`created media source: ${ms.constructor?.name}`);
// MediaSource listeners are arrow functions with a lexical scope, and do not need to be bound
ms.addEventListener('sourceopen', this._onMediaSourceOpen);
ms.addEventListener('sourceended', this._onMediaSourceEnded);
ms.addEventListener('sourceclose', this._onMediaSourceClose);
ms.addEventListener('startstreaming', this._onStartStreaming);
ms.addEventListener('endstreaming', this._onEndStreaming);

// Disable AirPlay for ManagedMediaSource to work
media.disableRemotePlayback = true;

// link video and media Source
media.src = self.URL.createObjectURL(ms);
// cache the locally generated object url
this._objectUrl = media.src;
const objectUrl = (this._objectUrl = self.URL.createObjectURL(ms));
// link video and media Source
try {
media.removeAttribute('src');
removeChildren(media);
media.disableRemotePlayback = true;
addSource(media, objectUrl);
media.load();
} catch (error) {
media.src = objectUrl;
}
media.addEventListener('emptied', this._onMediaEmptied);
}
}
Expand Down Expand Up @@ -249,11 +256,14 @@ export default class BufferController implements ComponentAPI {

// clean up video tag src only if it's our own url. some external libraries might
// hijack the video tag and change its 'src' without destroying the Hls instance first
if (media.src === _objectUrl) {
if (this.mediaSrc === _objectUrl) {
media.removeAttribute('src');
removeChildren(media);
media.load();
} else {
this.warn('media.src was changed by a third party - skip cleanup');
this.warn(
'media|source.src was changed by a third party - skip cleanup'
);
}
}

Expand Down Expand Up @@ -867,14 +877,20 @@ export default class BufferController implements ComponentAPI {
};

private _onMediaEmptied = () => {
const { media, _objectUrl } = this;
if (media && media.src !== _objectUrl) {
this.error(
`Media element src was set while attaching MediaSource (${_objectUrl} > ${media.src})`
const { mediaSrc, _objectUrl } = this;
if (mediaSrc !== _objectUrl) {
logger.error(
`Media element src was set while attaching MediaSource (${_objectUrl} > ${mediaSrc})`
);
}
};

private get mediaSrc(): string | undefined {
const media =
(this.media?.firstChild as HTMLSourceElement | null) || this.media;
return media?.src;
}

private _onSBUpdateStart(type: SourceBufferName) {
const { operationQueue } = this;
const operation = operationQueue.current(type);
Expand Down Expand Up @@ -1018,3 +1034,16 @@ export default class BufferController implements ComponentAPI {
});
}
}

function removeChildren(node: HTMLElement) {
while (node.firstChild) {
node.removeChild(node.firstChild);
}
}

function addSource(media: HTMLMediaElement, url: string) {
const source = self.document.createElement('source');
source.type = 'video/mp4';
source.src = url;
media.appendChild(source);
}
8 changes: 2 additions & 6 deletions src/controller/eme-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1164,9 +1164,7 @@ class EMEController implements ComponentAPI {
)
.concat(
media?.setMediaKeys(null).catch((error) => {
this.log(
`Could not clear media keys: ${error}. media.src: ${media?.src}`
);
this.log(`Could not clear media keys: ${error}`);
})
)
)
Expand All @@ -1177,9 +1175,7 @@ class EMEController implements ComponentAPI {
}
})
.catch((error) => {
this.log(
`Could not close sessions and clear media keys: ${error}. media.src: ${media?.src}`
);
this.log(`Could not close sessions and clear media keys: ${error}`);
});
}

Expand Down

0 comments on commit 754951b

Please sign in to comment.