Twilio可编程视频和Ionic 3-音频问题

时间:2018-12-05 04:48:10

标签: typescript ionic-framework ionic3 twilio twilio-video

我正在开发必须实现Twilio可编程视频的移动应用程序。我已经在Laravel PHP Framework中使用Twilio SDK 5.24.2开发了一个后端,并且运行良好。

在移动应用程序中,我通过npm安装了twilio-video 2.0.0-beta4软件包,并基于“ video-quickstart-js-1.x”中的示例开发了一个页面。问题是,当Twilio尝试连接到会议室时,控制台中的错误如下(在日志末尾):

INFO in [connect #1]: Connecting to a Room
DEBUG in [connect #1]: Options: Object
INFO in [NTSIceServerSource #1]: Created a new NTSIceServerSource
DEBUG in [NTSIceServerSource #1]: ECS server: https://ecs.us1.twilio.com
INFO in [connect #1]: LocalTracks were not provided, so they will be acquired automatically before connecting to the Room. LocalTracks will be released if connecting to the Room fails or if the Room is disconnected
WARN in [createLocalTracks #1]: Call to getUserMedia failed: DOMException: Could not start audio source
INFO in [connect #1]: Error while connecting to a Room: DOMException: Could not start audio source

我在Ionic中的代码如下:

import { Component, ViewChild } from '@angular/core';
import { IonicPage, NavController, NavParams, LoadingController } from 'ionic-angular';
import { ApiServiceProvider } from '../../providers/api-service';
import TwilioVideo from 'twilio-video';

export class VideoPage
{
  public roomSid: string;
  public activeRoom: any;
  public twilioAccessToken: string;

  @ViewChild('remoteMedia') remoteMedia: any;
  @ViewChild('localMedia') localMedia: any;
  @ViewChild('buttonLeave') buttonLeave: any;

  constructor(
    public navCtrl: NavController, 
    public navParams: NavParams,
    private apiServiceProvider: ApiServiceProvider
  ) {
    this.roomSid = navParams.get('room_sid');
    this.joinToRoom(this.roomSid);
  }

  joinToRoom(roomSid: string) {
    let videoCallData = {
      room_sid: roomSid
    };

    this.apiServiceProvider.joinVideoRoom(videoCallData)
    .then(
      (result) => {
        this.twilioAccessToken = result.access_token;
        this.generateVideoCall();
      },
      (error) => {
        console.log(error);
      }
    )
    .catch((error) => {
      console.log(error);
    });
  }

  generateVideoCall() {
    let connectOptions = {
      name: this.roomSid,
      video: true,
      audio:true
    };

    connectOptions['logLevel'] = 'debug';

    TwilioVideo.connect(this.twilioAccessToken, connectOptions)
    .then(this.roomJoined, function(error) {
      console.log('Could not connect to Twilio: ' + error.message);
    });
  }

  roomJoined(room: any) {
    this.activeRoom = room;

    // Attach LocalParticipant's Tracks, if not already attached.
    var previewContainer = this.localMedia;
    if (!previewContainer.querySelector('video')) {
      this.attachParticipantTracks(this.activeRoom.localParticipant, previewContainer);
    }

    // Attach the Tracks of the Room's Participants.
    this.activeRoom.participants.forEach(function(participant) {
      console.log("Already in Room: '" + participant.identity + "'");
      let previewContainer = this.remoteMedia;
      this.attachParticipantTracks(participant, previewContainer);
    });

    // When a Participant joins the Room, log the event.
    this.activeRoom.on('participantConnected', function(participant) {
      console.log("Joining: '" + participant.identity + "'");
    });

    // When a Participant adds a Track, attach it to the DOM.
    this.activeRoom.on('trackAdded', function(track, participant) {
      console.log(participant.identity + " added track: " + track.kind);
      var previewContainer = this.remoteMedia;
      this.attachTracks([track], previewContainer);
    });

    // When a Participant removes a Track, detach it from the DOM.
    this.activeRoom.on('trackRemoved', function(track, participant) {
      console.log(participant.identity + " removed track: " + track.kind);
      this.detachTracks([track]);
    });

    // When a Participant leaves the Room, detach its Tracks.
    this.activeRoom.on('participantDisconnected', function(participant) {
      console.log("Participant '" + participant.identity + "' left the room");
      this.detachParticipantTracks(participant);
    });

    // Once the LocalParticipant leaves the room, detach the Tracks of all Participants, including that of the LocalParticipant.
    this.activeRoom.on('disconnected', function() {
      console.log('Left room');

      if (this.previewTracks) {
        this.previewTracks.forEach(function(track) {
          track.stop();
        });
        this.previewTracks = null;
      }

      this.detachParticipantTracks(this.activeRoom.localParticipant);
      this.activeRoom.participants.forEach(this.detachParticipantTracks);
    });
  }

  // Attach the Participant's Tracks to the DOM.
  attachParticipantTracks(participant, container) {
    var tracks = Array.from(participant.tracks.values());
    this.attachTracks(tracks, container);
  }

  // Attach the Tracks to the DOM.
  attachTracks(tracks, container) {
    tracks.forEach(function(track) {
      container.appendChild(track.attach());
    });
  }

  // Detach the Tracks from the DOM.
  detachTracks(tracks) {
    tracks.forEach(function(track) {
      track.detach().forEach(function(detachedElement) {
        detachedElement.remove();
      });
    });
  }

  // Detach the Participant's Tracks from the DOM.
  detachParticipantTracks(participant) {
    var tracks = Array.from(participant.tracks.values());
    this.detachTracks(tracks);
  }

  // Leave Room.
  leaveRoomIfJoined() {
    if (this.activeRoom) {
      this.activeRoom.disconnect();
    }
  }
}

HTML具有下一个结构:

<ion-content padding>
  <div #remoteMedia></div>

  <div #localMedia></div>

  <div id="buttonContainer">
    <button ion-button icon-only round #buttonLeave (click)="leaveCall($event)">
      <ion-icon name="close"></ion-icon>
    </button>
  </div>
</ion-content>

我已经安装了cordova-plugin-media-capture插件,并在config.xml中分配了此权限

<config-file parent="/*" target="AndroidManifest.xml">
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
</config-file>

我想念什么?

谢谢。

0 个答案:

没有答案