Angular 中 video 自动静音播放

在页面里面加了一个 video,想让这个视频在页面加载之后自动播放,用下面的写法:

1
2
3
4
5
6
7
8
9
10
11
 <video
id="officeVideo"
preload="metadata"
poster="assets/media/office.jpg"
playsinline
autoplay
muted
loop
>
<source src="assets/media/office.mp4" type="video/mp4" />
</video>

但是在谷歌浏览器下测试,发现第一次可以自动播放,再刷新就暂停了,很奇怪,网上找了一些解决方案开始尝试,例如下面的代码用 jQuery 找到这个 video 元素,手动调用 play 函数:

1
2
3
const el = $('#officeVideo')
const video = el.get(0)
video.play()

结果报了一个错:

1
Uncaught (in promise) DOMException

莫名其妙的错误,后来查了一下说 play 函数是异步的,返回一个 promise,要这样写:

1
2
3
4
5
6
7
8
9
10
const el = $('#officeVideo')
const video = el.get(0)
const thePromise = video.play()
if (thePromise !== undefined) {
thePromise.then(function() {
video.pause()
video.currentTime = 0
video.play()
})
}

结果发现又报了一个错:

1
ERROR Error: Uncaught (in promise): NotAllowedError: play() failed because the user didn't interact with the document first. https://goo.gl/xX8pDD

说不能在用户没有主动触发的情况下自动播放视频,我试了一下:

1
2
3
$('.play-btn').click(function() {
video.paused ? video.play() : video.pause()
})

这样当用户点击之后,视频确实可以播放了,到底如何才能实现自动播放的目的呢?网上的资料都说,只要加了 autoPlay 和 muted 就能够自动播放,但实践证明这种说法并不可信。经过大量的查询,终于找到了问题的根结所在:

‘muted’ 属性仅在页面初始化的时候才有效,如果视频是动态加载到页面中的,需要在 video 元素添加到 dom 中之后显式设置 video.muted = true 才行

当看到这句话的时候,眼泪差点掉下来了,最终代码:

1
2
3
4
5
6
@ViewChild('officeVideo', { read: ElementRef }) officeVideo: ElementRef

ngAfterViewInit() {
const video: HTMLVideoElement = this.officeVideo.nativeElement
video.muted = true
}