URL.createObjectURL

SteadySlower·2024년 12월 23일
0

Javascript&TypeScript

목록 보기
3/4
post-thumbnail

URL.createObjectURL은 브라우저에서 파일 객체, Blob 객체, 또는 미디어 소스를 가리키는 임시 URL을 생성하는 기능이다. 이를 통해 브라우저의 메모리 내에서 임시적으로 데이터에 접근할 수 있다. 이 URL은 외부 데이터 (file system 혹은 network)를 가져올때 사용하는 URL처럼 사용할 수 있다.


개념

URL.createObjectURL은 브라우저의 메모리 내 객체를 참조하는 고유한 URL을 생성한다. 생성된 URL은 브라우저 환경에서만 유효하며, 외부 네트워크 요청 없이 해당 데이터에 접근할 수 있다.

“브라우저” 환경에서만 유효하다는 말은 nodejs에서는 사용할 수 없다는 의미이다. 생성된 URL이 가르키는 위치는 “브라우저” 메모리이기 때문이다.

사용법

const url = URL.createObjectURL(object);
  • object: File이나 Blob 같은 객체를 받는다.
  • 리소스 해제: URL은 사용이 끝나면 URL.revokeObjectURL(url)로 해제해야 메모리 누수를 방지할 수 있다.

예시 코드 1: 이미지 미리보기 구현

input file을 통해서 파일을 선택하면 기본적으로 input에는 이미지 파일의 이름만 볼 수 있다. 아래와 같은 코드로 선택된 파일의 URL을 가지고 올 수 있다면 img 태그를 활용해서 선택된 이미지를 보여줄 수 있다.

메모리 누수를 방지하기 위해서 URL.revokeObjectURL를 사용하는 것도 잊지 말자.

import { useState } from "react";

export default function ImagePreview() {
  const [preview, setPreview] = useState(""); // 미리보기 URL 저장

  const onImageChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const {
      target: { files },
    } = event;
    if (!files || files.length === 0) return;

    const file = files[0]; // 첫 번째 파일 가져오기
    const url = URL.createObjectURL(file); // URL 생성
    setPreview(url); // 미리보기로 설정
  };
  
  // 메모리 누수 방지
  useEffect(() => URL.revokeObjectURL(preview), [])

  return (
    <div>
      <form>
        {preview === "" ? (
					<span>사진을 추가해주세요.</span>
        ) : <img src={preview} alt={"preview image"}>}
        <input
          id="photo"
          type="file"
          accept="image/*"
          onChange={onImageChange}
        />
      </form>
    </div>
  );
}

예시 코드 2: Blob 데이터를 Howler.js로 재생하기

오디오 재생을 위해서 Howler.js라는 라이브러리를 사용하는 프로젝트가 있었다. Howler.js의 경우 Howl 객체를 만드는데 Blob 데이터를 사용해서 재생을 하고 싶을 때는 아래와 같이 createURL을 사용해야 한다.

import { Howl } from "howler";

export default function PlayAudio({ blob }: { blob: Blob }) {
  const playAudio = () => {
    const url = URL.createObjectURL(blob); // Blob 객체로부터 URL 생성
    const sound = new Howl({
      src: [url],
      format: ["wav"], 
      html5: true, 
    });

    sound.play();

    // 재생이 끝나면 URL 해제
    sound.on("end", () => {
      URL.revokeObjectURL(url);
    });
  };

  return (
    <button onClick={playAudio} className="px-4 py-2 bg-blue-500 text-white rounded">
      오디오 재생
    </button>
  );
}
profile
백과사전 보다 항해일지(혹은 표류일지)를 지향합니다.

0개의 댓글