4
votes

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

2

2 Answers

3
votes

I finally managed to fix the problem. I will post this for anyone who runs into this issue.

What the underlying problem was? The problem is that although laptop and macbook and some phone browsers allow you to create multiple webcams, the browsers on iphone, don't.

What I did to solve this problem? What I did was to use the camera which the twilio uses to create or connect to a room. What I was doing wrong was that I was creating a second webcam layer and accessing my webcam from there. (This is a fault in twilio's code, not mine). So basically all I did was this:

room.localParticipant.tracks.foreach((a=>any)=>{if(a.kind=="video"){videoelement=a.track}})
1
votes
import 'zone.js/dist/zone-patch-user-media';
import 'zone.js/dist/webapis-rtc-peer-connection';

These polyfills solved my problem.