首页 > 解决方案 > Twilio 可编程视频在 ionic 4 中不可见

问题描述

我正在尝试使用 Twilio 视频实现视频通话,此处连接但提供 Twilio 访问令牌。

我获得了访问令牌,但本地房间(本地摄像头预览视频不可见),我正在尝试连接远程视频。远程视频也已连接,但未显示在移动屏幕上。

HTML

<ion-content  #scrollArea fullscreen>

<div id="video-container">

  <div id="local" #localVideo>
    <p>local video</p>
  </div>

  <div id="remote" #remoteVideo>
    <p>remote video</p>
  </div>
  <input type="text" [(ngModel)]="username" placeholder="username">

  <input type="text" [(ngModel)]="roomName" placeholder="room name">

  <input type="button" [disabled]="!username || !roomName ? true : false" value="connect" (click)="connect()">

  <input type="button" [disabled]="!twilioService.roomObj ? true : false" value="disconnect" (click)="disconnect()">

</div>

</ion-content>

ts

import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { TwiliovideoService } from '../_service/twiliovideo.service';
import { ServiceProxy, ServiceRegistry } from '../_helpers/ServiceProxy';
import { IonContent } from '@ionic/angular';
import { async } from '@angular/core/testing';

@Component({
  selector: 'app-videocall',
  templateUrl: './videocall.component.html',
  styleUrls: ['./videocall.component.scss'],
})
export class VideocallComponent implements OnInit {

  message1: string;
  accessToken: string;
  roomName: string;
  username: string;
  @ViewChild('scrollArea') content: IonContent;
  @ViewChild('localVideo') localVideo: ElementRef;
  @ViewChild('remoteVideo') remoteVideo: ElementRef;

  video_token: any;



  constructor(public twilioService: TwiliovideoService,public serviceProxy: ServiceProxy,) {

    this.twilioService.msgSubject.subscribe(r => {
      this.message1 = r;
    });

   }

  ngOnInit() {

    this.twilioService.localVideo = this.localVideo;
    this.twilioService.remoteVideo = this.remoteVideo;
    // this.connect();
  }

  //Video call

  log(message) {
    this.message1 = message;
  }

  disconnect() {
    if (this.twilioService.roomObj && this.twilioService.roomObj !== null) {
      this.twilioService.roomObj.disconnect();
      this.twilioService.roomObj = null;
    }
  }


  async connect() {
    let date = Date.now();
    let video_start = {
      userName: this.username,
      roomName: this.roomName
    }
    console.log(this.roomName)
    await this.serviceProxy.SingleRequest(ServiceRegistry.VIDEOCALL_SESSION,video_start).subscribe(async arg=>{
      this.video_token = arg.result
    });
    console.log(this.video_token)
    // localStorage.setItem('video_token', JSON.stringify({
    //   video_token: this.video_token,
    //   created_at: date
    // }));

    // let storage = JSON.parse(localStorage.getItem('video_token') || '{}');
    // if (!this.roomName || !this.username) { this.message1 = "enter username and room name."; return; }
    // if (storage['video_token'] && storage['created_at'] + 3600000 > date) {
      if(this.video_token){
      this.accessToken = this.video_token
      await this.twilioService.connectToRoom(this.accessToken, { name: this.roomName, audio: true, video: { width: 240 } })

      // return;

    }

    // if (this.video_token!= null)
    //   this.twilioService.connectToRoom(this.accessToken, { name: this.roomName, audio: true, video: { width: 240 } })
  }

  // 



}

服务.ts

import { Injectable, ElementRef } from '@angular/core';
import { connect, createLocalTracks, createLocalVideoTrack } from 'twilio-video';
import { BehaviorSubject } from 'rxjs';


@Injectable({
  providedIn: 'root'
})
export class TwiliovideoService {
  msgSubject = new BehaviorSubject("");
  remoteVideo: ElementRef;
  localVideo: ElementRef;

  previewing: boolean;
  roomObj: any;

  constructor() { }

  connectToRoom(accessToken: string, options): void {


    connect(accessToken, options).then(room => {
      console.log(`Successfully joined a Room: ${room}`);
      if (!this.previewing && options['video']) {
        this.startLocalVideo();
        this.previewing = true;
      }


      // Attach the Participant's Media to a <div> element.
      room.on('participantConnected', participant => {
        console.log(`Participant "${participant.identity}" connected`);

        participant.tracks.forEach(publication => {
          if (publication.isSubscribed) {
            const track = publication.track;
            this.remoteVideo.nativeElement.appendChild(track.attach());
          }
        });

        participant.on('trackSubscribed', track => {
          this.remoteVideo.nativeElement.appendChild(track.attach());
        });
      });

      // Log your Client's LocalParticipant in the Room
      const localParticipant = room.localParticipant;
      console.log(`Connected to the Room as LocalParticipant "${localParticipant.identity}"`);

      // Log any Participants already connected to the Room
      room.participants.forEach(participant => {
        console.log(`Participant "${participant.identity}" is connected to the Room`);
        participant.on('trackSubscribed', track => {
          this.remoteVideo.nativeElement.appendChild(track.attach());
        });

      });

      // Log new Participants as they connect to the Room
      room.once('participantConnected', participant => {
        console.log(`Participant "${participant.identity}" has connected to the Room`);
      });

      // Log Participants as they disconnect from the Room
      room.once('participantDisconnected', participant => {
        console.log(`Participant "${participant.identity}" has disconnected from the Room`);
      });



    }, error => {
      console.error(`Unable to connect to Room: ${error.message}`);
    });

  }

  startLocalVideo(): void {
    createLocalVideoTrack().then(track => {
      this.localVideo.nativeElement.appendChild(track.attach());
    });
  }
}

标签: htmlnode.jsionic-frameworktwilio

解决方案


您需要在 config.xml 和 AndroidManifest.xml 中授予音频和摄像头权限

  1. 安装 android 权限(遵循 ionic 文档)

  2. 在 config.xml 和 AndroidManifest.xml 中添加这些权限

        <custom-config-file parent="/*" target="AndroidManifest.xml">
        <uses-feature android:name="android.hardware.camera" />
        <uses-feature android:name="android.hardware.camera.autofocus" />
        <uses-feature android:name="android.hardware.camera2.full" />
        <uses-feature android:name="android.hardware.camera2.autofocus" />
        <uses-permission android:name="android.permission.CAMERA" />
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.webkit.PermissionRequest" />
        <uses-permission android:name="android.permission.RECORD_AUDIO" />
        <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    </custom-config-file>
    

推荐阅读