【问题标题】:Twilio Remote video from Safari iPhone showing black-screen in Angular 5来自 Safari iPhone 的 Twilio Remote 视频在 Angular 5 中显示黑屏
【发布时间】:2020-04-14 19:16:23
【问题描述】:

iPhone Safari 版本:11.2.5

Chrome 版本:检查更新版本 80.0.3987.163(官方构建)(64 位)

连接是点对点的。

If I can give you an overview it's like -

Video is coming on iPhone from mac safari, Chrome, window laptop
Video is coming on Android Phone from mac safari, Chrome, window laptop
Video is coming on mac safari, Chrome, window laptop from Android Phone

Video is NOT COMING on mac safari, Chrome, window laptop from iPhone

如果您能提供帮助,请告诉我。提前致谢。

【问题讨论】:

    标签: ios angular twilio twilio-video


    【解决方案1】:

    我解决了这个问题

    createLocalVideoTrack({
          video: { width: 1280, height: 720 },
        }).then(track => {
          if (this.localVideo) {
            const element = track.attach();
            this.renderer.data.id = track.sid;
            this.renderer.setStyle(element, 'width', '25%');
            this.renderer.appendChild(this.localVideo.nativeElement, element);
            this.attachVideoClass();
          }
        });
    

    应该是:

       this.roomObj.localParticipant.videoTracks.forEach(publication => {
          const element = publication.track.attach();
          this.renderer.data.id = publication.track.sid;
          this.renderer.setStyle(element, 'width', '25%');
          this.renderer.appendChild(this.localVideo.nativeElement, element);
        })
    

    【讨论】:

    • 出于某些恼人的原因,Twilio 继续在其示例代码中发布“createLocalVideoTrack”方法,但它不适用于 ios——从 iOS 接收视频流的浏览器客户端只显示一个黑框.您的解决方案对我有用 - 谢谢 - 它让我发疯,我花了很长时间才找到它!
    【解决方案2】:

    这里是 Twilio 开发者宣传员。

    我建议通读developing for Safari 11 article,它解决了一系列潜在问题。

    【讨论】:

    • 我已经检查过了...我正在接收音频,但如果是视频,则会出现唯一的黑屏。
    • 您使用的 Chrome 浏览器是在桌面上使用的吗?您使用的是哪个版本的 Twilio Video?使用 iOS Safari 13 进行测试时,您发现您的代码有效吗?
    • Chrome 浏览器在桌面上,我使用的是 Twilio-video v2.3.0。我用 iOS Safari 13 声音测试过,黑屏来了。
    • 你能分享你用来连接的代码吗?我在 iOS Safari 上连接到 Twilio Video 没有问题,所以我想知道您在做什么不同。
    • 您使用的是哪个版本的 Twilio Video?
    【解决方案3】:

    请检查代码:

    import { Injectable, EventEmitter, ElementRef, Renderer2, RendererFactory2 } from '@angular/core';
    import { Observable } from 'rxjs/Observable';
    import { Observer } from 'rxjs';
    import { connect, createLocalTracks, createLocalVideoTrack } from 'twilio-video';
    import { BehaviorSubject } from 'rxjs/BehaviorSubject';
    import { Http } from '@angular/http';
    import { Router } from '@angular/router';
    import { BaCustomPreLoader } from './baCustomPreloader.service';
    
    
    @Injectable()
    export class TwilioService {
    
      remoteVideo: ElementRef;
      localVideo: ElementRef;
      previewing: boolean;
      msgSubject = new BehaviorSubject("");
      roomObj: any;
    
      roomParticipants;
    
      private renderer: Renderer2;
      constructor(
        private http: Http,
        private router: Router,
        private rendererFactory: RendererFactory2,
        private baCustomPreLoader: BaCustomPreLoader) {
        this.renderer = rendererFactory.createRenderer(null, null);
      }
    
      getToken(username): Observable<any> {
        return this.http.post('/abc', { uid: 'ashish' });
      }
    
      microphone = true;
    
      mute() {
        this.roomObj.localParticipant.audioTracks.forEach(function (
          audioTrack
        ) {
          audioTrack.track.disable();
        });
        this.microphone = false;
      }
    
    
      unmute() {
        this.roomObj.localParticipant.audioTracks.forEach(function (
          audioTrack,
          key,
          map
        ) {
          audioTrack.track.enable();
        });
        this.microphone = true;
      }
    
    
      connectToRoom(accessToken: string, options): void {
        connect(accessToken, options).then(room => {
          this.roomObj = room;
    
          if (!this.previewing && options['video']) {
            this.startLocalVideo();
            this.previewing = true;
          }
    
          this.roomParticipants = room.participants;
          room.participants.forEach(participant => {
            this.attachParticipantTracks(participant);
          });
    
          room.on('participantDisconnected', (participant) => {
            this.detachParticipantTracks(participant);
          });
    
          room.on('participantConnected', (participant) => {
            this.roomParticipants = room.participants;
            this.attachParticipantTracks(participant);
    
            participant.on('trackAdded', track => {
    
              const element = track.attach();
              this.renderer.data.id = track.sid;
              this.renderer.setStyle(element, 'height', '100%');
              this.renderer.setStyle(element, 'max-width', '100%');
              this.renderer.appendChild(this.remoteVideo.nativeElement, element);
              this.attachVideoClass();
              this.baCustomPreLoader.hide();
            });
          });
    
          // When a Participant adds a Track, attach it to the DOM.
          room.on('trackAdded', (track, participant) => {
            this.attachTracks([track]);
          });
    
          // When a Participant removes a Track, detach it from the DOM.
          room.on('trackRemoved', (track, participant) => {
            this.detachTracks([track]);
          });
    
          room.once('disconnected', room => {
            room.localParticipant.tracks.forEach(track => {
              track.track.stop();
              const attachedElements = track.track.detach();
              attachedElements.forEach(element => element.remove());
              room.localParticipant.videoTracks.forEach(video => {
                const trackConst = [video][0].track;
                trackConst.stop();  // <- error
    
                trackConst.detach().forEach(element => element.remove());
    
                room.localParticipant.unpublishTrack(trackConst);
              });
    
    
    
              let element = this.remoteVideo.nativeElement;
              while (element.firstChild) {
                element.removeChild(element.firstChild);
              }
              let localElement = this.localVideo.nativeElement;
              while (localElement.firstChild) {
                localElement.removeChild(localElement.firstChild);
              }
              this.router.navigate(['thanks']);
              setTimeout(() => {
                window.location.reload();
              }, 1000)
            });
    
          });
        }, (error) => {
          alert(error.message);
        });
      }
    
      attachParticipantTracks(participant): void {
        participant.tracks.forEach(part => {
          this.trackPublished(part);
        });
      }
    
      trackPublished(publication) {
        if (publication.isSubscribed)
          this.attachTracks(publication.track);
    
        if (!publication.isSubscribed)
          publication.on('subscribed', track => {
            this.attachTracks(track);
          });
      }
    
      attachTracks(tracks) {
    
        const element = tracks.attach();
        this.renderer.data.id = tracks.sid;
        this.renderer.setStyle(element, 'height', '100%');
        this.renderer.setStyle(element, 'max-width', '100%');
        this.renderer.appendChild(this.remoteVideo.nativeElement, element);
        this.attachVideoClass();
        this.baCustomPreLoader.hide();
      }
    
      startLocalVideo(): void {
        createLocalVideoTrack({
          video: { width: 1280, height: 720 },
        }).then(track => {
          if (this.localVideo) {
            const element = track.attach();
            this.renderer.data.id = track.sid;
            this.renderer.setStyle(element, 'width', '25%');
            this.renderer.appendChild(this.localVideo.nativeElement, element);
            this.attachVideoClass();
          }
        });
      }
    
      detachParticipantTracks(participant) {
        this.detachTracks(participant);
      }
    
      detachTracks(tracks): void {
        tracks.tracks.forEach(track => {
          let element = this.remoteVideo.nativeElement;
          while (element.firstChild) {
            element.removeChild(element.firstChild);
          }
        });
      }
    
      attachVideoClass() {
        let remote = document.getElementById('remote');
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-11-29
      • 2020-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多