Skip to content

Commit

Permalink
Add high resolution meeting features and additional codecs (#2812)
Browse files Browse the repository at this point in the history
* Add high resolution meeting features and additional codecs

Co-authored-by: Shi Su <shisuss@amazon.com>
Co-authored-by: David Wang <davidwj@amazon.com>
Co-authored-by: Xiang Li <rixiang@amazon.com>
Co-authored-by: Henry Smith <hensmi@amazon.com>

---------

Co-authored-by: Shi Su <shisuss@amazon.com>
Co-authored-by: David Wang <davidwj@amazon.com>
Co-authored-by: Xiang Li <rixiang@amazon.com>
Co-authored-by: Henry Smith <hensmi@amazon.com>
  • Loading branch information
5 people authored Dec 12, 2023
1 parent 7a9aebe commit 3afd784
Show file tree
Hide file tree
Showing 148 changed files with 10,925 additions and 4,199 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [3.19.0] - 2023-09-20

### Added
- Add high resolution meeting features. See the [Meeting Features](https://aws.github.io/amazon-chime-sdk-js/modules/meetingfeatures.html) guide for more information.
- Add VP9 and AV1 video codecs. See the [Video Codecs](https://aws.github.io/amazon-chime-sdk-js/modules/videocodecs.html) guide for more information. VP9 has the ability to enable SVC.

### Removed

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ The following developer guides cover specific topics for a technical audience.
- [Client Event Ingestion](https://aws.github.io/amazon-chime-sdk-js/modules/clientevent_ingestion.html)
- [Content Security Policy](https://aws.github.io/amazon-chime-sdk-js/modules/contentsecurity_policy.html)
- [Managing Video Quality for Different Video Layouts](https://aws.github.io/amazon-chime-sdk-js/modules/videolayout.html)
- [Meeting Features](https://aws.github.io/amazon-chime-sdk-js/modules/meetingfeatures.html)

## Migration Guides

Expand Down
152 changes: 100 additions & 52 deletions demos/browser/app/meetingV2/component/ContentShareManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,65 +203,113 @@ export default class ContentShareManager implements ContentShareObserver {
document.getElementById('dropdown-item-content-share-test-stereo-audio-tone').style.display = 'none';
}

document.getElementById('content-enable-simulcast').addEventListener('click', () => {
this.updateContentSimulcastAndSVCConfigUX();
});
document.getElementById('content-enable-svc').addEventListener('click', () => {
this.updateContentSimulcastAndSVCConfigUX();
});
this.updateContentSimulcastAndSVCConfigUX();


document.getElementById('button-save-content-share-configs').addEventListener('click', () => {
this.frameRate = parseInt((document.getElementById('content-capture-frame-rate') as HTMLInputElement).value, 10);
this.setContentShareConfig();
});
this.setContentShareConfig();
}

const previousEnableVolumeReduction = this.enableVolumeReduction;
const previousEnableCircularCut = this.enableCirculeCut;
this.enableVolumeReduction = (document.getElementById(
'content-enable-volume-reduction'
) as HTMLInputElement).checked;
this.enableCirculeCut = (document.getElementById('content-enable-circular-cut') as HTMLInputElement).checked;
if (
previousEnableVolumeReduction !== this.enableVolumeReduction ||
previousEnableCircularCut !== this.enableCirculeCut
) {
this.logger.info(
`New values for content share media processing, restarting. enableVolumeReduction:${this.enableVolumeReduction}, enableCirculeCut:${this.enableCirculeCut}`
);
if (this.started) {
this.stop();
this.start();
}
private setContentShareConfig(): void {
this.frameRate = parseInt((document.getElementById('content-capture-frame-rate') as HTMLInputElement).value, 10);

const previousEnableVolumeReduction = this.enableVolumeReduction;
const previousEnableCircularCut = this.enableCirculeCut;
this.enableVolumeReduction = (document.getElementById(
'content-enable-volume-reduction'
) as HTMLInputElement).checked;
this.enableCirculeCut = (document.getElementById('content-enable-circular-cut') as HTMLInputElement).checked;
if (
previousEnableVolumeReduction !== this.enableVolumeReduction ||
previousEnableCircularCut !== this.enableCirculeCut
) {
this.logger.info(
`New values for content share media processing, restarting. enableVolumeReduction:${this.enableVolumeReduction}, enableCirculeCut:${this.enableCirculeCut}`
);
if (this.started) {
this.stop();
this.start();
}
}

const enableSimulcastForContentShare = (document.getElementById('content-enable-simulcast') as HTMLInputElement)
const enableSimulcastForContentShare = (document.getElementById('content-enable-simulcast') as HTMLInputElement)
.checked;
if (enableSimulcastForContentShare) {
const lowMaxBitratesKbps =
parseInt((document.getElementById('content-simulcast-low-max-bitratekbps') as HTMLInputElement).value) ||
undefined;
const lowScaleFactor =
parseInt((document.getElementById('content-simulcast-low-scale-factor') as HTMLInputElement).value) ||
undefined;
const lowMaxFramerate =
parseInt((document.getElementById('content-simulcast-low-max-framerate') as HTMLInputElement).value) ||
undefined;
const highMaxBitratesKbps =
parseInt((document.getElementById('content-simulcast-high-max-bitratekbps') as HTMLInputElement).value) ||
undefined;
const highScaleFactor =
parseInt((document.getElementById('content-simulcast-high-scale-factor') as HTMLInputElement).value) ||
undefined;
const highMaxFramerate =
parseInt((document.getElementById('content-simulcast-high-max-framerate') as HTMLInputElement).value) ||
undefined;
this.audioVideo.enableSimulcastForContentShare(true, {
low: {
maxBitrateKbps: lowMaxBitratesKbps,
scaleResolutionDownBy: lowScaleFactor,
maxFramerate: lowMaxFramerate,
},
high: {
maxBitrateKbps: highMaxBitratesKbps,
scaleResolutionDownBy: highScaleFactor,
maxFramerate: highMaxFramerate,
},
});
} else {
this.audioVideo.enableSimulcastForContentShare(false);

const enableSVCForContentShare = (document.getElementById('content-enable-svc') as HTMLInputElement)
.checked;
if (enableSimulcastForContentShare) {
const lowMaxBitratesKbps =
parseInt((document.getElementById('content-simulcast-low-max-bitratekbps') as HTMLInputElement).value) ||
undefined;
const lowScaleFactor =
parseInt((document.getElementById('content-simulcast-low-scale-factor') as HTMLInputElement).value) ||
undefined;
const lowMaxFramerate =
parseInt((document.getElementById('content-simulcast-low-max-framerate') as HTMLInputElement).value) ||
undefined;
const highMaxBitratesKbps =
parseInt((document.getElementById('content-simulcast-high-max-bitratekbps') as HTMLInputElement).value) ||
undefined;
const highScaleFactor =
parseInt((document.getElementById('content-simulcast-high-scale-factor') as HTMLInputElement).value) ||
undefined;
const highMaxFramerate =
parseInt((document.getElementById('content-simulcast-high-max-framerate') as HTMLInputElement).value) ||
undefined;
this.audioVideo.enableSimulcastForContentShare(true, {
low: {
maxBitrateKbps: lowMaxBitratesKbps,
scaleResolutionDownBy: lowScaleFactor,
maxFramerate: lowMaxFramerate,
},
high: {
maxBitrateKbps: highMaxBitratesKbps,
scaleResolutionDownBy: highScaleFactor,
maxFramerate: highMaxFramerate,
},
});
if (enableSVCForContentShare) {
this.audioVideo.enableSVCForContentShare(true);
} else {
this.audioVideo.enableSimulcastForContentShare(false);
this.audioVideo.enableSVCForContentShare(false);
}
});
}
}

private updateContentSimulcastAndSVCConfigUX() {
const enableSimulcastForContentShare = (document.getElementById('content-enable-simulcast') as HTMLInputElement)
.checked;
if (enableSimulcastForContentShare) {
(document.getElementById('content-enable-svc') as HTMLInputElement).disabled = true;
(document.getElementById('content-enable-svc') as HTMLInputElement).checked = false;
return;
}

const enableSVCConfig = (document.getElementById('content-svc-config')).style.display === 'block';
if (enableSVCConfig) {
(document.getElementById('content-enable-svc') as HTMLInputElement).disabled = false;
} else {
(document.getElementById('content-enable-svc') as HTMLInputElement).disabled = true;
(document.getElementById('content-enable-svc') as HTMLInputElement).checked = false;
}

const enableSVC = (document.getElementById('content-enable-svc') as HTMLInputElement).checked;
if (enableSVC) {
(document.getElementById('content-enable-simulcast') as HTMLInputElement).checked = false;
(document.getElementById('content-enable-simulcast') as HTMLInputElement).disabled = true;
} else {
(document.getElementById('content-enable-simulcast') as HTMLInputElement).disabled = false;
}
}

private updateContentShareUX(): void {
Expand Down
54 changes: 45 additions & 9 deletions demos/browser/app/meetingV2/meetingV2.html
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,6 @@ <h5 class="modal-title" id="additional-options-modal-label">Additional Options</
</select>
<label for="logLevel" style="text-align: left;">Log Level:</label>
</div>
<div class="form-floating mb-3">
<select name="videoCodec" class="form-select" id="videoCodecSelect">
<option value="default">Meeting Default</option>
<option value="vp8">VP8</option>
<option value="h264ConstrainedBaselineProfile">H.264 Constrained Baseline Profile</option>
</select>
<label for="videoCodec" style="text-align: left;">Preferred Video Send Codec:</label>
</div>
<div class="form-floating mb-3">
<select name="audioCapability" class="form-select" id="audioCapabilitySelect">
<option value="SendReceive">SendReceive</option>
Expand Down Expand Up @@ -175,16 +167,52 @@ <h5 class="modal-title" id="additional-options-modal-label">Additional Options</
<label for="fullband-music-stereo-quality" class="form-check-label">Set fullband music (stereo)
quality</label>
</div>
<label for="videoCodec" style="text-align: left;">Preferred Video Send Codec:</label>
<select name="videoCodec" class="form-select" id="videoCodecSelect">
<option value="default">Meeting Default</option>
<option value="vp8">VP8</option>
<option value="h264ConstrainedBaselineProfile">H.264 Constrained Baseline Profile</option>
<option value="vp9Profile0" id="vp9-video-codec">VP9 Profile 0</option>
<option value="av1Main" id="av1Main-video-codec">AV1 Main Profile</option>
</select>
<label for="contentCodec" style="text-align: left;">Preferred Content Send Codec:</label>
<select name="contentCodec" class="form-select" id="contentCodecSelect">
<option value="default">Meeting Default</option>
<option value="vp8">VP8</option>
<option value="h264ConstrainedBaselineProfile">H.264 Constrained Baseline Profile</option>
<option value="vp9Profile0" id="vp9Profile0-content-codec">VP9 Profile 0</option>
<option value="av1Main"id="av1Main-content-codec">AV1 Main Profile</option>
</select>
<label for="videoFeature" id="videoFeatureTitle" style="text-align: left;">Meeting Maximum Camera Video Resolution:</label>
<select name="videoFeature" class="form-select" id="videoFeatureSelect">
<option value="none">Disable Camera Video</option>
<option value="hd" selected>HD 720p</option>
<option value="fhd">FHD 1080p (requires max attendee)</option>
</select>
<label for="contentFeature" id="contentFeatureTitle" style="text-align: left;">Meeting Maximum Content Share Resolution:</label>
<select name="contentFeature" class="form-select" id="contentFeatureSelect">
<option value="none">Disable Content Share</option>
<option value="fhd" selected>FHD 1080p</option>
<option value="uhd">UHD 2160p (requires max attendee)</option>
</select>
<div class="form-group row" style="text-align: left;">
<label style="padding-top:5px" class="col-md-9 col-form-label">Max attendees allowed (range: 1 - 250):</label>
<input for="max-attendee-count" class="col-md-3" type="number" id="max-attendee-cnt">
</div>
<div class="form-check" style="text-align: left;">
<input type="checkbox" id="simulcast" class="form-check-input">
<label for="simulcast" class="form-check-label">Enable Simulcast for Chrome</label>
</div>
<div class="form-check" style="text-align: left;">
<input type="checkbox" id="svc" class="form-check-input">
<label for="svc" class="form-check-label">Enable SVC for Chrome</label>
</div>
<div class="form-check" style="text-align: left;">
<input type="checkbox" id="priority-downlink-policy" class="form-check-input">
<label for="priority-downlink-policy" class="form-check-label">Use Priority-Based Downlink
Policy</label>
</div>
<lable id="server-side-network-adaption-title" for="server-side-network-adaption" style="display: none; padding-top:5px">Server Side Network Adaption</lable>
<label id="server-side-network-adaption-title" for="server-side-network-adaption" style="display: none; padding-top:5px">Server Side Network Adaption</label>
<select id="server-side-network-adaption" class="form-select" style="width:100%; display: none;">
<option value="default">Default</option>
<option value="none">None (Deprecated)</option>
Expand Down Expand Up @@ -368,6 +396,7 @@ <h1 class="h3 mb-3 font-weight-normal text-center">Select devices</h1>
<option value="360p">360p (nHD) @ 15 fps (600 Kbps max)</option>
<option value="540p" selected>540p (qHD) @ 15 fps (1.4 Mbps max)</option>
<option value="720p">720p (HD) @ 15 fps (1.5 Mbps max)</option>
<option value="1080p" id="1080p">1080p (FHD) @ 15 fps (2.5 Mbps max)</option>
</select>
</div>
</div>
Expand Down Expand Up @@ -919,6 +948,13 @@ <h5 class="my-2">Simulcast Encoding</h5>
</div>
</div>
</div>
<div id="content-svc-config">
<h5 class="my-2">SVC Encoding</h5>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="content-enable-svc">
<label class="form-check-label" for="content-enable-svc">Enable SVC</label>
</div>
</div>
</div>
<button id="button-save-content-share-configs" type="button" class="btn btn-primary" data-bs-dismiss="modal"
aria-pressed="false" autocomplete="off">
Expand Down
Loading

0 comments on commit 3afd784

Please sign in to comment.