浏览代码

1.1.0 多平台

gemercheung 3 年之前
父节点
当前提交
427f94ef97

+ 1 - 1
packages/core/package.json

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

+ 118 - 21
packages/core/src/lib/basicSimaqRecorder.ts

@@ -5,13 +5,26 @@ import { getVideo } from './videoElement';
 import { EventEmitter } from 'eventemitter3';
 
 export type ResolutionType = '1080p' | '2k' | '4k';
+
+export type PlatformType = 'web' | 'electron' | 'canvas';
+
+export interface PlatformConfigType {
+    chromeMediaSourceId?: string | null;
+    canvasId?: string;
+    minWidth?: number;
+    maxWidth?: number;
+    minHeight?: number;
+    maxHeight?: number;
+    frameRate?: number;
+}
+
 export interface InitConfigType extends DisplayMediaStreamConstraints {
-    uploadUrl: '';
+    uploadUrl?: string;
     resolution: ResolutionType;
     autoDownload?: boolean;
     isElectron?: boolean;
-    chromeMediaSourceId?: null;
-    chromeAudioSourceId?: null;
+    platform?: PlatformType;
+    config?: PlatformConfigType;
     debug?: boolean;
 }
 export enum RecorderStatusType {
@@ -35,22 +48,59 @@ export class BasicSimaqRecorder extends EventEmitter {
     private recordChunks: Blob[] = [];
     private autoDownload = false;
     private passiveEnd = false;
-    private isElectron: boolean;
+    private platform: string;
+    private uploadUrl: string;
+    private canvasId: string;
+    private platformConfig: PlatformConfigType;
     private chromeMediaSourceId: string | null;
-    private chromeAudioSourceId: string | null;
+
     constructor(arg: InitConfigType) {
         super();
         console.log('arg', arg);
         this.autoDownload = arg.autoDownload;
-        this.isElectron = arg.isElectron;
-        this.chromeMediaSourceId = arg.chromeMediaSourceId;
-        this.chromeAudioSourceId = arg.chromeAudioSourceId;
+        this.platform = arg.platform;
+        this.platformConfig = arg.config;
+        this.uploadUrl = arg.uploadUrl;
+        this.initParams(arg);
         videoConstraints.subscribe((value) => {
             console.log('subscribe', value);
         });
     }
     private sleep = (ms) => new Promise((r) => setTimeout(r, ms));
 
+    private get isElectron(): boolean {
+        return this.platform === 'electron';
+    }
+    private get isWeb(): boolean {
+        return this.platform === 'web';
+    }
+    private get isCanvas(): boolean {
+        return this.platform === 'canvas';
+    }
+
+    private get canvasElement(): HTMLCanvasElement {
+        // return document.getElementById(this.canvasId);
+        return document.querySelector(this.canvasId);
+    }
+    private set canvasElement(canvas) {
+        this.canvasElement = canvas;
+    }
+
+    private initParams(arg: InitConfigType): void {
+        switch (arg.platform) {
+            case 'web':
+                break;
+            case 'electron':
+                this.chromeMediaSourceId = arg.config.chromeMediaSourceId;
+                break;
+            case 'canvas':
+                this.canvasId = arg.config.canvasId;
+                break;
+            default:
+                break;
+        }
+    }
+
     public async startRecord(): Promise<void> {
         try {
             if (!this.isStartRecoding) {
@@ -60,9 +110,12 @@ export class BasicSimaqRecorder extends EventEmitter {
                     return;
                 }
 
-                const media = this.isElectron
-                    ? await this.getEletronDisplayMedia()
-                    : await this.getDisplayMedia();
+                // const media = this.isElectron
+                //     ? await this.getEletronDisplayMedia()
+                //     : await this.getDisplayMedia();
+
+                const media = await this.getDefaultMedia();
+
                 console.log('media', media);
                 if (media) {
                     this.emit('startRecord');
@@ -92,6 +145,41 @@ export class BasicSimaqRecorder extends EventEmitter {
             console.error('startRecord::', error);
         }
     }
+    private getDefaultMedia(): Promise<MediaStream | null> {
+        return new Promise(async (resolve) => {
+            switch (this.platform) {
+                case 'web':
+                    return resolve(await this.getDisplayMedia());
+                case 'canvas':
+                    return resolve(await this.getCanvasSteam());
+                case 'electron':
+                    return resolve(await this.getEletronDisplayMedia());
+                default:
+                    return resolve(await this.getDisplayMedia());
+            }
+        });
+    }
+
+    private getCanvasSteam(): Promise<MediaStream | null> {
+        return new Promise(async (resolve) => {
+            try {
+                const audioInput = await this.getDeaultAudio();
+                if (audioInput) {
+                    this.audioInput = audioInput;
+                }
+                console.log('audioInput', audioInput);
+                console.log('this.canvasElement', this.canvasElement);
+                const stream = this.canvasElement.captureStream(30);
+                if (stream) {
+                    return resolve(stream);
+                }
+                return resolve(null);
+            } catch (error) {
+                return resolve(null);
+            }
+        });
+    }
+
     private getEletronDisplayMedia(): Promise<MediaStream | null> {
         return new Promise(async (resolve) => {
             try {
@@ -101,18 +189,21 @@ export class BasicSimaqRecorder extends EventEmitter {
                 }
                 console.log('eletron-audioInput', audioInput);
                 if (navigator.mediaDevices.getDisplayMedia) {
+
+                    const videoConfig = {
+                        mandatory: {
+                            chromeMediaSource: 'desktop',
+                            chromeMediaSourceId: this.chromeMediaSourceId,
+                            minWidth: this.platformConfig.minWidth || 1280,
+                            maxWidth: this.platformConfig.maxWidth || 3840,
+                            minHeight: this.platformConfig.minHeight || 720,
+                            maxHeight: this.platformConfig.maxHeight || 2160,
+                        },
+                    };
+                    console.log('videoConfig', videoConfig);
                     const res = await navigator.mediaDevices.getUserMedia({
                         audio: false,
-                        video: {
-                            mandatory: {
-                                chromeMediaSource: 'desktop',
-                                chromeMediaSourceId: this.chromeMediaSourceId,
-                                minWidth: 1280,
-                                maxWidth: 3840,
-                                minHeight: 720,
-                                maxHeight: 2160,
-                            },
-                        },
+                        video: videoConfig,
                     } as any as MediaStreamConstraints);
                     return resolve(res);
                 }
@@ -260,5 +351,11 @@ export class BasicSimaqRecorder extends EventEmitter {
         window.URL.revokeObjectURL(url);
     }
 
+    public updateCanvas(canvas: HTMLCanvasElement) {
+        if (this.isCanvas) {
+            this.canvasElement = canvas;
+        }
+    }
+
     private uploadToServer(): void { }
 }

+ 13 - 10
play/index.html

@@ -1,13 +1,16 @@
 <!DOCTYPE html>
 <html lang="en">
-  <head>
-    <meta charset="UTF-8" />
-    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
-    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <title>Simaq video recorder SDK</title>
-  </head>
-  <body>
-    <div id="app"></div>
-    <script type="module" src="/src/main.ts"></script>
-  </body>
+    <head>
+        <meta charset="UTF-8" />
+        <link rel="icon" type="image/svg+xml" href="/vite.svg" />
+        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+        <link rel="stylesheet" href="/player/goldplay-h265.css" />
+        <script src="/player/goldplay-h265-sdk.js"></script>
+
+        <title>Simaq video recorder SDK</title>
+    </head>
+    <body>
+        <div id="app"></div>
+        <script type="module" src="/src/main.ts"></script>
+    </body>
 </html>

+ 1 - 2
play/package.json

@@ -9,8 +9,7 @@
     "preview": "vite preview"
   },
   "dependencies": {
-    "@simaq/core": "workspace:^1.0.0",
-    "@simaq/foo": "workspace:^1.0.0",
+    "@simaq/core": "workspace:^1.0.17",
     "lodash-es": "^4.17.21",
     "vue": "^3.2.37"
   },

文件差异内容过多而无法显示
+ 26 - 0
play/public/player/goldplay-h265-polyfill.js


文件差异内容过多而无法显示
+ 26 - 0
play/public/player/goldplay-h265-sdk.js


文件差异内容过多而无法显示
+ 2 - 0
play/public/player/goldplay-h265.css


二进制
play/public/player/image/goldplay-logo-empty.png


二进制
play/public/player/image/goldplay-logo.png


文件差异内容过多而无法显示
+ 31 - 0
play/public/player/image/goldplay-logo.svg


二进制
play/public/player/image/goldvideo-logo-w.png


二进制
play/public/player/image/loading.gif


文件差异内容过多而无法显示
+ 1220 - 0
play/public/player/lib/TAppDecoderStatic.js


二进制
play/public/player/lib/TAppDecoderStatic.wasm


文件差异内容过多而无法显示
+ 5283 - 0
play/public/player/lib/libffmpeg.js


二进制
play/public/player/lib/libffmpeg.wasm


+ 57 - 3
play/src/App.vue

@@ -3,14 +3,19 @@
 // Check out https://vuejs.org/api/sfc-script-setup.html#script-setup
 import HelloWorld from './components/HelloWorld.vue';
 import { VideoRecorder } from '@simaq/core';
+import { onMounted } from 'vue';
 // import { add } from "lodash-es";
 // import { meaningOfLife } from "@simaq/foo";
 
 const videoRecorder = new VideoRecorder({
-    uploadUrl: '',
+    // uploadUrl: '',
     resolution: '4k',
     autoDownload: true,
-    debug: true,
+    platform: 'canvas',
+    config: {
+        canvasId: '.goldplay__screen--canvas',
+    },
+    debug: false,
 });
 console.log('videoRecorder', videoRecorder);
 videoRecorder.on('startRecord', () => {
@@ -28,18 +33,67 @@ videoRecorder.on('cancelRecord', () => {
     console.log('cancelRecord');
     //cancel录屏event
 });
+
+onMounted(() => {
+    const GoldPlay = (window as any).GoldPlay;
+
+    let el = document.querySelector('.play-container');
+    //播放器参数
+    let options = {
+        // 视频播放地址
+        sourceURL: 'https://omc3i.codesandbox.io/ts/playlist.m3u8',
+        type: 'HLS',
+        // wasm库地址
+        // libPath: '/lib',
+        libPath: 'https://omc3i.codesandbox.io/',
+    };
+    let player = new GoldPlay(el, options);
+
+    const testFrame: HTMLIFrameElement = document.getElementById(
+        'testFrame',
+    ) as HTMLIFrameElement;
+    console.log('testFrame', testFrame);
+    testFrame.onload = () => {
+        // const canvas = testFrame.contentWindow?.document.getElementsByName(
+        //     'canvas',
+        // ) as unknown as HTMLCanvasElement;
+        console.log(
+            'testFrame-load',
+            window.frames['testFrame'].document.getElementsByName('canvas'),
+        );
+    };
+    // testFrame.addEventListener('load', () => {
+
+    //     if (canvas) {
+    //         videoRecorder.updateCanvas(canvas);
+    //     }
+    // });
+});
 </script>
 
 <template>
-    <div></div>
+    <div>
+        <div class="play-container"></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>
+    <iframe
+        id="testFrame"
+        src="https://cszfb.4dkankan.com/spc.html?m=c-bHsbx73"
+    ></iframe>
     <!-- <HelloWorld msg="Vite + Vue" /> -->
 </template>
 
 <style scoped>
+.play-container {
+    width: 800px;
+    height: 600px;
+    /* background-color: #000; */
+    margin: 20px 0 0 100px;
+    float: left;
+}
 .logo {
     height: 6em;
     padding: 1.5em;

+ 1 - 3
pnpm-lock.yaml

@@ -49,8 +49,7 @@ importers:
 
   play:
     specifiers:
-      '@simaq/core': workspace:^1.0.0
-      '@simaq/foo': workspace:^1.0.0
+      '@simaq/core': workspace:^1.0.17
       '@vitejs/plugin-vue': ^3.0.0
       lodash-es: ^4.17.21
       typescript: ^4.6.4
@@ -59,7 +58,6 @@ importers:
       vue-tsc: ^0.38.4
     dependencies:
       '@simaq/core': link:../packages/core
-      '@simaq/foo': link:../packages/foo
       lodash-es: 4.17.21
       vue: 3.2.37
     devDependencies: