Skip to content

Commit

Permalink
feat(live): support low latency streams (beta) KMCNG-2460 (#1035)
Browse files Browse the repository at this point in the history
  • Loading branch information
amirch1 committed Dec 7, 2022
1 parent 8616664 commit 87f6a88
Show file tree
Hide file tree
Showing 13 changed files with 160 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export class EntryLiveWidget extends EntryWidget implements OnDestroy {
public _showDVRWindow: boolean = false;
public _dvrWindowAvailable: boolean = false;
public _explicitLive: boolean = true;
public _lowLatency: boolean = false;
public _srtKey: string = '';
public _liveDashboardEnabled: boolean = false;

Expand Down Expand Up @@ -85,6 +86,7 @@ export class EntryLiveWidget extends EntryWidget implements OnDestroy {
this._dvrWindowAvailable = false;
this._selectedConversionProfile = null;
this._explicitLive = true;
this._lowLatency = false;
this._srtKey = "";
this._manualStreamsConfiguration = [];
this._bitrates = [];
Expand All @@ -108,11 +110,33 @@ export class EntryLiveWidget extends EntryWidget implements OnDestroy {
}
if (this._liveType === "kaltura") {
(data as KalturaLiveStreamEntry).explicitLive = this._explicitLive ? KalturaNullableBoolean.trueValue : KalturaNullableBoolean.falseValue;
(data as KalturaLiveStreamEntry).adminTags = this.getAdminTags(data.adminTags || '');
(data as KalturaLiveStreamEntry).srtPass = this._srtKey === '' ? null : this._srtKey;
(data as KalturaLiveStreamEntry).conversionProfileId = this._selectedConversionProfile;
}
}

private getAdminTags(tags: string): string {
if (this._lowLatency) {
if (tags.indexOf('lowlatency') === -1) {
if (tags === '') {
tags = 'lowlatency';
} else {
tags += ',lowlatency';
}
}
} else {
if (tags.indexOf('lowlatency') > -1) {
if (tags.indexOf(',lowlatency') !== -1) {
tags = tags.replace(',lowlatency','');
} else {
tags = tags.replace('lowlatency', '');
}
}
}
return tags;
}

public onSrtPassChange(): void {
if (this._srtKey.length > 9 && this._srtKey.length < 80){
this.setDirty();
Expand Down Expand Up @@ -221,6 +245,7 @@ export class EntryLiveWidget extends EntryWidget implements OnDestroy {
}
}
this._explicitLive = entry.explicitLive === KalturaNullableBoolean.trueValue;
this._lowLatency = entry.adminTags && entry.adminTags.indexOf('lowlatency') > -1;
this._srtKey = entry.srtPass;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<k-area-blocker [showLoader]="_widgetService.showSectionLoader" [message]="_widgetService.sectionBlockerMessage" [bodyScroll]="true">
<div class="kLive">
<p class="kTitle">{{'applications.content.entryDetails.live.live' | translate}}</p>
<div class="kLiveDetails">
<div class="kLiveDetails" #details>

<div *ngIf="_widgetService._liveType === 'kaltura'">
<div>
Expand Down Expand Up @@ -156,6 +156,20 @@
<span>{{_widgetService._explicitLive ? ( 'app.common.on' | translate) : ( 'app.common.off' | translate)}}</span>
</div>
</div>

<div class="kRow">
<div class="kLabels">
<span>{{'applications.content.entryDetails.live.lowLatency' | translate}}</span>
<i #helpTip class="kIconhelp_full kHelpTip" (click)="openLoaLatencyHelp()"></i>
</div>
<div>
<p-inputSwitch class="kControl kInputSwitch"
[disabled]="_kmcPermissions.LIVE_STREAM_UPDATE | kDisabledIfNotPermitted"
(onChange)="_widgetService.setDirty()"
[(ngModel)]="_widgetService._lowLatency"></p-inputSwitch>
<span>{{_widgetService._explicitLive ? ( 'app.common.on' | translate) : ( 'app.common.off' | translate)}}</span>
</div>
</div>
</div>


Expand Down Expand Up @@ -299,6 +313,7 @@
<span>{{config.url}}</span>
</div>
</div>
<span #anchor></span>
</div>
</div>
</k-area-blocker>
Expand All @@ -314,3 +329,13 @@
<kLiveDashboard [entryId]="_widgetService.data.id" [parentPopupWidget]="liveDashboard"></kLiveDashboard>
</ng-template>
</kPopupWidget>

<kPopupWidget data-aid="helpTip" #lowLatencyHelp [popupWidth]="410" [appendTo]="details" [closeBtn]="false" [targetRef]="anchor" [targetOffset]="{'x': 158, 'y': -50}" [closeOnScroll]="true">
<div class="kTooltip">
<div class="content1">
<span>{{'applications.upload.prepareLive.kalturaStreamType.lowLatencyHelp1' | translate}}</span>
<a (click)="openLowLatencyLink()">{{'applications.upload.prepareLive.kalturaStreamType.lowLatencyHelp2' | translate}}</a>
</div>
<span>{{'applications.upload.prepareLive.kalturaStreamType.lowLatencyHelp3' | translate}}</span>
</div>
</kPopupWidget>
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,10 @@
margin-bottom: 14px;
}
.kLabels{
display: flex;
align-items: center;
flex: 0 0 auto;
width: 150px;
width: 170px;
}
.kSrtKey {
white-space: nowrap;
Expand Down Expand Up @@ -197,6 +199,30 @@
color: $kDandger;
font-size: 13px;
}
.kHelpTip {
font-size: 15px;
margin-left: 8px;
cursor: pointer;
&:hover{
color: $kSecondary;
}
}
.kTooltip {
padding: 24px;
box-sizing: border-box;
display: flex;
flex-direction: column;
span, a {
white-space: nowrap;
}
.content1 {
display: flex;
margin-bottom: 4px;
a {
margin-left: 4px;
}
}
}
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { KMCPermissions } from 'app-shared/kmc-shared/kmc-permissions';
import { LiveAnalyticsMainViewService } from 'app-shared/kmc-shared/kmc-views';
import { KalturaLiveStreamEntry, KalturaSipSourceType } from 'kaltura-ngx-client';
import { EntryStore } from "../entry-store.service";
import {serverConfig} from "config/server";

@Component({
selector: 'kEntryLive',
Expand All @@ -18,6 +19,7 @@ import { EntryStore } from "../entry-store.service";
export class EntryLive implements AfterViewInit, OnInit, OnDestroy {

@ViewChild('liveAnalytics', { static: true }) _liveAnalytics: PopupWidgetComponent;
@ViewChild('lowLatencyHelp', { static: true }) _lowLatencyHelp: PopupWidgetComponent;

public _kmcPermissions = KMCPermissions;
public _copyToClipboardTooltips: { success: string, failure: string, idle: string, notSupported: string } = null;
Expand Down Expand Up @@ -92,6 +94,10 @@ export class EntryLive implements AfterViewInit, OnInit, OnDestroy {
this._liveAnalytics.open();
}
}
public openLoaLatencyHelp(): void {
this._lowLatencyHelp.open();
this._lowLatencyHelp.popup.nativeElement.style.opacity = 1;
}

public _generateSip(): void {
if (this._selectedSipSource) {
Expand All @@ -110,5 +116,10 @@ export class EntryLive implements AfterViewInit, OnInit, OnDestroy {
});
}
}

public openLowLatencyLink(): void {
this._browserService.openLink(serverConfig.externalLinks.live.lowLatency);
this._lowLatencyHelp.close();
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ export class CreateLiveComponent implements OnInit, OnDestroy, AfterViewInit {
liveDVR: false,
enableRecording: this._permissionsService.hasPermission(KMCPermissions.FEATURE_LIVE_STREAM_RECORD),
enableRecordingSelectedOption: KalturaRecordStatus.appended,
previewMode: false
previewMode: false,
lowLatency: false
};
public manualLiveData: ManualLive = {
name: '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export class CreateLiveService {
name: data.name,
application: KalturaEntryApplication.kmc,
applicationVersion: globalConfig.client.appVersion,
adminTags: data.lowLatency ? 'lowlatency' : '',
sourceVersion: 'create_live',
description: data.description,
recordStatus: data.enableRecording ? data.enableRecordingSelectedOption : KalturaRecordStatus.disabled,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<k-area-blocker [showLoader]="_isBusy" [message]="_blockerMessage">
<form [formGroup]="_form" novalidate class="kContent">
<form [formGroup]="_form" novalidate class="kContent" #popup>
<section class="kFormContainer">
<div class="kFormSection">

Expand Down Expand Up @@ -77,7 +77,27 @@
</div>
</div>

<div class="kRow">
<span class="kLabel kInputSwitchLabel">{{'applications.upload.prepareLive.kalturaStreamType.lowLatency' | translate}}</span>
<div class="kRequired"></div>
<div>
<p-inputSwitch class="kControl kInputSwitch" formControlName="lowLatency"></p-inputSwitch>
<span>{{_form.controls['lowLatency'].value ? ( 'app.common.on' | translate) : ( 'app.common.off' | translate)}}</span>
<i #helpTip class="kIconhelp_full kHelpTip"></i>
</div>
</div>

</div>
</section>
</form>
</k-area-blocker>

<kPopupWidget data-aid="helpTip" [popupWidth]="410" [targetRef]="helpTip" [appendTo]="popup" [targetOffset]="{'x':0, 'y': 24}" [closeBtn]="false">
<div class="kTooltip">
<div class="content1">
<span>{{'applications.upload.prepareLive.kalturaStreamType.lowLatencyHelp1' | translate}}</span>
<a (click)="openLowLatencyLink()">{{'applications.upload.prepareLive.kalturaStreamType.lowLatencyHelp2' | translate}}</a>
</div>
<span>{{'applications.upload.prepareLive.kalturaStreamType.lowLatencyHelp3' | translate}}</span>
</div>
</kPopupWidget>
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,32 @@
opacity: 0.35;
cursor: default;
}
.kRow {
position: relative;
.kHelpTip {
position: absolute;
padding-top: 4px;
font-size: 15px;
margin-left: 8px;
cursor: pointer;
&:hover{
color: $kSecondary;
}
}
}
.kTooltip {
padding: 24px;
box-sizing: border-box;
display: flex;
flex-direction: column;
span, a {
white-space: nowrap;
}
.content1 {
display: flex;
margin-bottom: 4px;
a {
margin-left: 4px;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {BrowserService} from 'app-shared/kmc-shell';
import {KalturaLive} from './kaltura-live-stream.interface';
import { cancelOnDestroy, tag } from '@kaltura-ng/kaltura-common';
import {KMCPermissions, KMCPermissionsService} from 'app-shared/kmc-shared/kmc-permissions';
import {serverConfig} from "config/server";

@Component({
selector: 'kKalturaLiveStream',
Expand Down Expand Up @@ -119,7 +120,8 @@ export class KalturaLiveStreamComponent implements OnInit, OnDestroy {
liveDVR: false,
enableRecording: [{value: false, disabled: !canRecordLive}],
enableRecordingSelectedOption: [{value: '', disabled: true}],
previewMode: false
previewMode: false,
lowLatency: false
});

this._form
Expand All @@ -145,4 +147,8 @@ export class KalturaLiveStreamComponent implements OnInit, OnDestroy {
this._isBusy = isBusy;
this._blockerMessage = message;
}

public openLowLatencyLink(): void {
this._browserService.openLink(serverConfig.externalLinks.live.lowLatency);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ export interface KalturaLive {
liveDVR: boolean,
enableRecording: boolean,
enableRecordingSelectedOption: KalturaRecordStatus,
previewMode: boolean
previewMode: boolean,
lowLatency: boolean
}
3 changes: 2 additions & 1 deletion src/configuration/server-config-example.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
"bulkUploadSamples": "http://kmc.kaltura.com/content/docs/kaltura_batch_upload_sample.zip"
},
"live": {
"akamaiEdgeServerIpURL": "kalvodhds-i.akamaihd.net/serverIp"
"akamaiEdgeServerIpURL": "kalvodhds-i.akamaihd.net/serverIp",
"lowLatency": "https://knowledge.kaltura.com/help/low-latency-streaming-guidelines"
}
}
}
3 changes: 2 additions & 1 deletion src/configuration/server-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ export interface ServerConfig {
bulkUploadSamples?: string
},
live?: {
akamaiEdgeServerIpURL?: string
akamaiEdgeServerIpURL?: string,
lowLatency?: string
}
};
}
Expand Down
5 changes: 5 additions & 0 deletions src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,10 @@
"appended": "Append recorded content to a single entry"
},
"previewMode": "Preview Mode",
"lowLatency": "Low Latency (Beta)",
"lowLatencyHelp1": "Follow instructions on this",
"lowLatencyHelp2": "Knowledge Center article",
"lowLatencyHelp3": "to make sure Low Latency works correctly",
"errors": {
"required": "This field is required."
}
Expand Down Expand Up @@ -1880,6 +1884,7 @@
"dvrWindow": "DVR Window:",
"activeRec": "Recording:",
"previewMode": "Preview Mode:",
"lowLatency": "Low Latency (Beta):",
"rtsp": "RTSP Broadcasting URLs",
"srt": "SRT Broadcasting URLs",
"primarySRTid": "Primary Stream ID:",
Expand Down

0 comments on commit 87f6a88

Please sign in to comment.