본문 바로가기
WEB/일반

[JS] canvas를 이용해서 mp4 영상에서 배경 제거하기 (크로마키 기능)

by IT황구 2025. 1. 25.
728x90
반응형

안녕하세요. 오랜만에 글을 쓰는 것 같습니다.

 

오늘은 배경색이 있는 mp4 파일에서 배경을 제거하는 방법을 알아보겠습니다.

 

PoC로 만들고 꽤 괜찮았지만, 여러 문제가 있어 결국 다른 방법을 택했습니다. 하지만 만들었던게 아까워서 글로 남깁니다.

 

기능을 개발하게 된 계기

요약

  • 30MB apng 렌더링 -> 다운로드 속도가 너무 느림 -> 용량 압축을 위해 webp 사용 -> 사파리에서 영상이 끊기는 문제 -> mp4 시도 -> 배경색이 투명하게 되지 않는 문제

 

요즘은 회사에서 이벤트 페이지를 개발하고 있습니다. 이벤트 페이지의 특성상 최대한 가볍게 만들어서 빠르게 유저와 인터랙션 해야하는데요. 초기 로딩을 빠르게 하기 위해 react 같은 라이브러리 없이 vanilla js만을 이용해서 개발하고 있습니다.

 

이번엔 룰렛이 돌아가는 기능을 개발해야 했습니다. js로 직접 구현이 아닌 여러 이유로 APNG 파일을 재생하는 방향으로 정했었습니다.

 

다만, 처음 APNG를 전달받았을 때 용량이 30MB나 되는 문제가 있었는데요. webp로 확인해보니 용량은 줄었지만 사파리에서 최적화가 덜 되었는지 렉이 좀 있었습니다.

 

mp4를 사용해보니 용량도 webp처럼 줄고 다른 브라우저에서도 재생이 잘 되었습니다. 하지만 Modal의 배경 색상과 mp4 파일의 배경이 겹쳐 색상이 맞지 않는 문제가 있었습니다. 

 

mp4는 투명도를 지원하지 않아서 발생하는 문제였고 크로마키 기능을 통해서 배경색을 제거하는 시도를 했었습니다.

 

구현 방법

https://developer.mozilla.org/ko/docs/Web/API/Canvas_API/Manipulating_video_using_canvas

 

캔버스(canvas)를 이용한 비디오 조작하기 - Web API | MDN

비디오에서 다양한 시각적 효과를 보여주기 위해,캔버스와 비디오의 기능을 결합하여 실시간으로 비디오 데이터를 조작할 수 있습니다. 이 튜토리얼에서는 JavaScript 코드로 어떻게 크로마 키잉(

developer.mozilla.org

 

처음에 문서를 읽어보면 잘 와닿지 않는데요. 정리하면 굉장히 간단합니다.

  • mp4 파일을 캔버스에 렌더링 한다. (재귀적으로 호출해서 매 비디오 프레임마다 새롭게 그리는 방식)
  • 매 프레임마다 캔버스에 렌더링 할 때 원하는 색상을 투명하게 해서 렌더링 한다.

투명하게 하는 방법은 (r,g,b,a) 에서 alpha 값에 0을 넣는 방식으로 처리합니다.

 


위 예시에서 비디오를 플레이하면 특정 영역이 하얗게 보이는 것을 볼 수 있습니다. 특정 색상 부분들의 alpha 값이 0으로 되어 그런 것인데요.

 

배경색이 단일 색상일 경우 원하는 배경의 색상만 투명하게 처리할 수 있습니다.

 

실제 사용했던 영상은 배경이 검정색이었고, 배경색의 rgb 값을 특정해서 원하는 부분만 오려낼 수 있었습니다.

 

문제점

배경이 아닌 물체들도 투명하게 변할 수 있다

  • 특정 rgb 값을 모두 투명하게 하는 것이라, 원하는 영역만 투명하게 하긴 어렵습니다. (특정 위치의 rgb 값을 스킵하거나 해야하겠죠) 유튜브를 보면 초록색 옷 입은 경우 얼굴만 둥둥 떠다니는 경우가 있는데, 왜 그런지 이해가 됐습니다. 

 

OS에 따라 rgb 값이 조금씩 다르다

  • 이건 크로마키 방식의 문제라기 보다는 색상을 처리하는 OS의 문제입니다. Mac Chrome, Safari 브라우저에서 #0B0B0B (11, 11, 11) 은 모바일 환경에서 다른 색상이었습니다.
    • Chrome, Safari : #0B0B0B (11, 11, 11)
    • Safari on IOS : #0E0E0E (14, 14, 14)
    • Android : #0F0E0F (15, 14, 15)

 

따라서 특정 rgb 값만 제거할 경우, 사이트에 접속하는 환경에 따라 투명 처리를 하지 못할 수 있습니다. 

 

이런 문제로 적용하기 어려운 점이 있었습니다.

 

투명 배경을 지원하는 webm, mov 같이 사용하기

위와 같은 문제가 있다면 이런 생각이 들 수 있습니다. chrome은 webm, Safari는 mov를 통해서 배경이 없는 영상을 재생할 수 있지 않나?

 

맞습니다. 하지만 위 방식의 경우 다음과 같은 단점이 있습니다.

 

1. 파일을 2개씩 관리해야한다.

2.mov 파일의 경우 용량이 크다.

 

2번의 단점으로 인해 용량 문제로 시작했던 이슈가 다시 용량 문제로 돌아오게 됩니다.

 

실제로 mov 파일을 받았을때 40MB 가량 됐었고, 이 방법을 선택할 수 없었습니다.

 

iOS의 저전력 모드는 mp4 파일이 자동재생이 되지 않는다.

실제 스펙은 모바일에서 영상이 자동으로 재생되어야 했습니다.

 

하지만 저전력모드의 경우 영상이 자동재생 되지 않는 정책이라 큰 문제가 됐습니다. 우회하는 방법들도 있지만, 결국 유저의 터치가 한 번이라도 있어야 했기에 해당 방법은 사용할 수 없었습니다.

 

마무리

위의 단점 외에도 영상을 캔버스로 옮기면서 화질이 조금 떨어져 보이는 이슈도 있었습니다.

 

결론적으로는 디자이너분이 APNG를 작게 최적화 해주셨습니다. (프레임 별 해상도, 프레임 수 조절) 그리고 APNG를 preload 하는 방식으로 유저가 빠르게 영상을 볼 수 있게 수정했습니다.

 

처음부터 그렇게 하지.. 라고 생각할 수 있지만, APNG 최적화가 어려워 보이는 상황이라 답을 빠르게 찾아야 했었기에 이런 방법을 시도하게 되었습니다.

 

이번 프로젝트에서 mp4, mov, webm 같은 확장자에 대해서도 다시 공부할 수 있었고 브라우저, OS의 배경색 차이, 용량, 동작 차이등에 대해서도 직접 겪어볼 수 있었습니다.

 

동영상의 배경색 관련 이슈 해결에 도움이 되었으면 좋겠습니다.

 

감사합니다.

728x90
반응형