Преглед изворни кода

feat:(更新)1.1.3 -- 更新录制声音来自项目

gemercheung пре 2 година
родитељ
комит
6f56fab089

+ 6 - 6
package.json

@@ -15,16 +15,16 @@
     "dev": "pnpm -C play dev"
   },
   "devDependencies": {
-    "@nighttrax/eslint-config-tsx": "~10.0.0-beta.0",
-    "doctoc": "~2.2.0",
+    "@nighttrax/eslint-config-tsx": "~10.0.0",
+    "@typescript-eslint/eslint-plugin": "^5.40.0",
+    "@typescript-eslint/parser": "^5.40.0",
+    "doctoc": "~2.2.1",
     "eslint": "~8.20.0",
-    "eslint-plugin-import": "~2.26.0",
-    "@typescript-eslint/eslint-plugin": "^5.30.6",
-    "@typescript-eslint/parser": "^5.30.6",
     "eslint-config-prettier": "^8.5.0",
+    "eslint-plugin-import": "~2.26.0",
     "eslint-plugin-prettier": "^4.2.1",
     "prettier": "^2.7.1",
-    "typescript": "~4.7.0"
+    "typescript": "~4.7.4"
   },
   "pnpm": {
     "peerDependencyRules": {

+ 3 - 3
packages/core/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@simaq/core",
-  "version": "1.1.1",
+  "version": "1.1.3",
   "main": "dist/index",
   "types": "dist/index",
   "files": [
@@ -19,10 +19,10 @@
   },
   "dependencies": {
     "eventemitter3": "^4.0.7",
-    "rxjs": "~7.5.5"
+    "rxjs": "~7.5.7"
   },
   "devDependencies": {
     "rimraf": "~3.0.2",
-    "typescript": "~4.7.0"
+    "typescript": "~4.7.4"
   }
 }

+ 9 - 1
packages/core/src/lib/audioConstraints.ts

@@ -1,3 +1,11 @@
 import { BehaviorSubject } from 'rxjs';
 
-export const audioConstraints = new BehaviorSubject<MediaTrackConstraints>({});
+export const audioConstraints = new BehaviorSubject<MediaTrackConstraints>({
+    autoGainControl: true,
+    echoCancellation: true,
+    noiseSuppression: true,
+    latency: 0,
+    channelCount: 2,
+    sampleRate: 44100,
+    suppressLocalAudioPlayback: false,
+});

+ 32 - 8
packages/core/src/lib/basicSimaqRecorder.ts

@@ -39,7 +39,8 @@ export enum RecorderStatusType {
 export class BasicSimaqRecorder extends EventEmitter {
     displayMediaStreamConstraints: DisplayMediaStreamConstraints = {
         video: videoConstraints.getValue(),
-        audio: audioConstraints.getValue(),
+        // audio: audioConstraints.getValue(),
+        audio: false,
     };
     private isStartRecoding = false;
     private stream: MediaStream;
@@ -129,7 +130,7 @@ export class BasicSimaqRecorder extends EventEmitter {
                         // console.log('video', video);
                         video.srcObject = media;
                         this.stream = media;
-                        this.createMediaRecoder();
+                        await this.createMediaRecoder();
                         this.mediaRecorder.start();
                         this.stream.getVideoTracks()[0].onended = () => {
                             console.log('stop-share');
@@ -228,6 +229,10 @@ export class BasicSimaqRecorder extends EventEmitter {
                 }
                 console.log('audioInput', audioInput);
                 if (navigator.mediaDevices.getDisplayMedia) {
+                    console.log(
+                        'displayMediaStreamConstraints',
+                        this.displayMediaStreamConstraints,
+                    );
                     const res = await navigator.mediaDevices.getDisplayMedia(
                         this.displayMediaStreamConstraints,
                     );
@@ -243,13 +248,21 @@ export class BasicSimaqRecorder extends EventEmitter {
     private async getDeaultAudio(): Promise<MediaStream> {
         return new Promise(async (resolve) => {
             try {
+                const audioConfig = {
+                    echoCancellation: true,
+                    autoGainControl: true,
+                    noiseSuppression: true,
+                    latency: 0,
+                };
+                console.log('audioConfig', audioConfig);
                 if (navigator.mediaDevices.getUserMedia) {
                     const res = await navigator.mediaDevices.getUserMedia({
-                        audio: true,
+                        audio: audioConfig,
                         video: false,
                     });
                     return resolve(res);
                 }
+
                 return resolve(null);
             } catch (error) {
                 return resolve(null);
@@ -312,8 +325,7 @@ export class BasicSimaqRecorder extends EventEmitter {
         }
     }
 
-    private createMediaRecoder(): void {
-        console.log('video-flag', videoConstraints.value);
+    private async createMediaRecoder() {
         // let mergeSteam: MediaStream;
         let audioTrack: MediaStreamTrack, videoTrack: MediaStreamTrack;
         if (this.audioInput) {
@@ -321,8 +333,20 @@ export class BasicSimaqRecorder extends EventEmitter {
             [audioTrack] = this.audioInput.getAudioTracks();
             this.stream = new MediaStream([videoTrack, audioTrack]);
         }
+        const globalAudioInstance = (window as any).Howler;
+        if (globalAudioInstance?.ctx) {
+            const streamDest =
+                globalAudioInstance.ctx.createMediaStreamDestination();
+            globalAudioInstance.masterGain.connect(streamDest);
+            console.log('streamDest', streamDest);
+            [videoTrack] = this.stream.getVideoTracks();
+            [audioTrack] = (streamDest.stream as MediaStream).getAudioTracks();
+            console.log('audioTrack', audioTrack);
+            this.stream = new MediaStream([videoTrack, audioTrack]);
+        }
+
         const mediaRecorder = new MediaRecorder(this.stream, {
-            mimeType: 'video/webm;codecs=vp9,opus',
+            mimeType: 'video/webm;codecs=vp9',
             audioBitsPerSecond: videoConstraints.value.audioBitsPerSecond,
             videoBitsPerSecond: videoConstraints.value.videoBitsPerSecond,
         });
@@ -332,7 +356,7 @@ export class BasicSimaqRecorder extends EventEmitter {
             this.emit(
                 'record',
                 new Blob([event.data], {
-                    type: 'video/mp4; codecs=h264',
+                    type: 'video/webm; codecs=webm',
                 }),
             );
         };
@@ -345,7 +369,7 @@ export class BasicSimaqRecorder extends EventEmitter {
 
     private handleAutoDownload(chunks: Blob[]): void {
         const downloadBlob = new Blob(chunks, {
-            type: 'video/mp4; codecs=h264',
+            type: 'video/webm; codecs=webm',
         });
         const url = URL.createObjectURL(downloadBlob);
         const a: HTMLAnchorElement = document.createElement('a');

+ 23 - 21
play/package.json

@@ -1,22 +1,24 @@
 {
-  "name": "play",
-  "private": true,
-  "version": "0.0.0",
-  "type": "module",
-  "scripts": {
-    "dev": "vite --host 0.0.0.0",
-    "build": "vue-tsc --noEmit && vite build",
-    "preview": "vite preview"
-  },
-  "dependencies": {
-    "@simaq/core": "workspace:^1.0.17",
-    "lodash-es": "^4.17.21",
-    "vue": "^3.2.37"
-  },
-  "devDependencies": {
-    "@vitejs/plugin-vue": "^3.0.0",
-    "typescript": "^4.6.4",
-    "vite": "^3.0.0",
-    "vue-tsc": "^0.38.4"
-  }
-}
+    "name": "play",
+    "private": true,
+    "version": "0.0.0",
+    "type": "module",
+    "scripts": {
+        "dev": "vite --host 0.0.0.0",
+        "build": "vue-tsc --noEmit && vite build",
+        "preview": "vite preview"
+    },
+    "dependencies": {
+        "@simaq/core": "workspace:^1.1.2-beta.0",
+        "lodash-es": "^4.17.21",
+        "vue": "^3.2.40",
+        "howler": "^2.2.3"
+    },
+    "devDependencies": {
+        "@vitejs/plugin-vue": "^3.1.2",
+        "typescript": "^4.8.4",
+        "vite": "^3.1.7",
+        "vite-plugin-mkcert": "^1.10.1",
+        "vue-tsc": "^0.38.9"
+    }
+}

BIN
play/public/2825345580.mp3


BIN
play/public/SoundHelix-Song-13.mp3


+ 57 - 27
play/src/App.vue

@@ -4,13 +4,18 @@
 import HelloWorld from './components/HelloWorld.vue';
 import { VideoRecorder } from '@simaq/core';
 import { onMounted } from 'vue';
+import { Howler, Howl } from 'howler';
 // import { add } from "lodash-es";
 // import { meaningOfLife } from "@simaq/foo";
-
+console.log('howler', Howler, Howl);
+let sound = new Howl({
+    html5: false,
+    src: ['2825345580.mp3', '2825345580.mp3'],
+});
 const videoRecorder = new VideoRecorder({
     // uploadUrl: '',
     resolution: '4k',
-    autoDownload: true,
+    autoDownload: false,
     platform: 'web',
     // config: {
     //     canvasId: '.goldplay__screen--canvas',
@@ -19,46 +24,65 @@ const videoRecorder = new VideoRecorder({
 });
 console.log('videoRecorder', videoRecorder);
 videoRecorder.on('startRecord', () => {
+    sound.play();
     //开始录屏event
 });
 videoRecorder.on('record', (data: Blob) => {
     //录屏后片断数据
     console.log('record', data);
+    handleAutoDownload([data]);
 });
 videoRecorder.on('endRecord', (data) => {
     console.log('endRecord', data);
+    sound.stop();
     //结束录屏event
 });
 videoRecorder.on('cancelRecord', () => {
     console.log('cancelRecord');
     //cancel录屏event
 });
-
+const handleAutoDownload = async (chunks: Blob[]) => {
+    const downloadBlob = new Blob(chunks, {
+        type: 'video/mp4; codecs=h264',
+    });
+    // const downloadBlob = await fixWebmMetaInfo(
+    //     new Blob(chunks, { type: 'video/webm; codecs=h264' }),
+    // );
+    const url = URL.createObjectURL(downloadBlob);
+    const a: HTMLAnchorElement = document.createElement('a');
+    document.body.appendChild(a);
+    a.style.display = 'none';
+    a.href = url;
+    const name = new Date().getTime();
+    a.download = `${name}.mp4`;
+    a.click();
+    window.URL.revokeObjectURL(url);
+};
 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);
+    // 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', canvas);
-    };
+    // 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', canvas);
+    // };
     // testFrame.addEventListener('load', () => {
 
     //     if (canvas) {
@@ -69,17 +93,23 @@ onMounted(() => {
 </script>
 
 <template>
-    <div>
+    <!-- <div>
         <div class="play-container"></div>
+    </div> -->
+    <div>
+        <!-- <audio src="SoundHelix-Song-13.mp3" /> -->
+        <!-- <audio controls id="cAudio">
+            <source src="2825345580.mp3" type="audio/mpeg" />
+        </audio> -->
     </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
+    <!-- <iframe
         id="testFrame"
         src="https://cszfb.4dkankan.com/spc.html?m=c-bHsbx73"
-    ></iframe>
+    ></iframe> -->
     <!-- <HelloWorld msg="Vite + Vue" /> -->
 </template>
 

+ 2 - 1
play/vite.config.ts

@@ -1,7 +1,8 @@
 import { defineConfig } from 'vite';
 import vue from '@vitejs/plugin-vue';
+import mkcert from 'vite-plugin-mkcert';
 
 // https://vitejs.dev/config/
 export default defineConfig({
-    plugins: [vue()],
+    plugins: [vue(), mkcert()],
 });

Разлика између датотеке није приказан због своје велике величине
+ 975 - 691
pnpm-lock.yaml