Angular 9实现带进度条的音频播放/暂停功能求助
实现Angular 9基础音频播放/暂停与进度条功能
没问题,我帮你基于原生HTML5 Audio API来实现基础的音频播放功能,不用依赖第三方组件,完全适配你现有的HTML结构。下面是一步步的实现方案:
第一步:组件类(.ts文件)核心逻辑
首先在你的组件类中初始化音频实例,管理播放状态、进度、音量等变量:
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core'; @Component({ selector: 'app-audio-player', templateUrl: './audio-player.component.html', styleUrls: ['./audio-player.component.css'] }) export class AudioPlayerComponent implements OnInit { @ViewChild('myProgress') myProgress!: ElementRef<HTMLProgressElement>; audioInstance!: HTMLAudioElement; isPlaying = false; currentTime = 0; duration = 0; volume = 1; volumeIcon = 'ion-md-volume-high'; song: any; // 假设你的song对象包含audio_url字段 ngOnInit(): void { // 初始化音频实例 this.audioInstance = new Audio(); // 监听音频加载完成事件,获取总时长 this.audioInstance.addEventListener('loadedmetadata', () => { this.duration = this.audioInstance.duration; }); // 监听播放进度变化,实时更新当前时间 this.audioInstance.addEventListener('timeupdate', () => { this.currentTime = this.audioInstance.currentTime; }); // 监听缓冲进度变化 this.audioInstance.addEventListener('progress', () => { if (this.audioInstance.buffered.length > 0) { const bufferedEnd = this.audioInstance.buffered.end(this.audioInstance.buffered.length - 1); this.myProgress.nativeElement.value = bufferedEnd; this.myProgress.nativeElement.max = this.duration || 1; } }); // 播放结束后重置状态 this.audioInstance.addEventListener('ended', () => { this.isPlaying = false; }); } // 播放/暂停切换 play(song: any): void { this.song = song; // 如果当前播放的不是这首歌,切换音频源 if (this.audioInstance.src !== song.audio_url) { this.audioInstance.src = song.audio_url; this.audioInstance.load(); } if (this.isPlaying) { this.audioInstance.pause(); this.isPlaying = false; } else { this.audioInstance.play(); this.isPlaying = true; } } // 格式化时间:秒转分:秒 formatTime(seconds: number): string { const mins = Math.floor(seconds / 60); const secs = Math.floor(seconds % 60); return `${mins}:${secs.toString().padStart(2, '0')}`; } // 拖动进度条跳转播放位置 seekTo(event: Event): void { const target = event.target as HTMLInputElement; const seekTime = Number(target.value); this.audioInstance.currentTime = seekTime; } // 调整音量并更新图标 changeVolumeIcon(event: Event): void { const target = event.target as HTMLInputElement; this.volume = Number(target.value) / 100; this.audioInstance.volume = this.volume; // 更新音量图标 if (this.volume === 0) { this.volumeIcon = 'ion-md-volume-off'; } else if (this.volume < 0.5) { this.volumeIcon = 'ion-md-volume-low'; } else { this.volumeIcon = 'ion-md-volume-high'; } } // 其他辅助方法(按需实现) prevSong(): void { // 这里实现上一首逻辑 } nextSong(): void { // 这里实现下一首逻辑 } toggleRepeat(): void { // 这里实现循环逻辑 } toggleShuffle(): void { // 这里实现随机逻辑 } openPlaylist(): void { // 你的播放列表打开逻辑 } }
第二步:修改HTML模板
把你现有的HTML模板中的amplitude相关属性替换成Angular绑定,关联组件类中定义的变量和方法:
<div id="audioPlayer" [class]="playerClass"> <!-- Begin | Audio Player Progress --> <div id="progress-container"> <input type="range" class="amplitude-song-slider" [value]="currentTime" [max]="duration || 1" (input)="seekTo($event)" > <progress class="audio-progress audio-progress--played amplitude-song-played-progress" [value]="currentTime" [max]="duration || 1" ></progress> <progress id="myProgress" class="audio-progress audio-progress--buffered amplitude-buffered-progress" #myProgress ></progress> </div> <!-- End | Audio Player Progress --> <!-- Begin | Audio --> <div class="audio"> <div class="song-image"> <img [src]="song?.cover_art_url" alt="{{song?.name}}"> </div> <div class="song-info pl-3"> <span class="song-name d-inline-block text-truncate">{{song?.name}}</span> <span class="song-artists d-block text-muted">{{song?.artist}}</span> </div> </div> <!-- End | Audio --> <!-- Begin | Audio Controls --> <div class="audio-controls"> <div class="audio-controls--left d-flex mr-auto"> <button class="btn btn-icon-only amplitude-repeat" (click)="toggleRepeat()"> <i class="ion-md-sync"></i> </button> </div> <div class="audio-controls--main d-flex"> <button class="btn btn-icon-only amplitude-prev" (click)="prevSong()"> <i class="ion-md-skip-backward"></i> </button> <button class="btn btn-air btn-pill btn-default btn-icon-only amplitude-play-pause" (click)="play(song)" > <i class="ion-md-play" *ngIf="!isPlaying"></i> <i class="ion-md-pause" *ngIf="isPlaying"></i> </button> <button class="btn btn-icon-only amplitude-next" (click)="nextSong()"> <i class="ion-md-skip-forward"></i> </button> </div> <div class="audio-controls--right d-flex ml-auto"> <button class="btn btn-icon-only amplitude-shuffle amplitude-shuffle-off" (click)="toggleShuffle()"> <i class="ion-md-shuffle"></i> </button> </div> </div> <!-- End | Audio Controls --> <!-- Begin | Audio Info --> <div class="audio-info d-flex align-items-center pr-4"> <span class="mr-4"> {{formatTime(currentTime)}} / {{formatTime(duration)}} </span> <div class="audio-volume dropdown"> <button class="btn btn-icon-only" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <i [class]="volumeIcon"></i> </button> <div class="dropdown-menu dropdown-menu-right volume-dropdown-menu"> <input type="range" class="amplitude-volume-slider" [value]="volume * 100" (change)="changeVolumeIcon($event)" > </div> </div> <!-- Song options --> <app-song-options [icon]="'la-ellipsis-v'" [song]="song"></app-song-options> <button class="btn btn-icon-only" (click)="openPlaylist()"> <i class="ion-md-musical-note"></i> </button> </div> <!-- End | Audio Info --> </div> <!-- End | Audio Player -->
关键功能说明
- 播放/暂停:通过
HTMLAudioElement的play()和pause()方法实现,同时切换按钮图标和isPlaying状态。 - 进度条更新:监听
timeupdate事件实时获取当前播放时间,绑定到进度条的value属性;总时长在loadedmetadata事件中获取。 - 缓冲进度:监听
progress事件获取已缓冲的音频长度,更新缓冲进度条。 - 进度拖拽:拖动range输入框时,通过
seekTo方法设置音频的currentTime实现跳转。 - 音量控制:调整range值时更新音频的
volume属性,并根据音量大小切换图标。
这样就完成了基础的音频播放功能,完全基于Angular和原生API,不需要依赖第三方组件。你可以根据自己的需求进一步扩展上一首、下一首、循环、随机等功能。
内容的提问来源于stack exchange,提问作者Alexis Lapeze
相关产品推荐
相关产品推荐

