Notice
Recent Posts
Recent Comments
Link
투케이2K
336. (javaScript) 자바스크립트 video 비디오 태그에 재생 중 인 stream 스트림 을 캔버스 화면 녹화로 저장 실시 - canvas record 본문
JavaScript
336. (javaScript) 자바스크립트 video 비디오 태그에 재생 중 인 stream 스트림 을 캔버스 화면 녹화로 저장 실시 - canvas record
투케이2K 2023. 10. 30. 18:24[개발 환경 설정]
개발 툴 : Edit++
개발 언어 : JavaScript
[소스 코드]
<!-- ===================================================================================================== -->
<!-- [자바스크립트 코드 지정] -->
<!-- ===================================================================================================== -->
<script>
// =======================================================================
// [캔버스 비디오 재생 녹화 시작 중지 관련]
// =======================================================================
var interval; // [지속적으로 캔버스에 비디오 이미지 그림]
var videoView; // [비디오 뷰]
var canvas; // [캔버스]
var recorder; // [녹화 영상 저장]
const arrVideoData = []; // 스트림 데이터를 담아둘 배열 생성
function startVideoPlay(){
console.log("");
console.log("=========================================");
console.log("[startVideoPlay] : [start]");
console.log("----------------------------------------");
console.log("[설 명] : 비디오 재생 및 상태 감지");
console.log("=========================================");
console.log("");
// [로직 처리 실시]
try {
// [비디오 재생 컴포넌트 지정]
videoView = document.getElementById("videoView");
// [캔버스 컴포넌트 지정]
canvas = document.getElementById("canvas");
// [캔버스 사이즈 지정 실시]
var width = videoView.clientWidth;
var height = videoView.clientHeight;
canvas.height = height;
canvas.width = width;
// [캔버스 getContext 지정]
var ctx = canvas.getContext("2d");
// [비디오 재생 상태 감지 이벤트 리스너 등록]
videoView.onerror = (event) => {
console.error("");
console.error("=========================================");
console.error("[startVideoPlay] : 원격 비디오 뷰 컴포넌트 : onerror");
console.error("=========================================");
console.error("");
// [인터벌 중지]
if (interval != null){
window.clearInterval(interval);
interval = null;
}
};
videoView.onwaiting = (event) => {
console.log("");
console.log("=========================================");
console.log("[startVideoPlay] : 원격 비디오 뷰 컴포넌트 : onwaiting");
console.log("=========================================");
console.log("");
};
videoView.onpause = (event) => {
console.error("");
console.error("=========================================");
console.error("[startVideoPlay] : 원격 비디오 뷰 컴포넌트 : onpause");
console.error("=========================================");
console.error("");
// [인터벌 중지]
if (interval != null){
window.clearInterval(interval);
interval = null;
}
};
videoView.onplaying = (event) => {
console.warn("");
console.warn("=========================================");
console.warn("[videoJsPlay] : 원격 비디오 뷰 컴포넌트 : onplaying");
console.warn("=========================================");
console.warn("");
// [캔버스 그리기]
if (ctx != null){
interval = window.setInterval(function() {
ctx.drawImage(videoView, 0, 0, canvas.width, canvas.height);
}, 10);
}
};
// [비디오 재생에 필요한 SRC 지정]
videoView.setAttribute("src","https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"); // 동영상 주소
// [비디오 재생 수행]
videoView.play();
}
catch (error){
// [에러 발생 내용 확인]
console.error("");
console.error("=========================================");
console.error("[startVideoPlay] : [Exception]");
console.error("--------------------------------------");
console.error("[all error] : " + error);
console.error("--------------------------------------");
console.error("[error stack] : " + error.stack);
console.error("=========================================");
console.error("");
// [에러 팝업창 표시]
alert("[startVideoPlay] :: [Exception] :: " + error);
}
};
function canvasRecordStart(){
console.log("");
console.log("=========================================");
console.log("[canvasRecordStart] : [start]");
console.log("----------------------------------------");
console.log("[설 명] : 캔버스 비디오 녹화 시작");
console.log("=========================================");
console.log("");
// [로직 처리 실시]
try {
// [실시간 영상 재생 여부 체크]
if (interval == null){
// [에러 팝업창 표시]
alert("[canvasRecordStart] :: [Error] :: 비디오 재생 여부를 확인해 주세요");
return
}
// 캔버스 영역 화면을 스트림으로 취득
const mediaStream = canvas.captureStream();
// MediaRecorder(녹화기) 객체 생성
mediaRecorder = new MediaRecorder(mediaStream);
// MediaRecorder.dataavailable 이벤트 처리
mediaRecorder.ondataavailable = (event)=>{
console.log("[canvasRecordStart] : [add] : stream data");
// 스트림 데이터(Blob)가 들어올 때마다 배열에 담아둔다
arrVideoData.push(event.data);
}
// MediaRecorder.stop 이벤트 처리
mediaRecorder.onstop = (event)=>{
console.log("");
console.log("=========================================");
console.log("[canvasRecordStart] : [onstop]");
console.log("----------------------------------------");
console.log("[설 명] : 캔버스 비디오 녹화 종료 >> 비디오 파일 저장 실시");
console.log("=========================================");
console.log("");
// 들어온 스트림 데이터들(Blob)을 통합한 Blob객체를 생성
const blob = new Blob(arrVideoData);
// BlobURL 생성: 통합한 스트림 데이터를 가르키는 임시 주소를 생성
const blobURL = window.URL.createObjectURL(blob);
// 다운로드 구현
const anchor = document.createElement("a"); // 앵커 태그 생성
document.body.appendChild(anchor); // body 에 추가
anchor.style.display = "none";
anchor.href = blobURL; // 다운로드 경로 설정
anchor.download = "twok.webm"; // 파일명 설정
anchor.click(); // 앵커 클릭 >> 다운로드
// 배열 초기화
arrVideoData.splice(0);
// [팝업창 표시]
alert('캔버스 녹화가 종료 되었습니다.');
}
// MediaRecorder 녹화 시작
mediaRecorder.start(1000);
// [팝업창 표시]
alert('캔버스 녹화가 시작 되었습니다.');
}
catch (error){
// [에러 발생 내용 확인]
console.error("");
console.error("=========================================");
console.error("[canvasRecordStart] : [Exception]");
console.error("--------------------------------------");
console.error("[all error] : " + error);
console.error("--------------------------------------");
console.error("[error stack] : " + error.stack);
console.error("=========================================");
console.error("");
// [에러 팝업창 표시]
alert("[canvasRecordStart] :: [Exception] :: " + error);
}
};
function canvasRecordStop(){
console.log("");
console.log("=========================================");
console.log("[canvasRecordStop] : [start]");
console.log("----------------------------------------");
console.log("[설 명] : 캔버스 비디오 녹화 종료");
console.log("=========================================");
console.log("");
// [로직 처리 실시]
try {
// [실시간 영상 재생 여부 체크]
if (interval == null){
// [에러 팝업창 표시]
alert("[canvasRecordStop] :: [Error] :: 비디오 재생 여부를 확인해 주세요");
return
}
// [미디어 레코드 널 체크]
if (mediaRecorder == null){
// [에러 팝업창 표시]
alert("[canvasRecordStop] :: [Error] :: mediaRecorder Is Null");
return
}
else {
console.log("");
console.log("=========================================");
console.log("[canvasRecordStop] : [mediaRecorder]");
console.log("----------------------------------------");
console.log("[설 명] : 캔버스 비디오 녹화 종료 수행");
console.log("=========================================");
console.log("");
// [인터벌 중지]
if (interval != null){
window.clearInterval(interval);
interval = null;
}
// [비디오 재생 정지]
if (videoView != null){
videoView.pause();
}
// [녹화 중지 처리]
mediaRecorder.stop();
}
}
catch (error){
// [에러 발생 내용 확인]
console.error("");
console.error("=========================================");
console.error("[canvasRecordStop] : [Exception]");
console.error("--------------------------------------");
console.error("[all error] : " + error);
console.error("--------------------------------------");
console.error("[error stack] : " + error.stack);
console.error("=========================================");
console.error("");
// [에러 팝업창 표시]
alert("[canvasRecordStop] :: [Exception] :: " + error);
}
};
</script>
<body>
<!-- ===================================================================================================== -->
<!-- [body 생성] -->
<!-- ===================================================================================================== -->
<!-- ----------------------------------------------------------------------------------------------------- -->
<!-- 웹 화면 녹화 -->
<!-- ----------------------------------------------------------------------------------------------------- -->
<div class="divTagContentWidthLargeClass" style="height: 1px; background-color: #000000; top: 57%;"></div>
<!-- [비디오 컨테이너] -->
<div class="divTagContentWidthLargeClass" style="height: 5%; background-color: #ffffff; top: 59%; border: none;">
<p class="pTagContentMiddleClass" style="color:#000;"> 비디오 뷰 </p>
</div>
<div class="divTagContentWidthLargeClass" style="height: 25%; background-color: none; top: 59%;">
<video id="videoView" crossOrigin="anonymous" controls autoplay preload="auto" muted="muted" style="width: 100%; height: 100%; margin: 0 auto; padding: 0; position: relative; top: 0%; left: 0%;"></video>
</div>
<!-- [캔버스 컨테이너] -->
<div class="divTagContentWidthLargeClass" style="height: 5%; background-color: #ffffff; top: 60%; border: none;">
<p class="pTagContentMiddleClass" style="color:#000;"> 캔버스 영역 </p>
</div>
<div class="divTagContentWidthLargeClass" style="height: 25%; background-color: none; top: 60%;">
<canvas id="canvas" width="100%" height="100%"></canvas>
</div>
<!-- [비디오 재생 버튼] -->
<div class="divTagContentWidthLargeClass" style="height: 8%; background-color: #000000; top: 61%;"
onclick="startVideoPlay();">
<p class="pTagContentMiddleClass"> [startVideoPlay] 비디오 재생 실시 </p>
</div>
<!-- [캔버스 녹화 시작] -->
<div class="divTagContentWidthLargeClass" style="height: 8%; background-color: #000000; top: 62%;"
onclick="canvasRecordStart();">
<p class="pTagContentMiddleClass"> [canvasRecordStart] 캔버스 녹화 시작</p>
</div>
<!-- [캔버스 녹화 종료] -->
<div class="divTagContentWidthLargeClass" style="height: 8%; background-color: #000000; top: 63%;"
onclick="canvasRecordStop();">
<p class="pTagContentMiddleClass"> [canvasRecordStop] 캔버스 녹화 종료</p>
</div>
</body>
반응형
'JavaScript' 카테고리의 다른 글
Comments