Issues with Video Tag in Ionic

I’m currently running into an issue with HTML5 Video tags in Ionic 3. When the app i’m building is running or built to an iPad the app will, after 17 page loads of a page containing a video tag, stop displaying the video referenced and just offer the play button with a line through it error. Watching the network tab in safari suggests that the video is continuing to be requested and received. The Video tag just fails to play the video.

A test project displaying the issue at hand can be found here: https://github.com/greggarson/VideoTagTest

I’ve been able to reproduce this issue against both WKWebView and UIWebView. Has anyone seen something like this? Any pointers would be greatly appreciated.

1 Like

Managed figure this one out. It appears that the removal of the Page isn’t enough to unload the video from memory, which is probably what was causing the issue.

A snippet like:

ionViewWillLeave() { 
    if(this.videoPlayerElement) { 
        this.videoPlayerElement.nativeElement.pause(); 
        this.videoPlayerElement.nativeElement.src = ''; } 
    }
}

appears to solve the problem.

2 Likes

@greggarson

I created a media component, so in the ngAfterViewInit() I do the following:

  ...

  @ViewChild('video')
  public video: ElementRef;

  private stream: any;

  ...

  public ngAfterViewInit() {

    const constraints = {
      audio: false,
      video: {
        width: { min: 1024, ideal: 1280, max: 1920 },
        height: { min: 776, ideal: 720, max: 1080 },
        facingMode: 'environment'
      }
    };

    if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {

      navigator.mediaDevices.getUserMedia(constraints).then(stream => {
        this.video.nativeElement.src = window.URL.createObjectURL(stream);
        this.stream = stream;
        this.video.nativeElement.play();
      }).catch(function(err) {
        this.logger.error(err.name + ': ' + err.message);
      });

    } else {
      this.logger.error('Your browser does not support the mediaDevices API');
    }
  }

Note: I don’t need audio and I want to use the rear facing camera.

In the ngOnDestroy() I do the following:

  public ngOnDestroy() {

    if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {

      if (this.stream) {
        this.video.nativeElement.pause();
        this.video.nativeElement.src = '';
        this.stream.getTracks().forEach( track => track.stop() );
      }
    }
  }

The Component’s template:

  selector: 'page-media',
  template: `
    <div id="media-container">
      <div id="media">
        <video #video id="video" muted playsinline autoplay></video>
      </div>
    </div>`

And, the Component’s .scss:

  page-media {

    #media-container {
      background-color: black;
      max-width: 1920px;
    }

    #media {
      width: 100%;
    }

    #video {
      width: 100%;
    }

  }

The Page’s markup:

  <ion-content no-bounce class="media-container">

    <ion-grid>
      <ion-row align-items-center>
        <page-media>
        </page-media>
      </ion-row>
    </ion-grid>

  </ion-content>

The Page’s .scss:

    .media-container {

      .scroll-content {
        background-color: black !important;
        display: flex;
        flex-direction: column;
        overflow: hidden;
      }

      ion-grid {
        padding: 0;
        height: 100%;
      }

      ion-row {
        flex: 1;
      }

    }
1 Like

@robinyo Your posts here have always been good, but lately you’ve taken it to the next level. Really good stuff.

@robinyo Thanks for this, looks like the clean up you’re doing is basically the same as mine. I’m not using the mediaDevices API at all right now though, so i’ll take a look at that too to see if it’s any help.