TikTok Screenshot: 틱톡 영상 캡쳐 크롬 확장 앱 개발 후기
안녕하세요, 저는 최근 "TikTok Screenshot"이라는 크롬 확장 앱을 개발한 개발자입니다. 이 프로젝트는 사용자가 틱톡(TikTok) 영상을 손쉽게 캡쳐할 수 있도록 돕는 도구로서, 인스타그램 릴스와 마찬가지로 많은 분들이 필요로 하지만 공식적으로 제공되지 않는 기능을 구현하기 위해 시작되었습니다. 이번 글에서는 개발 과정과 최종적으로 적용된 Sidepanel 기반의 다운로드 방식, 그리고 CORS(Cross-Origin Resource Sharing) 문제를 해결하기 위해 사용한 우회 방법에 대해 상세히 설명드리겠습니다.
1. 프로젝트의 시작: 왜 TikTok Screenshot이 필요했을까?
1.1 문제 정의
틱톡은 짧고 재미있는 영상을 통해 전 세계적으로 큰 인기를 끌고 있는 소셜 미디어 플랫폼입니다. 특히 사용자들은 다음과 같은 이유로 틱톡 영상을 캡쳐하고 싶어 합니다:
- 콘텐츠 백업: 자신이 올린 영상을 보관하거나 재활용하고 싶음.
- 참고 자료 수집: 다른 크리에이터의 콘텐츠를 학습하거나 참고 자료로 활용.
- 공유 및 편집: 개인 프로젝트나 마케팅 용도로 활용.
하지만 틱톡 역시 인스타그램과 마찬가지로, 영상 화면을 쉽게 저장하거나 활용할 수 있는 공식적인 방법을 제공하지 않습니다. 그래서 저는 이러한 문제를 해결하기 위해 TikTok Screenshot이라는 크롬 확장 앱을 개발하기로 결심했습니다. 이번 버전에서는 영상 다운로드 기능은 제외하고, 틱톡 영상 화면 캡쳐에 집중하여 단순하면서도 직관적인 도구를 만들고자 했습니다.
2. 핵심 기능 설계: "캡쳐 → Sidepanel 이동 → 다운로드"의 구현
2.1 주요 기능
TikTok Screenshot의 핵심 기능은 다음과 같습니다:
- 틱톡 영상 캡쳐: 틱톡 영상을 정지 상태로 캡쳐하여 이미지 파일로 변환.
- Sidepanel로 이동: 캡쳐된 이미지를 바로 다운로드하지 않고, Sidepanel로 이동하여 사용자가 확인 또는 추가 작업을 할 수 있도록 설계.
- Sidepanel에서 다운로드: 사용자가 Sidepanel에서 원하는 이미지를 선택하여 다운로드.
이와 같은 설계는 사용자 경험(UX)을 고려한 선택으로, 캡쳐된 이미지를 즉시 다운로드하지 않고 한 번 더 확인할 수 있도록 하여 실수를 줄이고 사용자 친화적인 인터페이스를 제공합니다.
2.2 CORS 문제와 그 해결 방법
개발 과정에서 가장 큰 난관 중 하나는 CORS(Cross-Origin Resource Sharing) 문제였습니다. 틱톡의 영상은 외부 도메인에서 제공되며, 이를 직접 Canvas로 가져오려고 하면 보안 정책에 의해 차단됩니다. 이 문제를 해결하기 위해 아래와 같은 접근 방식을 사용했습니다:
2.2.1 Canvas를 화면에 띄워 우클릭 복사 기능 제공
Canvas 요소를 화면에 띄우고, 사용자가 우클릭 → 이미지 복사를 통해 수동으로 이미지를 복사하도록 설계했습니다. 이렇게 함으로써 CORS 제약 없이 캡쳐된 이미지를 활용할 수 있게 되었습니다.
function displayCanvasForCopy(videoElement) {
const canvas = document.createElement('canvas');
canvas.width = videoElement.videoWidth;
canvas.height = videoElement.videoHeight;
const ctx = canvas.getContext('2d');
ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
// Canvas를 화면에 표시
const container = document.createElement('div');
container.style.position = 'fixed';
container.style.top = '10px';
container.style.right = '10px';
container.style.zIndex = '9999';
container.appendChild(canvas);
document.body.appendChild(container);
// 사용자에게 안내 메시지 표시
alert('우클릭으로 이미지를 복사한 뒤, Sidepanel로 이동해 붙여넣기 해주세요.');
}
2.2.2 Sidepanel로 이미지 전송
사용자가 Canvas 이미지를 복사한 뒤, Sidepanel로 이동하여 붙여넣기를 하면 이미지가 Sidepanel에 표시되도록 구현했습니다. 이를 위해 paste
이벤트를 감지하고, 클립보드 데이터에서 이미지를 추출했습니다.
// Sidepanel 스크립트에서 클립보드 이벤트 처리
document.addEventListener('paste', (event) => {
const clipboardItems = event.clipboardData.items;
for (const item of clipboardItems) {
if (item.type.indexOf('image') !== -1) {
const blob = item.getAsFile();
const imageUrl = URL.createObjectURL(blob);
// 이미지를 Sidepanel에 표시
const img = document.createElement('img');
img.src = imageUrl;
document.getElementById('image-container').appendChild(img);
}
}
});
2.3 Sidepanel에서 이미지 다운로드
Sidepanel에서 이미지를 다운로드하기 위한 버튼을 추가하고, 사용자가 클릭하면 이미지가 로컬에 저장되도록 구현했습니다.
function downloadImage(imageUrl) {
const a = document.createElement('a');
a.href = imageUrl;
a.download = 'tiktok-screenshot.png';
a.click();
}
3. 개발 과정에서 겪었던 어려움
3.1 틱톡의 동적 DOM 구조
틱톡은 매우 동적이고 복잡한 DOM 구조를 가지고 있습니다. 특히 영상은 여러 계층의 <div>
와 <iframe>
으로 감싸져 있어, 정확한 비디오 요소를 식별하는 것이 쉽지 않았습니다. 이를 해결하기 위해 다음과 같은 방법을 사용했습니다:
- MutationObserver: DOM 변경 사항을 실시간으로 감지하여 비디오 요소를 찾는 데 활용.
- XPath: 특정 요소의 위치를 정확히 지정하기 위해 XPath를 사용.
3.2 크롬 확장 앱의 보안 제약
크롬 확장 앱은 보안 정책(CSP, Content Security Policy)로 인해 특정 기능을 제한합니다. 예를 들어, 외부 리소스에 직접 접근하거나 실행하는 것이 제한됩니다. 이를 해결하기 위해:
- 필요한 모든 리소스를 로컬에 포함.
manifest.json
파일에서 적절한 권한 설정.
{
"permissions": [
"activeTab",
"sidePanel"
],
"content_security_policy": "script-src 'self'; object-src 'self'"
}
4. 배운 점과 앞으로의 계획
4.1 배운 점
- 문제 해결 능력: 틱톡의 복잡한 DOM 구조와 크롬 확장 앱의 제약 조건을 극복하며 문제 해결 능력을 키웠습니다.
- CORS 문제 해결: Canvas를 화면에 띄워 우클릭 복사 방식으로 CORS 문제를 우회하는 방법을 배웠습니다.
- 사용자 중심 설계: Sidepanel을 도입하여 사용자가 캡쳐된 이미지를 한 번 더 확인할 수 있도록 UX를 개선했습니다.
- 피드백의 가치: 초기 버전을 출시한 뒤 사용자들의 피드백을 반영해 기능을 개선하는 과정이 큰 도움이 되었습니다.
4.2 앞으로의 계획
현재 TikTok Screenshot은 기본적인 캡쳐 및 Sidepanel 기반 다운로드 기능만 제공하지만, 앞으로 다음과 같은 기능을 추가할 계획입니다:
- 자동 배치 캡쳐: 여러 장면을 한 번에 캡쳐할 수 있는 기능.
- 편집 기능 추가: 캡쳐한 이미지를 간단히 편집할 수 있는 도구 제공.
- 다국어 지원: 글로벌 사용자를 위해 다양한 언어를 지원.
5. 마무리
TikTok Screenshot은 단순한 크롬 확장 앱이지만, 사용자들이 일상적으로 겪는 문제를 해결하기 위해 시작된 의미 있는 프로젝트였습니다. 특히 Sidepanel을 도입하고 CORS 문제를 우회한 점이 큰 성과라고 생각합니다. 개발 과정에서 많은 어려움도 있었지만, 이를 극복하며 성장한 저 자신을 돌아보게 됩니다. 앞으로도 사용자들의 요구를 경청하며 더욱 나은 서비스를 제공하기 위해 노력하겠습니다.
이 글을 읽으시는 분들 중에서도 크롬 확장 앱 개발에 관심이 있으신 분들이 있다면, 꼭 도전해 보시기를 바랍니다. 작은 아이디어가 큰 변화를 만들 수 있다는 것을 직접 경험하실 수 있을 겁니다. 😊
감사합니다!