如何在Angular项目中集成Amazon Chime SDK?
Angular集成Amazon Chime SDK完整示例
以下是适配Angular的Amazon Chime SDK基础集成示例,包含会议加入/离开、本地/远程视频渲染的核心功能:
1. 安装依赖
在项目根目录执行命令安装SDK包:
npm install amazon-chime-sdk-js
2. 创建会议组件
生成一个chime-meeting组件,替换以下文件内容:
chime-meeting.component.ts
import { Component, OnInit, ElementRef, ViewChild } from '@angular/core'; import { ConsoleLogger, DefaultDeviceController, DefaultMeetingSession, MeetingSessionConfiguration, AudioVideoFacade, DeviceChangeObserver, MediaDeviceInfo, } from 'amazon-chime-sdk-js'; @Component({ selector: 'app-chime-meeting', templateUrl: './chime-meeting.component.html', styleUrls: ['./chime-meeting.component.css'] }) export class ChimeMeetingComponent implements OnInit, DeviceChangeObserver { @ViewChild('localVideo') localVideo!: ElementRef<HTMLVideoElement>; @ViewChild('remoteVideo') remoteVideo!: ElementRef<HTMLVideoElement>; private meetingSession?: DefaultMeetingSession; private audioVideo?: AudioVideoFacade; private logger = new ConsoleLogger('ChimeMeeting', 'INFO'); meetingId = ''; attendeeId = ''; region = 'us-east-1'; isJoined = false; ngOnInit(): void { // 初始化设备控制器,监听设备变化 const deviceController = new DefaultDeviceController(this.logger); deviceController.addDeviceChangeObserver(this); } async joinMeeting(): Promise<void> { if (!this.meetingId || !this.attendeeId) { alert('请填写会议ID和参会者ID'); return; } this.isJoined = true; // 👇 重要:这里的会议凭证必须从你的后端获取 // 生产环境绝对不能在前端硬编码,示例仅作占位 const meetingCredentials = { Meeting: { MeetingId: this.meetingId, MediaPlacement: { AudioHostUrl: `wss://signal.chime.aws/control/${this.meetingId}`, AudioFallbackUrl: `wss://signal.chime.aws/control/${this.meetingId}`, ScreenDataUrl: `wss://signal.chime.aws/control/${this.meetingId}`, ScreenSharingUrl: `wss://signal.chime.aws/control/${this.meetingId}`, ScreenViewingUrl: `wss://signal.chime.aws/control/${this.meetingId}`, SignalingUrl: `wss://signal.chime.aws/control/${this.meetingId}`, TurnControlUrl: 'https://ccp.cdn.chime.aws' }, MediaRegion: this.region }, Attendee: { AttendeeId: this.attendeeId, ExternalUserId: 'angular-participant', JoinToken: 'YOUR_JOIN_TOKEN_FROM_BACKEND' // 必须替换为后端生成的有效Token } }; try { const config = new MeetingSessionConfiguration( meetingCredentials.Meeting, meetingCredentials.Attendee ); const deviceController = new DefaultDeviceController(this.logger); this.meetingSession = new DefaultMeetingSession(config, this.logger, deviceController); this.audioVideo = this.meetingSession.audioVideo; // 启动本地视频并绑定到DOM元素 await this.audioVideo.startLocalVideo(); this.audioVideo.bindVideoElement(this.localVideo.nativeElement); // 监听远程视频流,绑定到DOM元素 this.audioVideo.addVideoTileObserver({ videoTileDidUpdate: (tile) => { if (!tile.localTile && tile.state === 'active') { this.audioVideo?.bindVideoElement(tile.tileId, this.remoteVideo.nativeElement); } } }); // 正式加入会议 await this.audioVideo.start(); } catch (err) { this.logger.error('加入会议失败:', err); this.isJoined = false; alert('加入失败,请检查凭证是否有效'); } } async leaveMeeting(): Promise<void> { if (this.audioVideo) { await this.audioVideo.stop(); this.meetingSession = undefined; this.audioVideo = undefined; this.isJoined = false; } } // 设备变更监听方法 audioInputsChanged(devices: MediaDeviceInfo[]): void { this.logger.info('音频输入设备更新:', devices); } audioOutputsChanged(devices: MediaDeviceInfo[]): void { this.logger.info('音频输出设备更新:', devices); } videoInputsChanged(devices: MediaDeviceInfo[]): void { this.logger.info('视频输入设备更新:', devices); } }
chime-meeting.component.html
<div class="chime-container"> <div class="input-group"> <label>会议ID</label> <input type="text" [(ngModel)]="meetingId" placeholder="输入会议ID"> </div> <div class="input-group"> <label>参会者ID</label> <input type="text" [(ngModel)]="attendeeId" placeholder="输入参会者ID"> </div> <div class="input-group"> <label>AWS区域</label> <input type="text" [(ngModel)]="region" value="us-east-1"> </div> <button (click)="joinMeeting()" [disabled]="isJoined">加入会议</button> <button (click)="leaveMeeting()" [disabled]="!isJoined">离开会议</button> <div class="video-grid"> <div class="video-card"> <h4>本地画面</h4> <video #localVideo autoplay muted playsinline></video> </div> <div class="video-card"> <h4>远程画面</h4> <video #remoteVideo autoplay playsinline></video> </div> </div> </div>
chime-meeting.component.css
.chime-container { max-width: 900px; margin: 2rem auto; padding: 1.5rem; font-family: system-ui, -apple-system, sans-serif; } .input-group { margin-bottom: 1rem; } .input-group label { display: block; margin-bottom: 0.5rem; font-weight: 500; } .input-group input { width: 100%; padding: 0.75rem; border: 1px solid #e5e7eb; border-radius: 6px; } button { padding: 0.75rem 1.5rem; margin-right: 1rem; border: none; border-radius: 6px; cursor: pointer; font-weight: 500; } button:disabled { background-color: #d1d5db; cursor: not-allowed; } .video-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.5rem; margin-top: 2rem; } .video-card { border: 1px solid #e5e7eb; border-radius: 8px; padding: 1rem; } video { width: 100%; border-radius: 6px; background-color: #f3f4f6; }
3. 配置App模块
在app.module.ts中导入FormsModule(用于双向绑定)并声明组件:
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { ChimeMeetingComponent } from './chime-meeting/chime-meeting.component'; @NgModule({ declarations: [ AppComponent, ChimeMeetingComponent ], imports: [ BrowserModule, FormsModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
核心注意事项
- 凭证安全:示例中的会议凭证是占位内容,生产环境必须通过后端调用Amazon Chime的
CreateMeeting和CreateAttendeeAPI生成,绝对不能在前端暴露敏感信息。 - 浏览器权限:确保应用运行在HTTPS环境(localhost除外),否则浏览器会拒绝授予摄像头/麦克风权限。
- 错误扩展:示例的错误处理仅作基础提示,实际项目中可以添加更详细的日志、重试逻辑或UI状态提示。
内容的提问来源于stack exchange,提问作者Dash_PSR
相关产品推荐
相关产品推荐

