스프링 부트에 대한 Angular를 사용한 스크린캐스트

36210 단어 javascriptangular


이 기사에서는 각도에서 스프링 부트 서버로 화면 피드를 스트리밍하고 비디오 파일로 저장하는 방법을 살펴봅니다. 나는 최근에 내 프로젝트 중 하나에서 이 방법을 사용했습니다. 이것은 여러 부분으로 구성된 시리즈의 1부입니다. 나는 초보 프로그래머이기 때문에 여전히 개선의 여지가 있습니다.
시작합시다.

화면 캡처를 위한 Angular Frontend 설정



화면을 캡처한 다음 캡처한 비디오를 다운로드하는 기본 기능부터 시작하겠습니다. 이것은 간단한 각도 프로젝트입니다. 이름을 Screen-Capture로 지정하고 아래 명령을 실행하여 원하는 폴더에 프로젝트를 만듭니다.

ng new Screen-Capture


이제 신뢰할 수 있는 편집기에서 폴더를 열고 app.component.ts를 열어 카메라 스트림을 캡처하는 코드를 추가합니다.

const mediaDevices = navigator.mediaDevices as any;
declare var MediaRecorder: any;


이 줄은 브라우저mediaDevice api를 가져오고 전역 변수mediarecorder를 만듭니다.startRecording 함수를 추가해 보겠습니다.

1   async startRecording() {
2     var options;
3 
4     if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) {
5       options = {
6         videoBitsPerSecond: 2500000,
7         mimeType: 'video/webm; codecs=vp9',
8       };
9     } else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) {
10       options = {
11         videoBitsPerSecond: 2500000,
12         mimeType: 'video/webm; codecs=vp8',
13       };
14     } else {
15       options = { videoBitsPerSecond: 2500000, mimeType: 'video/webm' };
16     }
17 
18     try {
19       this.stream = await mediaDevices.getDisplayMedia({
20         screen: {
21           width: { min: 1024, ideal: 1280, max: 1920 },
22           height: { min: 576, ideal: 720, max: 1080 },
23           frameRate: { min: 10, ideal: 20, max: 25 },
24         },
25       });
26     } catch (err) {
27       alert('No devices found for recording.');
28     }
29     this.recorder = new MediaRecorder(this.stream, options);
30     let metadata: any;
31 
32     this.frameCount = 0;
33 
34     this.recorder.ondataavailable = (e: { data: any }) => {
35       this.blobarr.push(e.data);
36       this.frameCount += 1;
37     };
38 
39     this.recorder.addEventListener('stop', () => {
40       this.stream.getTracks().forEach(function (track: any) {
41         track.stop();
42       });
43       this.isRecording = false;
44     });
45 
46     this.recorder.start(500);
47   }


이제 이 함수는 우리 응용 프로그램에서 모든 무거운 작업을 수행하므로 가장 중요합니다. 함수 내에서 라인 번호 4-16에서 MediaRecorder를 통해 브라우저에 대한 쿼리가 비디오 인코딩에 사용될 최상의 코덱에 대해 수행됩니다. vp9는 최신 하드웨어에서 빠른 성능을 제공하므로 가장 선호되며 webm는 가장 선호되지 않습니다. 여기에서 비트/초가 2500000 또는 2.5Mbits/초로 설정되는 비트 전송률을 제한하는 것도 좋은 방법입니다.

19-24행


