Angular15中如何通过VgApiService动态更换ngx-videogular媒体源
解决方案:Angular 15 + ngx-videogular 动态切换视频源
问题根源分析
- 新版本
ngx-videogular已移除VgMedia可实例化类与removeMedia方法,媒体对象由vgMedia指令自动绑定到<video>元素,无法手动创建/移除。 - 你之前的
<source>循环写法错误:用*ngFor遍历所有视频,但每个<source>都绑定同一个currentIndex的源,导致生成多个重复的<source>标签,浏览器只会加载第一个,后续切换不会触发重新加载。
正确实现方案
方案1:单源动态切换(推荐)
适用于每个视频仅需一种格式的场景,直接绑定当前视频的源到单个 <source> 标签,配合 VgApiService 触发媒体刷新。
模板代码
<vg-player (onPlayerReady)="onPlayerReady($event)"> <video #media [vgMedia]="media" preload="auto" autoplay crossorigin> <source [src]="currentVideo.src" [type]="currentVideo.type"> </video> </vg-player> <!-- 示例切换按钮 --> <button (click)="nextVideo()">下一个视频</button>
组件代码
import { Component } from '@angular/core'; import { VgApiService } from '@videogular/ngx-videogular/core'; @Component({ selector: 'app-video-player', templateUrl: './video-player.component.html' }) export class VideoPlayerComponent { // 播放列表数据 videoList = [ { src: 'assets/video1.mp4', type: 'video/mp4' }, { src: 'assets/video2.mp4', type: 'video/mp4' } ]; currentIndex = 0; currentVideo = this.videoList[0]; private api!: VgApiService; onPlayerReady(api: VgApiService) { this.api = api; // 监听视频结束事件,自动切换下一个 this.api.getDefaultMedia().subscriptions.ended.subscribe(() => { this.nextVideo(); }); } nextVideo() { // 更新当前视频索引与源 this.currentIndex = (this.currentIndex + 1) % this.videoList.length; this.currentVideo = this.videoList[this.currentIndex]; // 等待Angular更新DOM后,刷新媒体并播放 setTimeout(() => { this.api.getDefaultMedia().load(); this.api.play(); }, 100); } }
方案2:多源动态切换(兼容多格式)
适用于单个视频需要提供多种格式(如mp4/webm)的场景,动态更新 <source> 列表后刷新媒体。
模板代码
<vg-player (onPlayerReady)="onPlayerReady($event)"> <video #media [vgMedia]="media" preload="auto" autoplay crossorigin> <source *ngFor="let source of currentVideoSources" [src]="source.src" [type]="source.type"> </video> </vg-player>
组件代码
// 其他部分同方案1,仅修改播放列表与切换逻辑 videoList = [ { sources: [ { src: 'assets/video1.mp4', type: 'video/mp4' }, { src: 'assets/video1.webm', type: 'video/webm' } ] }, { sources: [ { src: 'assets/video2.mp4', type: 'video/mp4' }, { src: 'assets/video2.webm', type: 'video/webm' } ] } ]; currentVideoSources = this.videoList[0].sources; nextVideo() { this.currentIndex = (this.currentIndex + 1) % this.videoList.length; this.currentVideoSources = this.videoList[this.currentIndex].sources; // 先卸载旧媒体,再加载新源 this.api.getDefaultMedia().unload(); setTimeout(() => { this.api.getDefaultMedia().load(); this.api.play(); }, 100); }
内容的提问来源于stack exchange,提问作者MichaelE
相关产品推荐
相关产品推荐

