gemercheung 3 years ago
parent
commit
8c90ad7429

+ 1 - 1
packages/core/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@simaq/core",
-  "version": "1.0.6",
+  "version": "1.0.7",
   "main": "dist/index",
   "types": "dist/index",
   "files": [

+ 1 - 0
packages/core/src/index.ts

@@ -1 +1,2 @@
 export * from './lib/init';
+export { RecorderStatusType } from './lib/basicSimaqRecorder';

+ 58 - 25
packages/core/src/lib/basicSimaqRecorder.ts

@@ -2,8 +2,8 @@ import { audioConstraints } from './audioConstraints';
 import { videoConstraints } from './videoConstraints';
 import { isSupport } from './isSupport';
 import { getVideo } from './videoElement';
-// import { BehaviorSubject } from 'rxjs';
 import { EventEmitter } from 'eventemitter3';
+
 export type ResolutionType = '1080p' | '2k' | '4k';
 export interface InitConfigType extends DisplayMediaStreamConstraints {
     uploadUrl: '';
@@ -11,6 +11,12 @@ export interface InitConfigType extends DisplayMediaStreamConstraints {
     autoDownload?: boolean;
     debug?: boolean;
 }
+export enum RecorderStatusType {
+    init = 0,
+    start = 1,
+    hold = 2,
+    end = 3,
+}
 export class BasicSimaqRecorder extends EventEmitter {
     displayMediaStreamConstraints: DisplayMediaStreamConstraints = {
         video: videoConstraints.getValue(),
@@ -20,9 +26,11 @@ export class BasicSimaqRecorder extends EventEmitter {
     private stream: MediaStream;
     private audioInput: MediaStream;
     private mediaRecorder: MediaRecorder;
+    public status: RecorderStatusType = 0;
     // public record = new BehaviorSubject<Blob>(null);
     private recordChunks: Blob[] = [];
     private autoDownload = false;
+    private passiveEnd = false;
 
     constructor(arg: InitConfigType) {
         super();
@@ -32,6 +40,7 @@ export class BasicSimaqRecorder extends EventEmitter {
             console.log('subscribe', value);
         });
     }
+    private sleep = (ms) => new Promise((r) => setTimeout(r, ms));
 
     public async startRecord(): Promise<void> {
         if (!this.isStartRecoding) {
@@ -40,10 +49,13 @@ export class BasicSimaqRecorder extends EventEmitter {
                 console.error('当前浏览器不支持录屏或不存在https环境');
                 return;
             }
-            this.isStartRecoding = true;
+
             const media = await this.getDisplayMedia();
+            console.log('media', media);
             if (media) {
                 this.emit('startRecord');
+                this.isStartRecoding = true;
+                this.status = RecorderStatusType.start;
                 // console.log('media', media);
                 const video: HTMLVideoElement = getVideo();
                 if (video) {
@@ -57,6 +69,8 @@ export class BasicSimaqRecorder extends EventEmitter {
                         this.endRecord();
                     };
                 }
+            } else {
+                this.endRecord();
             }
         }
     }
@@ -99,15 +113,40 @@ export class BasicSimaqRecorder extends EventEmitter {
         });
     }
 
-    public endRecord(): void {
+    public holdRecord(): void {
         this.isStartRecoding = false;
+        this.status = RecorderStatusType.hold;
         this.streamStop();
-        this.emit('endRecord');
+    }
+
+    public async endRecord(): Promise<Blob[]> {
+        return new Promise<Blob[]>(async (resolve) => {
+            try {
+                this.streamStop();
+                await this.sleep(1000);
+                this.isStartRecoding = false;
+                this.status = RecorderStatusType.end;
+                const blobs = this.recordChunks.slice();
+                console.log('last-dump', blobs);
+                if (this.autoDownload) {
+                    blobs?.length && this.handleAutoDownload(blobs);
+                }
+                this.emit('endRecord', blobs);
+                this.passiveEnd = false;
+                this.recordChunks = [];
+                resolve(blobs);
+            } catch (error) {
+                resolve([]);
+            }
+        });
     }
     private streamStop(): void {
         if (this.stream) {
             this.stream.getTracks().forEach((track) => track.stop());
         }
+        if (this.audioInput) {
+            this.audioInput.getTracks().forEach((track) => track.stop());
+        }
         if (this.mediaRecorder) {
             this.mediaRecorder.stop();
         }
@@ -129,7 +168,6 @@ export class BasicSimaqRecorder extends EventEmitter {
         });
         this.mediaRecorder = mediaRecorder;
         this.mediaRecorder.ondataavailable = (event) => {
-            // console.log('ondataavailable', event.data);
             this.recordChunks.push(event.data);
             this.emit(
                 'record',
@@ -139,29 +177,24 @@ export class BasicSimaqRecorder extends EventEmitter {
             );
         };
         this.mediaRecorder.stop = () => {
-            setTimeout(() => {
-                this.handleAutoDownload();
-                this.recordChunks = [];
-                // this.record.next(null);
-            }, 1000);
+            // setTimeout(() => {
+            //     this.handleAutoDownload();
+            // }, 1000);
         };
     }
 
-    private handleAutoDownload(): void {
-        if (this.autoDownload) {
-            // console.log('recordChunks', this.recordChunks);
-            const downloadBlob = new Blob(this.recordChunks, {
-                type: 'video/mp4; codecs=h264',
-            });
-            const url = URL.createObjectURL(downloadBlob);
-            const a: HTMLAnchorElement = document.createElement('a');
-            document.body.appendChild(a);
-            a.style.display = 'none';
-            a.href = url;
-            a.download = 'test.mp4';
-            a.click();
-            window.URL.revokeObjectURL(url);
-        }
+    private handleAutoDownload(chunks: Blob[]): void {
+        const downloadBlob = new Blob(chunks, {
+            type: 'video/mp4; codecs=h264',
+        });
+        const url = URL.createObjectURL(downloadBlob);
+        const a: HTMLAnchorElement = document.createElement('a');
+        document.body.appendChild(a);
+        a.style.display = 'none';
+        a.href = url;
+        a.download = 'test.mp4';
+        a.click();
+        window.URL.revokeObjectURL(url);
     }
 
     private uploadToServer(): void { }

+ 2 - 0
packages/core/src/lib/init.ts

@@ -2,6 +2,8 @@ import { BasicSimaqRecorder, InitConfigType } from './basicSimaqRecorder';
 import { createVideo, getVideo } from './videoElement';
 // import { audioConstraints } from "./audioConstraints";
 import { videoConstraints } from './videoConstraints';
+
+
 export class VideoRecorder extends BasicSimaqRecorder {
     // public displayMediaStreamConstraints: DisplayMediaStreamConstraints = {
     //   video: videoConstraints.value,

+ 5 - 5
play/src/App.vue

@@ -20,17 +20,17 @@ videoRecorder.on('record', (data: Blob) => {
     //录屏后片断数据
     console.log('record', data);
 });
-videoRecorder.on('endRecord', () => {
+videoRecorder.on('endRecord', (data) => {
+    console.log('endRecord', data);
     //结束录屏event
 });
-
 </script>
 
 <template>
-    <div>
-
-    </div>
+    <div></div>
     <button type="button" @click="videoRecorder.startRecord">开始录屏</button>
+    <button type="button" @click="videoRecorder.holdRecord">暂停录屏</button>
+    <!-- <button type="button" @click="videoRecorder.holdRecord">resume录屏</button> -->
     <button type="button" @click="videoRecorder.endRecord">停止录屏</button>
     <!-- <HelloWorld msg="Vite + Vue" /> -->
 </template>