import { AliRtcPlugin, LocalStreamInfo } from 'aliyun-rtc-sdk';
export default class UserNamePlugin extends AliRtcPlugin {
private canvas: HTMLCanvasElement;
private requestId?: number;
// text 為希望繪製的人名
constructor(text: string) {
super('UserNamePlugin'); // 外掛程式的名稱,可自訂,須保證全域唯一
this.options = { text };
this.canvas = document.createElement('canvas');
}
isSupported(): boolean {
// 本外掛程式不需要依賴特定版本 aliyun-rtc-sdk 的功能,所以直接返回 true 即可
return true;
}
setOptions(options: { text: string }): void {
// 用於動態更新希望繪製的人名
this.options = options;
}
shouldUpdate(): boolean {
// 當流發生改變的時候(比如開關網路攝影機),是否要調用 process 方法,這裡我們直接返回 true
return true;
}
process(streamInfo: LocalStreamInfo): Promise<void> {
if (streamInfo.currentVideoTrack) {
// 如果有視頻軌道,我們定義對視頻軌道的處理方式
const videoTrack = streamInfo.currentVideoTrack as MediaStreamVideoTrack;
const settings = videoTrack.getSettings();
// 將畫布的寬高調整為與視頻流相同
this.canvas.width = settings.width!;
this.canvas.height = settings.height!;
// 將 MediaStreamTrack 轉換為視頻元素的源
const stream = new MediaStream([videoTrack]);
const videoElement = document.createElement('video');
videoElement.srcObject = stream;
videoElement.play();
const ctx = this.canvas.getContext('2d')!;
// 定時繪製視訊框架到 canvas,並添加文字
const drawFrame = () => {
if (videoElement.readyState >= HTMLMediaElement.HAVE_CURRENT_DATA) {
ctx.drawImage(videoElement, 0, 0, this.canvas.width, this.canvas.height);
// 在右下角添加文字
ctx.fillStyle = 'white'; // 文字顏色
ctx.font = '40px Arial'; // 文字大小和字型
ctx.textAlign = 'right'; // 文本對齊
ctx.fillText(this.options.text, this.canvas.width - 20, this.canvas.height - 20); // 文本位置
}
this.requestId = requestAnimationFrame(drawFrame); // 持續繪製幀
}
this.requestId = requestAnimationFrame(drawFrame);
// 建立新的 MediaStream
const newStream = this.canvas.captureStream(settings.frameRate); // 或根據需要設定其他幀率
const newVideoTrack = newStream.getVideoTracks()[0];
// 調用 streamInfo.updateVideoTrack 替換視頻流
streamInfo.updateVideoTrack(newVideoTrack);
} else if (this.requestId) {
// 如果之前設定了 requestAnimationFrame,且此時沒有視頻軌道,則取消繪製
cancelAnimationFrame(this.requestId);
}
return Promise.resolve();
}
}