yyZa

RecordRTC로 Canvas 애니메이션 녹화하기(feat. 오류많음) 본문

개발일지

RecordRTC로 Canvas 애니메이션 녹화하기(feat. 오류많음)

yyza 2024. 5. 22. 11:03
반응형

🥑RecordRTC라이브러리 설치

https://github.com/muaz-khan/RecordRTC

 

GitHub - muaz-khan/RecordRTC: RecordRTC is WebRTC JavaScript library for audio/video as well as screen activity recording. It su

RecordRTC is WebRTC JavaScript library for audio/video as well as screen activity recording. It supports Chrome, Firefox, Opera, Android, and Microsoft Edge. Platforms: Linux, Mac and Windows. - mu...

github.com

npm i recordrtc

 

🥑오디오와 같이 Canvas를 녹화하기

내 프로젝트는 오디오와 함께 canvas의 움직임을 캡쳐 하여 녹화해야 하므로 Stream 두가지를 함께 섞을 필요가 있엇다.

(깃헙에 올라와 있는 오디오와 함께 녹화하는 레퍼런ㄴ스는 넌무 오래되어서 도움이 되지 않았다.)

 

1. 오디오 현재 탭에서 녹음하기

    - preferCurrentTab을 true로 설정하면 현재탭을 녹음할 수 있다.(다른탭 선택하지 않게 주의!)

const captureWindow = navigator.mediaDevices.getDisplayMedia({
		audio: true,
		preferCurrentTab: true,
		video: { mediaSource: 'screen' },
});

 

2. captureWindow의 Audio Stream과 Canvas의 Media Stream 합치기 or 녹화

    - finalStrem으로 비어있는 MedioaStream을 만들어준다.

    - getVideoTracks()로 각 Stream의 track을 추출해서 finalStream에 추가한다.

    - RecordRTCPromisesHandler를 사용하여 finalStram의 속성을 설정해준다. (이 부분 오류발생! 아래서 설명

    - recorder.startRecording을 시작하고 settimeout으로 재생시간을 설정하고 recorder.stopRecording

    - stopRecording이 끝나면 recorder.getBlob()값으로 생성되는 blob을 사용하면된다. (여기서도 오류 ! 아래서  설명)

await captureWindow
		.then((audioStream) => {
			let finalStream = new MediaStream();
			let canvasStream = appCanvas.view.captureStream();

			canvasStream.getVideoTracks().forEach(function (track) {
				finalStream.addTrack(track);
			});
			audioStream.getAudioTracks().forEach(function (track) {
				finalStream.addTrack(track);
			});

			
			let recorder = new RecordRTCPromisesHandler(finalStream, {
				type: 'video',
				videoBitsPerSecond: 256 * 8 * 1024,
				bitsPerSecond: 256 * 8 * 1024, // if this is provided, skip above two
				checkForInactiveTracks: true,
				mimeType: 'video/webm;codecs=vp9',
			});

			recorder.startRecording();
			webToonAnimation.playAnimationFn(timeLine);
                
			setTimeout(async () => {
				await recorder.stopRecording(async () => {
					const fixBlob = await fixWebmDuration(recorder.getBlob());
					store.blob = fixBlob;

					screenStream.getTracks().forEach((track) => track.stop());
					webToonAnimation.stopAnimationFn(timeLine);
				});
			}, projectStore.recordingTime * 1000);
			
		})
		.catch((err) => {
			alert('녹화가 정상적으로 진행되지 않았습니다. 현재 탭과 오디오를 공유해주세요!');
			console.log(err);

		});

🥑적용하면서 생긴 오류들

1.  RecordRTCPromisesHandler를 사용하여 finalStram의 속성을 설정 에러

    - RecordRTCPromisesHandler를 사용하여 finalStram의 속성을 설정해줄때 mimetype을 크롬에서 지원하는 codec으로 설정해야한다. 그렇지 않으면  video/x-matroska;codecs=avc1,opus <<type으로 자동설정 되므로 이건 크롬에서 지원하지 않는다. 다운로드 받은 blob의 duration이 설정되지 않아 미디어를 재생할 때 시간 탐색이 되지 않는다.

 

2. RecordRTC의 getSeekableBlob() 오류

    - 기본적인 Blob에는 Duration이 설정되있지 않아서 탐색이 가능한 Blob으로 컨버트해줘야 하는데 recordrtc의 getseekableBlob을 사용하면 된다고 깃헙에는 나와있지만 사용할 시 Ebml라이브러리의  "No schema entry found for unknown" 이라는 에러가 발생한다. 해서 ts-ebml을 설치하여 직접 컨버트를 시도 했지만 정상적으로 seekableBlob이 추출되지 않는다.

3. webm-duration-fix라이브러리 적용하여 seekableBlob 추출하기

    - 설치

npm i webm-duration-fix

import fixWebmDuration from 'webm-duration-fix';

 

   - 사용코드 

const fixBlob = await fixWebmDuration(recorder.getBlob());
반응형