19       this.stream = await mediaDevices.getDisplayMedia({
20         screen: {
21           width: { min: 1024, ideal: 1280, max: 1920 },
22           height: { min: 576, ideal: 720, max: 1080 },
23           frameRate: { min: 10, ideal: 20, max: 25 },
24         }, 



19-24행은 화면의 스트림 핸들을 가져옵니다. 프레임 속도 기본 설정도 이 줄에서 설정됩니다. 예기치 않은 오류를 처리하기 위해 try 및 catch 블록으로 둘러싸여 있습니다.

29-37행


29     this.recorder = new MediaRecorder(this.stream, options);
30     let metadata: any;
31 
32     this.frameCount = 0;
33 
34     this.recorder.ondataavailable = (e: { data: any }) => {
35       this.blobarr.push(e.data);
36       this.frameCount += 1;
37     };



29행에서 레코더 객체는 이전에서 얻은 옵션 및 스트림 핸들이 있는 MediaRecorder 함수로 생성됩니다. 이 레코더 객체ondataavailable에 이벤트가 34-37행에 연결됩니다. 이는 레코더 객체에서 방출되는 데이터 블롭을 가져와 blobarr 라는 배열로 푸시합니다. framecount 변수가 방출된 blob의 수를 계산하기 위해 유지됩니다.

39-46행


39     this.recorder.addEventListener('stop', () => {
40       this.stream.getTracks().forEach(function (track: any) {
41         track.stop();
42       });
43       this.isRecording = false;
44     });
45 
46     this.recorder.start(500);



39행에서 stop 이벤트는 녹음을 중지하도록 연결되어 있습니다. 이 이벤트는 사용자가 레코더 객체에서 중지 기능을 호출할 때 발생합니다. 이 경우 stop 이벤트가 호출되면 모든 트랙에서 스트림이 중지되고 변수isRecording가 false로 전환됩니다. 이 변수는 프로그램이 현재 화면을 녹화하고 있는지 여부를 설명합니다. 46행에서 start 레코더 객체의 함수가 500을 전달하는 동안 호출됩니다. 이 500은 ondataavailable 이벤트가 호출된 후의 간격을 설명하는 시간(밀리초)입니다. 더 큰 숫자는 더 긴 시간 간격을 나타냅니다.

이제 함수recordStart를 추가하여 startRecording 함수를 호출합니다. 이 함수는 또한 blobarr를 크기 0으로 재설정하고 isRecording을 true 상태로 전환합니다.

1  recordStart() {
2     this.isRecording = true;
3     this.blobarr.length = 0;
4     this.startRecording();
5   }

recordStop 개체에서 중지 기능을 호출하는 기능을 추가합니다recorder. 이 함수는 앞에서 설명한 레코드에서 stop 함수를 실행합니다.

1  recordStop() {
2     if (this.recorder) {
3       this.recorder.stop();
4       
5     }
6   }



이제 app.component.ts는 ..처럼 보일 것입니다.

1 import {
2   Component,
3   ElementRef,
4   OnDestroy,
5   OnInit,
6   ViewChild,
7 } from '@angular/core';
8 
9 const mediaDevices = navigator.mediaDevices as any;
10 declare var MediaRecorder: any;
11 
12 @Component({
13   selector: 'app-root',
14   templateUrl: './app.component.html',
15   styleUrls: ['./app.component.scss'],
16 })
17 export class AppComponent implements OnDestroy {
18   recorder: any;
19   stream: any;
20   frameCount: number = 0;
21   blobarr: any[] = [];
22   finalBlob: Blob | null = null;
23   isRecording: boolean = false;
24 
25   ngOnDestroy(): void {
26     this.blobarr.length = 0;
27     this.recordStop();
28   }
29 
30   async startRecording() {
31     var options;
32 
33     if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) {
34       options = {
35         videoBitsPerSecond: 2500000,
36         mimeType: 'video/webm; codecs=vp9',
37       };
38     } else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) {
39       options = {
40         videoBitsPerSecond: 2500000,
41         mimeType: 'video/webm; codecs=vp8',
42       };
43     } else {
44       options = { videoBitsPerSecond: 2500000, mimeType: 'video/webm' };
45     }
46 
47     try {
48       this.stream = await mediaDevices.getDisplayMedia({
49         screen: {
50           width: { min: 1024, ideal: 1280, max: 1920 },
51           height: { min: 576, ideal: 720, max: 1080 },
52           frameRate: { min: 10, ideal: 20, max: 25 },
53         },
54       });
55     } catch (err) {
56       alert('No devices found for recording.');
57     }
58     this.recorder = new MediaRecorder(this.stream, options);
59     let metadata: any;
60 
61     this.frameCount = 0;
62 
63     this.recorder.ondataavailable = (e: { data: any }) => {
64       this.blobarr.push(e.data);
65       this.frameCount += 1;
66     };
67 
68     this.recorder.onstop = (e: any) => {
69       this.isRecording = false;
70     };
71     this.recorder.start(500);
72   }
73 
74   downloadBlob() {
75     let downloadLink = document.createElement('a');
76     downloadLink.href = window.URL.createObjectURL(
77       new Blob(this.blobarr, { type: this.blobarr[0].type })
78     );
79     downloadLink.setAttribute('download', 'download.webm');
80     document.body.appendChild(downloadLink);
81     downloadLink.click();
82 
83     setTimeout(() => {
84       window.URL.revokeObjectURL(downloadLink.href);
85       document.body.removeChild(downloadLink);
86     }, 0);
87   }
88 
89   recordStop() {
90     if (this.recorder) {
91       this.recorder.stop();
92       this.stream.getTracks().forEach(function (track: any) {
93         track.stop();
94       });
95     }
96   }
97 
98   recordStart() {
99     this.isRecording = true;
100     this.blobarr.length = 0;
101     this.startRecording();
102   }
103 }
104 


이제 app.component.html로 이동하여 녹화를 시작하고 비디오를 다운로드하는 버튼을 추가하기 위한 아래 코드를 추가합니다.

1 <div *ngIf="!isRecording">
2   <button (click)="recordStart()">Start Recording</button>
3 </div>
4 <div *ngIf="isRecording">
5   <button (click)="recordStop()">Stop Recording</button>
6 </div>
7 
8 
9 <button (click)="downloadBlob()">Download</button>
10 


이제 ng serve -o 로 애플리케이션을 제공합니다. 녹화를 시작하고 중지한 다음 녹화된 스크린 캐스트를 다운로드할 수 있습니다.
다음은 분기part1에 있는 프로젝트 링크github입니다.
다음 부분에서는 비디오 청크를 수신할 스프링 부트 백엔드를 생성합니다. 계속 지켜봐 주세요.
감사.

좋은 웹페이지 즐겨찾기