Skip to content

Commit

Permalink
Fix AbortError in safari when video is turned ON (aws#2391)
Browse files Browse the repository at this point in the history
  • Loading branch information
devalevenkatesh authored Aug 8, 2022
1 parent c796579 commit b7ed297
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 26 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- Fix `AbortError` when turning video ON in Safari.

## [3.6.0] - 2022-06-23

### Added
Expand Down
30 changes: 15 additions & 15 deletions docs/classes/defaultvideotile.html
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ <h3>constructor</h3>
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L105">src/videotile/DefaultVideoTile.ts:105</a></li>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L118">src/videotile/DefaultVideoTile.ts:118</a></li>
</ul>
</aside>
<h4 class="tsd-parameters-title">Parameters</h4>
Expand Down Expand Up @@ -161,7 +161,7 @@ <h3>bind<wbr>Video<wbr>Element</h3>
<aside class="tsd-sources">
<p>Implementation of <a href="../interfaces/videotile.html">VideoTile</a>.<a href="../interfaces/videotile.html#bindvideoelement">bindVideoElement</a></p>
<ul>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L195">src/videotile/DefaultVideoTile.ts:195</a></li>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L208">src/videotile/DefaultVideoTile.ts:208</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
Expand Down Expand Up @@ -193,7 +193,7 @@ <h3>bind<wbr>Video<wbr>Stream</h3>
<aside class="tsd-sources">
<p>Implementation of <a href="../interfaces/videotile.html">VideoTile</a>.<a href="../interfaces/videotile.html#bindvideostream">bindVideoStream</a></p>
<ul>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L149">src/videotile/DefaultVideoTile.ts:149</a></li>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L162">src/videotile/DefaultVideoTile.ts:162</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
Expand Down Expand Up @@ -242,7 +242,7 @@ <h3>capture</h3>
<aside class="tsd-sources">
<p>Implementation of <a href="../interfaces/videotile.html">VideoTile</a>.<a href="../interfaces/videotile.html#capture">capture</a></p>
<ul>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L251">src/videotile/DefaultVideoTile.ts:251</a></li>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L264">src/videotile/DefaultVideoTile.ts:264</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
Expand All @@ -266,7 +266,7 @@ <h3>destroy</h3>
<aside class="tsd-sources">
<p>Implementation of <a href="../interfaces/videotile.html">VideoTile</a>.<a href="../interfaces/videotile.html#destroy">destroy</a></p>
<ul>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L118">src/videotile/DefaultVideoTile.ts:118</a></li>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L131">src/videotile/DefaultVideoTile.ts:131</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
Expand All @@ -290,7 +290,7 @@ <h3>device<wbr>Pixel<wbr>Ratio<wbr>Changed</h3>
<aside class="tsd-sources">
<p>Implementation of <a href="../interfaces/devicepixelratioobserver.html">DevicePixelRatioObserver</a>.<a href="../interfaces/devicepixelratioobserver.html#devicepixelratiochanged">devicePixelRatioChanged</a></p>
<ul>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L132">src/videotile/DefaultVideoTile.ts:132</a></li>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L145">src/videotile/DefaultVideoTile.ts:145</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
Expand Down Expand Up @@ -321,7 +321,7 @@ <h3>id</h3>
<aside class="tsd-sources">
<p>Implementation of <a href="../interfaces/videotile.html">VideoTile</a>.<a href="../interfaces/videotile.html#id">id</a></p>
<ul>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L137">src/videotile/DefaultVideoTile.ts:137</a></li>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L150">src/videotile/DefaultVideoTile.ts:150</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
Expand All @@ -344,7 +344,7 @@ <h3>mark<wbr>Poor<wbr>Connection</h3>
<aside class="tsd-sources">
<p>Implementation of <a href="../interfaces/videotile.html">VideoTile</a>.<a href="../interfaces/videotile.html#markpoorconnection">markPoorConnection</a></p>
<ul>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L233">src/videotile/DefaultVideoTile.ts:233</a></li>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L246">src/videotile/DefaultVideoTile.ts:246</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
Expand All @@ -369,7 +369,7 @@ <h3>pause</h3>
<aside class="tsd-sources">
<p>Implementation of <a href="../interfaces/videotile.html">VideoTile</a>.<a href="../interfaces/videotile.html#pause">pause</a></p>
<ul>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L219">src/videotile/DefaultVideoTile.ts:219</a></li>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L232">src/videotile/DefaultVideoTile.ts:232</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
Expand All @@ -396,7 +396,7 @@ <h3>set<wbr>Stream<wbr>Id</h3>
<aside class="tsd-sources">
<p>Implementation of <a href="../interfaces/videotile.html">VideoTile</a>.<a href="../interfaces/videotile.html#setstreamid">setStreamId</a></p>
<ul>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L264">src/videotile/DefaultVideoTile.ts:264</a></li>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L277">src/videotile/DefaultVideoTile.ts:277</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
Expand Down Expand Up @@ -426,7 +426,7 @@ <h3>state</h3>
<aside class="tsd-sources">
<p>Implementation of <a href="../interfaces/videotile.html">VideoTile</a>.<a href="../interfaces/videotile.html#state">state</a></p>
<ul>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L141">src/videotile/DefaultVideoTile.ts:141</a></li>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L154">src/videotile/DefaultVideoTile.ts:154</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
Expand All @@ -449,7 +449,7 @@ <h3>state<wbr>Ref</h3>
<aside class="tsd-sources">
<p>Implementation of <a href="../interfaces/videotile.html">VideoTile</a>.<a href="../interfaces/videotile.html#stateref">stateRef</a></p>
<ul>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L145">src/videotile/DefaultVideoTile.ts:145</a></li>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L158">src/videotile/DefaultVideoTile.ts:158</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
Expand All @@ -472,7 +472,7 @@ <h3>unmark<wbr>Poor<wbr>Connection</h3>
<aside class="tsd-sources">
<p>Implementation of <a href="../interfaces/videotile.html">VideoTile</a>.<a href="../interfaces/videotile.html#unmarkpoorconnection">unmarkPoorConnection</a></p>
<ul>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L242">src/videotile/DefaultVideoTile.ts:242</a></li>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L255">src/videotile/DefaultVideoTile.ts:255</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
Expand All @@ -497,7 +497,7 @@ <h3>unpause</h3>
<aside class="tsd-sources">
<p>Implementation of <a href="../interfaces/videotile.html">VideoTile</a>.<a href="../interfaces/videotile.html#unpause">unpause</a></p>
<ul>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L226">src/videotile/DefaultVideoTile.ts:226</a></li>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L239">src/videotile/DefaultVideoTile.ts:239</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
Expand Down Expand Up @@ -566,7 +566,7 @@ <h3><span class="tsd-flag ts-flagStatic">Static</span> disconnect<wbr>Video<wbr>
<li class="tsd-description">
<aside class="tsd-sources">
<ul>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L79">src/videotile/DefaultVideoTile.ts:79</a></li>
<li>Defined in <a href="https://github.com/aws/amazon-chime-sdk-js/blob/main/src/videotile/DefaultVideoTile.ts#L92">src/videotile/DefaultVideoTile.ts:92</a></li>
</ul>
</aside>
<div class="tsd-comment tsd-typography">
Expand Down
15 changes: 14 additions & 1 deletion src/videotile/DefaultVideoTile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,20 @@ export default class DefaultVideoTile implements DevicePixelRatioObserver, Video
// In Safari, a hidden video element can show a black screen.
// See https://bugs.webkit.org/show_bug.cgi?id=241152 for more information.
if (new DefaultBrowserBehavior().requiresVideoPlayWorkaround() && videoElement.paused) {
videoElement.play();
const promise = videoElement.play();
// See https://bugs.webkit.org/show_bug.cgi?id=243519 for more information.
// https://webkit.org/blog/7734/auto-play-policy-changes-for-macos/
/* istanbul ignore else */
if (promise !== undefined) {
promise
.catch(error => {
console.warn('Error playing video in Safari', error);
})
.then(() => {
// `then` block is needed, without it we run into black tile issue even though we catch the error.
console.debug('Video played successfully in Safari');
});
}
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions test/browserbehavior/DefaultBrowserBehavior.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,13 +230,13 @@ describe('DefaultBrowserBehavior', () => {
expect(new DefaultBrowserBehavior().requiresNoExactMediaStreamConstraints()).to.be.false;
});

it('can test Safari version 11', () => {
it('can test Safari version 15', () => {
domMockBehavior = new DOMMockBehavior();
domMockBehavior.browserName = 'safari11';
domMockBehavior.browserName = 'safari15';
mockBuilder = new DOMMockBuilder(domMockBehavior);
expect(new DefaultBrowserBehavior().name()).to.eq('safari');
expect(new DefaultBrowserBehavior().isSupported()).to.be.false;
expect(new DefaultBrowserBehavior().majorVersion()).to.eq(11);
expect(new DefaultBrowserBehavior().isSupported()).to.be.true;
expect(new DefaultBrowserBehavior().majorVersion()).to.eq(15);
expect(new DefaultBrowserBehavior().requiresBundlePolicy()).to.eq('max-bundle');
expect(new DefaultBrowserBehavior().requiresNoExactMediaStreamConstraints()).to.be.false;
});
Expand Down
18 changes: 13 additions & 5 deletions test/dommock/DOMMockBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -605,8 +605,8 @@ export default class DOMMockBuilder {
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.2 Safari/605.1.15';
const SAFARI12_USERAGENT =
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Safari/605.1.15';
const SAFARI11_USERAGENT =
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.0 Safari/605.1.15';
const SAFARI15_USERAGENT =
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Safari/605.1.15';
const IOS_SAFARI12_0_USERAGENT =
'Mozilla/5.0 (iPhone; CPU iPhone OS 12_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1';
const IOS_SAFARI12_1_USERAGENT =
Expand All @@ -621,7 +621,7 @@ export default class DOMMockBuilder {
USER_AGENTS.set('firefox', FIREFOX_USERAGENT);
USER_AGENTS.set('safari', SAFARI_USERAGENT);
USER_AGENTS.set('safari12', SAFARI12_USERAGENT);
USER_AGENTS.set('safari11', SAFARI11_USERAGENT);
USER_AGENTS.set('safari15', SAFARI15_USERAGENT);
USER_AGENTS.set('ios12.0', IOS_SAFARI12_0_USERAGENT);
USER_AGENTS.set('ios12.1', IOS_SAFARI12_1_USERAGENT);
USER_AGENTS.set('ios15.1', IOS_SAFARI15_1_USERAGENT);
Expand Down Expand Up @@ -1330,6 +1330,7 @@ export default class DOMMockBuilder {
style: { [key: string]: string } = {
transform: '',
};
paused: boolean;

private clearAttribute(): void {
this.videoHeight = 0;
Expand All @@ -1356,11 +1357,18 @@ export default class DOMMockBuilder {
this.listeners[type].push(listener);
}

pause(): void {}
pause(): void {
this.paused = true;
}

play(): Promise<void> {
this.paused = false;
if (mockBehavior.videoElementShouldFail) {
return Promise.reject();
if (['ios15.1', 'safari15'].includes(mockBehavior.browserName)) {
return Promise.reject(new MockError('AbortError', 'The operation was aborted'));
} else {
return Promise.reject();
}
}
if (this.refSrcObject) {
new TimeoutScheduler(mockBehavior.videoElementStartPlayDelay).start(() => {
Expand Down
21 changes: 20 additions & 1 deletion test/videotile/DefaultVideoTile.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ describe('DefaultVideoTile', () => {
});

it('unbinds a video stream in Safari', done => {
domMockBehavior.browserName = 'safari12';
domMockBehavior.browserName = 'safari15';
domMockBuilder = new DOMMockBuilder(domMockBehavior);
tile = new DefaultVideoTile(tileId, true, tileController, monitor);
const videoElement = videoElementFactory.create();
Expand Down Expand Up @@ -254,6 +254,25 @@ describe('DefaultVideoTile', () => {
});
});

it('catches AbortError and plays the paused video element in Safari after setting srcObject to a new video stream', done => {
domMockBehavior.browserName = 'safari15';
domMockBehavior.videoElementShouldFail = true;
domMockBuilder = new DOMMockBuilder(domMockBehavior);

tile = new DefaultVideoTile(tileId, true, tileController, monitor);
const sinonSpy = sinon.spy(console, 'warn');
const videoElement = document.createElement('video');
videoElement.pause();
tile.bindVideoElement(videoElement);
tile.bindVideoStream('attendee', true, mockVideoStream, 1, 1, 1);

new TimeoutScheduler(10).start(() => {
expect(sinonSpy.calledWithMatch('Error playing video')).to.be.true;
expect(videoElement.srcObject).to.equal(mockVideoStream);
done();
});
});

it('does not play the non-paused video element in Safari after setting srcObject to a new video stream', done => {
domMockBehavior.browserName = 'ios15.1';
domMockBuilder = new DOMMockBuilder(domMockBehavior);
Expand Down

0 comments on commit b7ed297

Please sign in to comment.