-
Broken Youtube Thumbnail error callback기타/메모장 2023. 10. 25. 20:50
Youtube Thumbnail URL
유튜브 썸네일을 이미지로 가져오기 위한 URL은 아래와 같다.
https://img.youtube.com/vi/{videoID}/{type}.jpg
https://i.ytimg.com/vi/{videoID}/{type}.jpg이때 videoID에는 유튜브에서 제공하는 비디오의 id를 넣고, type에는 가져올 이미지의 해상도를 타입에 맞게 입력한다. 사용할 수 있는 타입은 아래와 같다.
Resolution Type 320 x 180 mqdefault 480 x 360 0 720p or 1080p maxresdefault 업로더가 직접 업로드한 썸네일 original source original Broken Youtube Thumbnail
문제는 썸네일이 제대로 작동하지 않을 때이다. 보통 이미지 태그에 잘못된 src를 사용하여 이미지 로딩이 제대로 진행되지 않으면 흔히 엑스박스라고 하는 형태로 이미지가 깨지기 마련이다. 이때는 img태그에 onerror 속성을 사용하면 이러한 에러를 처리할 수 있다.
문제는 유튜브 썸네일 URL이 지나치게 친절하다는 것이다. 이미지를 가져오지 못했다면 에러를 만들어야 하지만, 너무나도 친절한 나머지 대체 이미지를 자동으로 줘버린다. 하하! 너무 고맙다.
덕분에 onerror 방식을 사용하려고 해도 정상적으로 작동하지 않는다. 대체된 이미지가 정상적으로 표시되기 때문이다. 하.. 그럼 원하는 대로 에러처리를 하고 싶을 땐 어떻게 하는 게 좋을까?
여러 방법을 찾아보았지만 그나마 가장 명확하면서 효과적으로 동작하는 방법이 있어서 소개해본다. 우리들의 영원한 친구 스택 오버플로우에서 찾은 내용이다.
해결법
우선 유튜브 썸네일을 가져옴에 있어 onerror 함수가 동작하지 않는 것은 유튜브가 base64 gif 형태의 이미지를 대체로 보내기 때문이다. 이때 해당 이미지의 해상도는 120 x 90이고, 이를 핵심으로 하여 에러를 임의로 발생시켜야 한다.
이를 위해 onload 속성을 사용한다. onerror는 비록 동작하지 않지만, 어찌 되었든 이미지가 로드되는 순간 onload는 동작한다. 이 onload 함수에서 에러 처리를 할 이미지 태그에서 naturalHeight 속성을 확인한다. 만약 해당 속성이 90 이하라면 이는 대체 이미지라고 판단하면 된다.
React 예시
나는 이번에 React를 사용하면서 이 문제를 해결해야 했기 때문에 React에서의 이 에러 처리방법을 예시로 보여주겠다. 물론 꼭 React가 아니더라도 이 개념을 이용한다면 vanilla javascript에서도 무리 없이 사용할 수 있다.
import { useRef, useState } from 'react' export default function YtThumbImg(props: IProps) { const [isError, setIsError] = useState(false) const imgREF = useRef<HTMLImageElement>(null) const errorHandler = () => { if (!imgREF.current) return if (imgREF.current?.naturalHeight > 90) return setIsError(true) } return isError ? ( <img src="/images/alternatives.png" alt="thumbnail error" /> ) : ( <img src={props.src} alt={props.alt} ref={imgREF} onLoad={errorHandler} /> ) }