|
@@ -28,8 +28,9 @@ export interface InitConfigType extends MediaStreamConstraints {
|
|
|
platform?: PlatformType;
|
|
|
config?: PlatformConfigType;
|
|
|
debug?: boolean;
|
|
|
- disbaledAudio?: boolean;
|
|
|
- systemAudio?: boolean
|
|
|
+ debugShowVideo?: boolean;
|
|
|
+ disabledAudio?: boolean;
|
|
|
+ systemAudio?: boolean;
|
|
|
}
|
|
|
export enum RecorderStatusType {
|
|
|
init = 0,
|
|
@@ -39,8 +40,8 @@ export enum RecorderStatusType {
|
|
|
}
|
|
|
|
|
|
interface CustomMediaStreamConstraints extends MediaStreamConstraints {
|
|
|
- selfBrowserSurface?: string,
|
|
|
- systemAudio?: string,
|
|
|
+ selfBrowserSurface?: string;
|
|
|
+ systemAudio?: string;
|
|
|
}
|
|
|
export class BasicSimaqRecorder extends EventEmitter {
|
|
|
displayMediaStreamConstraints: CustomMediaStreamConstraints = {
|
|
@@ -49,8 +50,7 @@ export class BasicSimaqRecorder extends EventEmitter {
|
|
|
preferCurrentTab: true,
|
|
|
audio: false,
|
|
|
// selfBrowserSurface: 'exclude',
|
|
|
- systemAudio: 'exclude'
|
|
|
-
|
|
|
+ systemAudio: 'exclude',
|
|
|
};
|
|
|
private isStartRecoding = false;
|
|
|
private stream: MediaStream;
|
|
@@ -66,9 +66,12 @@ export class BasicSimaqRecorder extends EventEmitter {
|
|
|
private canvasId: string;
|
|
|
private platformConfig: PlatformConfigType;
|
|
|
private chromeMediaSourceId: string | null;
|
|
|
- private disbaledAudio = false;
|
|
|
+ private disabledAudio = false;
|
|
|
private systemAudio = false;
|
|
|
private debug = false;
|
|
|
+ private codecType = 'video/webm;codecs=vp9,opus';
|
|
|
+ private codecH264Type = 'video/mp4;codecs=h264,opus';
|
|
|
+
|
|
|
constructor(arg: InitConfigType) {
|
|
|
super();
|
|
|
|
|
@@ -76,13 +79,18 @@ export class BasicSimaqRecorder extends EventEmitter {
|
|
|
this.platform = arg.platform;
|
|
|
this.platformConfig = arg.config;
|
|
|
this.uploadUrl = arg.uploadUrl;
|
|
|
- this.disbaledAudio = arg.disbaledAudio;
|
|
|
+ this.disabledAudio = arg.disabledAudio;
|
|
|
this.debug = arg.debug;
|
|
|
this.systemAudio = arg.systemAudio;
|
|
|
this.setSystemAudio();
|
|
|
this.initParams(arg);
|
|
|
videoConstraints.subscribe((value) => {
|
|
|
this.debug && console.log('subscribe', value);
|
|
|
+ this.displayMediaStreamConstraints.video = Object.assign(
|
|
|
+ {},
|
|
|
+ this.displayMediaStreamConstraints.video,
|
|
|
+ value,
|
|
|
+ );
|
|
|
});
|
|
|
this.debug && console.log('arg', arg);
|
|
|
}
|
|
@@ -109,6 +117,9 @@ export class BasicSimaqRecorder extends EventEmitter {
|
|
|
private initParams(arg: InitConfigType): void {
|
|
|
switch (arg.platform) {
|
|
|
case 'web':
|
|
|
+ if (arg.config.frameRate) {
|
|
|
+ videoConstraints.value.frameRate = arg.config.frameRate;
|
|
|
+ }
|
|
|
break;
|
|
|
case 'electron':
|
|
|
this.chromeMediaSourceId = arg.config.chromeMediaSourceId;
|
|
@@ -122,14 +133,13 @@ export class BasicSimaqRecorder extends EventEmitter {
|
|
|
}
|
|
|
private setSystemAudio() {
|
|
|
if (this.systemAudio) {
|
|
|
- this.displayMediaStreamConstraints.systemAudio = 'include'
|
|
|
+ this.displayMediaStreamConstraints.systemAudio = 'include';
|
|
|
this.displayMediaStreamConstraints.audio = true;
|
|
|
} else {
|
|
|
- this.displayMediaStreamConstraints.systemAudio = 'exclude'
|
|
|
+ this.displayMediaStreamConstraints.systemAudio = 'exclude';
|
|
|
this.displayMediaStreamConstraints.audio = false;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
public async startRecord(): Promise<void> {
|
|
|
try {
|
|
|
if (!this.isStartRecoding) {
|
|
@@ -138,6 +148,10 @@ export class BasicSimaqRecorder extends EventEmitter {
|
|
|
console.error('当前浏览器不支持录屏或不存在https环境');
|
|
|
return;
|
|
|
}
|
|
|
+ if (!isSupport()) {
|
|
|
+ console.error('当前浏览器不支持录屏或不存在https环境');
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
// const media = this.isElectron
|
|
|
// ? await this.getEletronDisplayMedia()
|
|
@@ -197,7 +211,7 @@ export class BasicSimaqRecorder extends EventEmitter {
|
|
|
this.audioInput = audioInput;
|
|
|
}
|
|
|
this.debug && console.log('audioInput', audioInput);
|
|
|
- const stream = this.canvasElement.captureStream(30);
|
|
|
+ const stream = this.canvasElement.captureStream(60);
|
|
|
if (stream) {
|
|
|
return resolve(stream);
|
|
|
}
|
|
@@ -254,10 +268,12 @@ export class BasicSimaqRecorder extends EventEmitter {
|
|
|
}
|
|
|
this.debug && console.log('audioInput', audioInput);
|
|
|
if (navigator.mediaDevices.getDisplayMedia) {
|
|
|
- this.debug && console.log(
|
|
|
- 'displayMediaStreamConstraints',
|
|
|
- this.displayMediaStreamConstraints,
|
|
|
- );
|
|
|
+ if (this.debug) {
|
|
|
+ console.log(
|
|
|
+ 'displayMediaStreamConstraints',
|
|
|
+ this.displayMediaStreamConstraints,
|
|
|
+ );
|
|
|
+ }
|
|
|
const res = await navigator.mediaDevices.getDisplayMedia(
|
|
|
this.displayMediaStreamConstraints,
|
|
|
);
|
|
@@ -365,14 +381,16 @@ export class BasicSimaqRecorder extends EventEmitter {
|
|
|
this.stream = new MediaStream([videoTrack, audioTrack]);
|
|
|
}
|
|
|
const globalAudioInstance = (window as any).Howler;
|
|
|
- if (globalAudioInstance?.ctx && !this.disbaledAudio) {
|
|
|
+ if (globalAudioInstance?.ctx && !this.disabledAudio) {
|
|
|
const streamAudio =
|
|
|
globalAudioInstance.ctx.createMediaStreamDestination();
|
|
|
globalAudioInstance.masterGain.connect(streamAudio);
|
|
|
console.log('streamDest', streamAudio);
|
|
|
(window as any).streamAudio = streamAudio;
|
|
|
[videoTrack] = this.stream.getVideoTracks();
|
|
|
- [audioTrack] = (streamAudio.stream as MediaStream).getAudioTracks();
|
|
|
+ [audioTrack] = (
|
|
|
+ streamAudio.stream as MediaStream
|
|
|
+ ).getAudioTracks();
|
|
|
console.log('audioTrack', audioTrack);
|
|
|
audioTrack.onended = (event) => {
|
|
|
console.log('audioTrack-end', event);
|
|
@@ -382,7 +400,7 @@ export class BasicSimaqRecorder extends EventEmitter {
|
|
|
}
|
|
|
|
|
|
const mediaRecorder = new MediaRecorder(this.stream, {
|
|
|
- mimeType: 'video/webm;codecs=vp9',
|
|
|
+ mimeType: this.codecType,
|
|
|
audioBitsPerSecond: videoConstraints.value.audioBitsPerSecond,
|
|
|
videoBitsPerSecond: videoConstraints.value.videoBitsPerSecond,
|
|
|
});
|
|
@@ -396,7 +414,7 @@ export class BasicSimaqRecorder extends EventEmitter {
|
|
|
this.emit(
|
|
|
'record',
|
|
|
new Blob([event.data], {
|
|
|
- type: 'video/webm; codecs=webm',
|
|
|
+ type: this.codecType,
|
|
|
}),
|
|
|
);
|
|
|
};
|
|
@@ -419,14 +437,14 @@ export class BasicSimaqRecorder extends EventEmitter {
|
|
|
};
|
|
|
|
|
|
} catch (error) {
|
|
|
- console.error('error', error)
|
|
|
+ console.error('error', error);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
private handleAutoDownload(chunks: Blob[]): void {
|
|
|
const downloadBlob = new Blob(chunks, {
|
|
|
- type: 'video/webm; codecs=webm',
|
|
|
+ type: this.codecH264Type,
|
|
|
});
|
|
|
const url = URL.createObjectURL(downloadBlob);
|
|
|
const a: HTMLAnchorElement = document.createElement('a');
|
|
@@ -445,5 +463,5 @@ export class BasicSimaqRecorder extends EventEmitter {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private uploadToServer(): void { }
|
|
|
+ // private uploadToServer(): void { }
|
|
|
}
|