Cannot play MP4 video in Angular 7

Viewed 4691

I have 2 days dealing with a weird issue about a mp4 video in angular 7. For some reason the MP4 video simply does not play.

This is my code:

HTML:

<div id="instructions" class="angled-img pull-left">
        <video allow="autoplay" width="350px" height="195px" class="img" controls
          poster='{{gameInfo.clip.preview}}'>
          <source src="{{gameInfo.clip.clip}}" type='video/mp4' />
        </video>
      </div>

TS:

public gameInformation(id: number): void {
this.gameService.getGame(id).subscribe(res => {
  this.gameInfo = res;
  console.log(res);
  this.loader = false;
}, error => {
  console.error(error);
  this.loader = false;
});
}

I am not sure why this is happening. Can somebody help me out? What I am doing wrong. I am using ngx-bootstrap for this.

Thanks in advance.

2 Answers

I am able to play video in the promise. Use these attributes in the Video tag "muted" and "autoplay".

Also I have created stackblitz example where I am calling a fake http call and I am trying to play sample video. Please use ngIf="gameInfo" in your video tag to make sure your response data is available before rendering your video. Also you can wrap the video play inside setTimeout to make sure video tag is rendered in the page.

Here is the stackblitz working example.

Play Video using angular

app.component.html

<hello name="{{ name }}"></hello>
<p>
  Start editing to see some magic happen :)
</p>

<div id="instructions" class="angled-img pull-left">
        <video muted autoplay  *ngIf="videoData" id="video1"  width="350px" height="195px" class="img" controls
         >
          <source src="{{videoData.url}}" type='video/mp4' />
        </video>
      </div>

app.component.ts

import { Component,OnInit } from '@angular/core';
import { VideoService } from './video.service';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit  {
  name = 'Angular';
  videoData: any = {};

  constructor(private videoService: VideoService) {

  }

  ngOnInit() {
    this.videoService.getVideo().subscribe(data => {
        this.videoData = data;
        this.videoData.url = 'https://www.w3schools.com/html/mov_bbb.mp4';
        setTimeout(() => {
            document.getElementById('video1').play();
        }, 1000);
    }, (error) => {
        this.videoData.url = 'https://www.w3schools.com/html/mov_bbb.mp4';
        setTimeout(() => {
  document.getElementById('video1').play();
        }, 1000);
      
      console.log('error', error)
    })
  }
}

video.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';

import { map } from 'rxjs/operators'

@Injectable()
export class VideoService {
   private httpOptions = {
    headers: new HttpHeaders({
      'Content-Type':  'application/json'
    })
  };

  url: string;
  constructor(private http: HttpClient) { 
    this.url = 'http://my-json-server.typicode.com/kodecrash/Javascript/video/1';
  }

  getVideo() {
    return this.http.get<any>(this.url, this.httpOptions)
    .pipe(map( (data: any) => {
      // login successful if there's a jwt token in the response
      return data;
    }));
  }

}

The problem is that chrome has disabled autoplay of videos containing sound, so, you need to use muted and autoplay attributes. Still, it is possible that video does not autoplay because you need to write muted before autoplay to make the autoplay work but during compilation, angular arranges attributes in alphabetical order. So, 1 good solution I found was:

<video autoplay onloadedmetadata="this.muted = true" oncanplay="this.play()">
    <source [src]="gameinfo.clip.clip" type="video/mp4" />
</video>

This way the video will autoplay in angular without changing anything in the typescript file.

Related