Flickr는 고해상도 사진 공유 플랫폼으로 잘 알려져 있지만, 비디오 콘텐츠의 저장소로서도 상당한 비중을 차지합니다. 하지만 개발자나 데이터 분석가 입장에서 Flickr의 비디오 데이터를 추출하는 것은 꽤나 까다로운 작업입니다. 단순한 src 태그 추출만으로는 고화질 소스에 접근할 수 없기 때문입니다.
본 포스팅에서는 제가 개발한 Flickr 비디오 다운로더를 구축하면서 마주한 기술적 과제들과 이를 해결하기 위한 엔지니어링 접근법을 공유하고자 합니다.
1. Flickr 미디어 전달 프로토콜의 이해
Flickr의 비디오 렌더링 방식은 일반적인 소셜 미디어와 다릅니다. 이들은 사용자 경험 최적화를 위해 Dynamic Adaptive Streaming과 유사한 구조를 사용하며, 클라이언트 사이드에서 복잡한 JavaScript 로직을 통해 소스를 할당합니다.
주요 장애물:
• 비정형 데이터 구조: 비디오 URL은 HTML 소스 내에 직접 노출되지 않고, 특정 JSON 객체(modelExport) 내부에 중첩되어 있습니다.
• CDN 토큰 만료: Flickr의 비디오 CDN(Edgecast 또는 자체 인프라)은 시한성 토큰을 사용하여 직접적인 핫링크를 방지합니다.
• 다양한 해상도 분기: 하나의 영상에 대해 orig, 720p, 360p 등 수많은 버전이 존재하며, 이를 동적으로 매핑해야 합니다.
2. 시스템 아키텍처 설계
확장성과 유지보수를 위해 저는 다음과 같은 마이크로서비스 지향적 설계를 채택했습니다.
기술 스택
• Frontend: Next.js 14 (App Router) - SEO 및 빠른 SSR 응답성 확보.
• Backend: Node.js (TypeScript) - 비동기 I/O 처리를 통한 고성능 스크레이핑.
• Core Engine: Python (Playwright) - 복잡한 JS 렌더링 페이지 해석용.
• Cache: Redis - 동일 URL에 대한 반복적인 요청 분석 방지 및 레이트 리밋 제어.
3. 핵심 기술 구현: 리버스 엔지니어링 및 추출
3.1 JSON 페이로드 파싱 (Deep Extraction)
Flickr 페이지를 로드할 때, 브라우저는 내부적으로 Y.UI 혹은 현대화된 React State 객체를 생성합니다. 저희 엔진은 정규표현식과 AST(Abstract Syntax Tree) 파싱을 결합하여 이 데이터에서 비디오 매니페스트를 추출합니다.
TypeScript
// 추출 로직의 개념적 예시
const extractFlickrMetadata = (htmlContent: string) => {
const regex = /modelExport:\s*({.*?}),\s*auth/s;
const match = htmlContent.match(regex);
if (!match) throw new Error("Metadata not found");
const rawData = JSON.parse(match[1]);
return rawData['video-player-models'][0].videoSources.map(source => ({
quality: source.type,
url: source.url,
width: source.width,
height: source.height
}));
};
3.2 Headless 브라우저 최적화
단순 HTTP GET 요청으로 데이터가 누락되는 경우, Playwright를 활용합니다. 하지만 브라우저 인스턴스는 메모리 소모가 크기 때문에 다음과 같은 최적화를 적용했습니다.
- Request Interception: 이미나 글꼴(.woff, .jpg) 요청을 차단하여 대역폭 80% 절감.
- Stealth Mode: navigator.webdriver 탐지를 우회하여 봇 차단 메커니즘 회피.
- Cluster Pool: 브라우저 컨텍스트를 재사용하여 Cold Start 시간 단축.
4. 해결해야 했던 난제: 해상도 우선순위 알고리즘
사용자는 항상 "최고 화질"을 원합니다. 하지만 Flickr API나 소스 데이터에서 제공하는 original 태그가 항상 최고 화질을 보장하지는 않습니다. 저희는 다음과 같은 수식에 기반하여 최적의 스트림을 선택합니다.
$$V_{score} = (Width \times Height) + Bitrate_{est}$$
이를 통해 가변 비트레이트(VBR) 상황에서도 사용자가 수동으로 선택할 필요 없이 가장 선명한 영상을 우선적으로 서빙합니다.
5. 보안 및 데이터 무결성
Flickr Video Downloader는 사용자 프라이버시를 최우선으로 합니다.
• No Logs Policy: 입력된 URL은 변환 즉시 메모리에서 제거됩니다.
• End-to-End Encryption: 모든 데이터 전송은 TLS 1.3을 통해 보호됩니다.
• CORS 보호: API 엔드포인트는 허용된 오리진에서만 접근 가능하도록 설정되어 있습니다.
6. 결론 및 향후 계획
Flickr와 같은 대형 플랫폼의 미디어를 추출하는 도구를 만드는 것은 단순한 코딩을 넘어, 해당 플랫폼의 프론트엔드 아키텍처를 깊이 있게 이해하는 과정이었습니다.
현재 제공되는 Flickr 비디오 다운로더는 시작에 불과합니다. 향후 다음과 같은 업데이트를 준비하고 있습니다.
- Batch Download 지원: 앨범 전체의 비디오를 한 번에 아카이빙하는 기능.
- CLI 도구 출시: 개발자들이 터미널에서 즉시 사용할 수 있는 npm 패키지 공개.
- AI 업스케일링 연동: 저화질 구형 Flickr 영상을 4K로 변환하여 다운로드하는 실험적 기능. 이 프로젝트에 관심이 있거나 기술적으로 궁금한 점이 있다면 언제든 댓글로 소통해 주세요. 개발자로서 더 나은 도구를 만들기 위한 피드백은 언제나 환영입니다!
Tags: #javascript #typescript #webscraping #python #devops #flickr #videodownloader

Top comments (0)