I have implemented Twilio Video on Angular using this tutorial: https://www.twilio.com/blog/video-chat-app-asp-net-core-angular-twilio
It is worth mentioning that I ran into a problem earlier where I wasn't able to show or receive any video through safari browser. I fixed that issue by downgrading my zone.js version to 1.0.82.
Now that the video was displaying correctly on all browsers including safari on Mac, now I am testing on iOS safari.
The issue: Local Video (Video from iphone camera) is not showing on iOS safari. However remote video does show. And on the other end, both the remote and local video is showing perfectly.
Twilio video on all browsers except safari iOS
Twilio video on safari iOS
Camera View (html):
<div id="preview" #preview>
<div *ngIf="isInitializing">Camera is initializing</div>
</div>
Camera TS (camera.ts)
import { Component, ElementRef, ViewChild, AfterViewInit, Renderer2 } from '@angular/core';
import { createLocalTracks, LocalTrack, LocalVideoTrack } from 'twilio-video';
@Component({
selector: 'app-camera',
templateUrl: './camera.component.html',
styleUrls: ['./camera.component.scss']
})
export class CameraComponent implements AfterViewInit {
@ViewChild('preview', { read: "", static: false }) previewElement: ElementRef;
get tracks(): LocalTrack[] {
return this.localTracks;
}
isInitializing: boolean = true;
videoTrack: LocalVideoTrack;
localTracks: LocalTrack[] = [];
constructor(
private readonly renderer: Renderer2) { }
async ngAfterViewInit() {
}
initializePreview(deviceInfo?: MediaDeviceInfo) {
if (deviceInfo) {
this.initializeDevice(deviceInfo.kind, deviceInfo.deviceId);
} else {
this.initializeDevice();
}
}
finalizePreview() {
try {
if (this.videoTrack) {
this.videoTrack.detach().forEach(element => element.remove());
}
} catch (e) {
console.error(e);
}
}
private async initializeDevice(kind?: MediaDeviceKind, deviceId?: string) {
try {
this.isInitializing = true;
this.finalizePreview();
this.localTracks = kind && deviceId
? await this.initializeTracks(kind, deviceId)
: await this.initializeTracks();
this.videoTrack = this.localTracks.find(t => t.kind === 'video') as LocalVideoTrack;
let videoElement = this.videoTrack.attach();
this.renderer.setStyle(videoElement, 'height', '100%');
this.renderer.setStyle(videoElement, 'width', '100%');
this.renderer.appendChild(this.previewElement.nativeElement, videoElement);
} finally {
this.isInitializing = false;
}
}
private initializeTracks(kind?: MediaDeviceKind, deviceId?: string) {
if (kind) {
switch (kind) {
case 'audioinput':
return createLocalTracks({ audio: { deviceId }, video: true });
case 'videoinput':
return createLocalTracks({ audio: true, video: { deviceId } });
}
}
return createLocalTracks({ audio: true, video: true });
}
}
This code is available here