자동 재생 정책 감지

W3C 워킹 드래프트,

이 문서에 대한 추가 정보
이 버전:
https://www.w3.org/TR/2025/WD-autoplay-detection-20250904/
최신 공개 버전:
https://www.w3.org/TR/autoplay-detection/
에디터 드래프트:
https://w3c.github.io/autoplay/
이전 버전:
히스토리:
https://www.w3.org/standards/history/autoplay-detection/
피드백:
GitHub
에디터:
(Mozilla)

초록

이 명세는 웹 개발자가 다양한 상황에서 미디어 파일의 자동 재생이 허용되는지 감지할 수 있는 기능을 제공합니다.

문서 상태

이 섹션은 문서가 공개될 당시의 상태를 설명합니다. 최신 W3C 출판 목록과 이 기술 보고서의 최신 개정판은 W3C 표준 및 초안 색인에서 확인할 수 있습니다.

이 명세에 대한 피드백과 의견을 환영합니다. GitHub Issues에서 명세 관련 토론을 진행하는 것을 권장합니다. 또는 미디어 워킹 그룹의 메일링 리스트 public-media-wg@w3.org (아카이브)로 의견을 보낼 수 있습니다. 이 드래프트는 워킹 그룹에서 아직 논의 중인 일부 대기 중인 이슈를 강조합니다. 이러한 이슈들에 대해 유효성 여부를 포함한 결론은 아직 내려지지 않았습니다.

이 문서는 미디어 워킹 그룹에서 권고 트랙을 사용하여 워킹 드래프트로 발표되었습니다. 이 문서는 W3C 권고가 될 예정입니다.

워킹 드래프트로 공개된다고 해서 W3C 및 회원의 승인을 의미하지는 않습니다.

이 문서는 드래프트 문서이며 언제든지 수정, 대체 또는 폐기될 수 있습니다. 진행 중인 작업 외의 문서로 인용하는 것은 적절하지 않습니다.

이 문서는 W3C 특허 정책에 따라 운영되는 그룹에서 작성되었습니다. W3C는 그룹의 결과물과 관련하여 공개된 특허 공개 목록을 유지합니다. 해당 페이지에는 특허 공개 방법도 안내되어 있습니다. 본인이 필수 청구를 포함한다고 믿는 특허에 대해 실제로 알고 있는 경우, W3C 특허 정책 6항에 따라 공개해야 합니다.

이 문서는 2025년 8월 18일 W3C 프로세스 문서에 의해 관리됩니다.

1. 소개

대부분의 사용자 에이전트는 자동 재생 미디어를 차단하는 자체 메커니즘을 가지고 있으며, 이러한 메커니즘은 구현별로 다릅니다. 웹 개발자들은 자동 재생 미디어가 허용되는지 감지할 수 있는 방법이 필요하며, 이를 통해 대체 콘텐츠를 선택하거나 미디어가 자동 재생되지 않을 때 사용자 경험을 개선하는 등의 작업을 수행할 수 있습니다. 예를 들어, 사용자 에이전트가 소리 나는 자동 재생만 차단한다면 웹 개발자는 소리나는 미디어를 소리 없는 미디어로 교체하여 미디어가 계속 재생되도록 할 수 있습니다. 차단된 미디어가 사용자에게 정지된 이미지처럼 보이는 대신, 소리 없는 미디어를 사용함으로써 경험을 개선할 수 있습니다. 사용자 에이전트가 어떤 자동 재생 미디어도 허용하지 않는다면, 웹 개발자는 미디어 리소스와 관련 작업의 로딩을 중단하여 사용자의 대역폭과 CPU 사용량을 절약할 수 있습니다.

현재 이 명세는 HTMLMediaElement (videoaudio) 그리고 Web Audio API만 다룹니다. 이 명세는 Web Speech API 및 애니메이션 image (GIF 애니메이션)은 다루지 않습니다.

2. 자동 재생 감지 API

자동 재생 감지는 Navigator 객체를 통해 수행할 수 있습니다. 결과는 미디어 타입과 동일한 타입을 가진 미디어가, 쿼리된 Navigator 객체와 연결된 Window 객체에 포함된 document 에 존재하는 미디어가 자동 재생을 허용하는지 알 수 있게 하거나, 특정 요소가 자동 재생을 허용하는지 확인할 수 있게 해줍니다.

2.1. 자동 재생 정책 열거형

enum AutoplayPolicy {
  "allowed",
  "allowed-muted",
  "disallowed"
};
열거형 값 설명
"allowed" 미디어가 자동 재생을 허용합니다.
"allowed-muted" 소리 없는 미디어 가 자동 재생을 허용합니다.
참고: 현재 이 속성은 주어진 미디어 타입이나 요소가 HTMLMediaElement 또는 그 확장(예: HTMLVideoElement 또는 HTMLAudioElement) 타입일 때만 반환됩니다.
소리 없는 미디어 요소 는 다음 조건 중 하나를 갖는 HTMLMediaElement 입니다:
  • 미디어의 volume 값이 0인 경우
  • 미디어의 muted 가 true인 경우
  • 미디어의 resource 에 오디오 트랙이 없는 경우
"disallowed" 어떠한 미디어도 자동 재생을 허용하지 않습니다.
참고: 자동 재생 정책은 현재 사용자가 미디어 자동 재생을 허용하는지 여부를 나타내며, 미래에 변경될 수 있습니다. 따라서 최신 결과가 필요하다면 매번 결과를 확인하는 것이 권장됩니다.
만약 사용자 에이전트가 HTML § 6.4.1 데이터 모델에서 설명한 사용자 활성화를 사용하여 자동 재생 미디어 허용 여부를 결정하고, 기본 정책이 모든 자동 재생을 차단(disallowed)이라면 사용자가 페이지나 미디어에서 지원되는 제스처를 수행한 후에 정책이 allowed 또는 allowed-muted 로 변경될 수 있습니다.

2.2. 자동 재생 감지 메서드

enum AutoplayPolicyMediaType { "mediaelement", "audiocontext" };

[Exposed=Window]
partial interface Navigator {
  AutoplayPolicy getAutoplayPolicy(AutoplayPolicyMediaType type);
  AutoplayPolicy getAutoplayPolicy(HTMLMediaElement element);
  AutoplayPolicy getAutoplayPolicy(AudioContext context);
};
열거형 값 설명
mediaelement HTMLMediaElement 및 그 확장(예: HTMLVideoElementHTMLAudioElement) 의 상태 쿼리에 사용됨.
audiocontext AudioContext 상태 쿼리에 사용됨.

2.2.1. 미디어 타입으로 쿼리

getAutoplayPolicy(type) 메서드는 대략적 상태를 반환합니다. 즉, 쿼리된 Navigator 객체와 연결된 Window 객체에 포함된 document 에 존재하는 미디어 요소 또는 오디오 컨텍스트가 자동 재생을 허용하는지 여부의 상태입니다. 여기서 대략적이라는 의미는 반환된 결과가 주어진 미디어 타입과 같은 모든 요소마다 항상 정확하지는 않다는 것입니다.
참고: 구현에 따라 같은 문서에 존재하는 일부 미디어가 미디어 타입으로 쿼리한 결과가 disallowed 인 경우에도 자동 재생될 수 있습니다. 이럴 때는 정확한 결과를 얻기 위해 특정 요소로도 쿼리하는 것이 권장됩니다.
일부 사용자 에이전트는 기본적으로 모든 미디어 요소에서 자동 재생을 허용하지 않을 수 있지만, 사용자가 클릭한 미디어 요소는 자동 재생을 허용합니다.

예를 들어, 처음에는 미디어 타입으로 쿼리한 결과와 객체로 쿼리한 결과가 모두 disallowed 일 수 있습니다. 사용자가 미디어 요소를 클릭하면 그 미디어 요소로 쿼리한 결과는 allowed 로 바뀌지만 미디어 타입으로 쿼리하거나 아직 클릭하지 않은 다른 미디어 요소로 쿼리한 결과는 disallowed 를 계속 반환합니다.

getAutoplayPolicy(type) 메서드를 호출할 때, 사용자 에이전트는 다음 단계를 수행해야 합니다:

  1. typemediaelement 이면 HTMLMediaElement 및 그 확장(예: HTMLVideoElementHTMLAudioElement)이 쿼리된 Navigator 객체와 연결된 Window 객체의 document 에 존재하는 현재 상태를 반환합니다.
  2. typeaudiocontext 이면 AudioContext 이 쿼리된 Navigator 객체와 연결된 Window 객체의 document 에 존재하는 현재 상태를 반환합니다.
반환값이 allowed
주어진 타입에 해당하는 모든 미디어가 자동 재생을 허용합니다.
반환값이 allowed-muted
주어진 타입에 해당하는 모든 소리 없는 미디어가 자동 재생을 허용합니다.
참고: 현재 이 속성은 주어진 미디어 타입이 mediaelement 일 때만 반환됩니다. 소리 없는 미디어란 소리 없는 미디어 요소 를 의미합니다.
반환값이 disallowed
주어진 타입에 해당하는 모든 미디어는 자동 재생이 허용되지 않습니다.
참고: 구현에 따라 문서에 자식 문서가 있는 경우, 상위 문서와 연결된 Navigator 객체로 쿼리한 결과와, 자식 문서에 연결된 Navigator 객체로 쿼리한 결과가 다를 수 있습니다.
foo.com의 최상위 문서 A에서 allowed 을 반환하고, 그 안에 bar.com의 다른 문서 B가 포함된 iframe이 있다고 가정합니다. 사용자 에이전트는 자식 문서 B도 상위 문서 A에서 상속된 결과와 동일하게 반환하거나, 문서 B에서 disallowed 등 다른 결과를 반환할 수 있습니다.

전자는 복잡성을 낮추고 자동 재생 차단 동작을 더 일관적으로 만듭니다. 후자는 더 세밀한 자동 재생 제어를 제공합니다.

2.2.2. 요소로 쿼리

getAutoplayPolicy(element)getAutoplayPolicy(context) 메서드는 주어진 요소가 자동 재생을 허용하는지에 대한 현재 상태를 반환합니다.
반환값이 allowed
이 요소는 현재 실행 컨텍스트 내에서 자동 재생이 허용됩니다.
반환값이 allowed-muted
이 요소는 소리가 나지 않을 때만 자동 재생이 허용됩니다.
참고: 현재 이 속성은 주어진 요소가 HTMLMediaElement 또는 그 확장(예: HTMLVideoElement 또는 HTMLAudioElement) 타입일 때만 반환됩니다. 소리 없는 미디어란 소리 없는 미디어 요소 를 의미합니다.

또한, 작성자가 소리 없는 미디어 요소가 재생을 시작한 직후에 이를 소리나게 만든다면, 사용자 에이전트는 해당 미디어 요소를 즉시 일시 정지할 것을 권장합니다 왜냐하면 더 이상 소리 없는 상태가 아니기 때문입니다.

반환값이 disallowed
이 요소는 자동 재생이 허용되지 않습니다.
참고: HTMLMediaElement 에 대해 작성자가 play() 를 호출하면 play() 에서 반환된 promise가 NotAllowedError 예외로 거부됩니다.

AudioContext 인 경우, AudioContextStatesuspended 상태로 유지된다는 의미입니다.

미디어 타입으로 쿼리한 결과와 요소로 쿼리한 결과가 다르다면, 작성자는 요소로 쿼리한 결과를 정확한 결과로 간주해야 합니다. 예시 2는 가능한 시나리오를 보여줍니다.

참고: 작성자가 전달하는 요소가 HTMLMediaElement (또는 그 확장, 예: HTMLVideoElementHTMLAudioElement) 또는 AudioContext 가 아니라면, 이 메서드들은 TypeError 를 throw 합니다.

3. 예시

미디어 요소가 자동 재생 가능한지 확인하는 예시.
if (navigator.getAutoplayPolicy("mediaelement") === "allowed") {
  // 새 미디어 요소를 생성하고 재생합니다.
} else if (navigator.getAutoplayPolicy("mediaelement") === "allowed-muted") {
  // 새 미디어 요소를 생성하고 음소거 상태로 재생합니다.
} else {
  // 자동 재생이 허용되지 않으므로, 대신 포스터를 표시합니다.
}
오디오 컨텍스트를 시작할 수 있는지 확인하는 예시. Web Audiosticky activation을 활용하여 AudioContext 를 시작할 수 있는지 판단합니다.
if (navigator.getAutoplayPolicy("audiocontext") === "allowed") {
  let ac = new AudioContext();
  ac.onstatechange = function() {
    if (ac.state === "running") {
      // 오디오 앱을 시작하세요.
    }
  }
} else {
  // 오디오 컨텍스트가 시작되지 않으므로 사용자에게 오디오 앱 시작을 유도하는 UI를 표시합니다.
  // 핸들러에서 ac.resume()을 호출하여 오디오를 시작할 수 있고, 'onstatechange'로 오디오 스택이 준비된 시점을 알 수 있습니다.
}
특정 미디어 요소로 쿼리하는 예시.
function handlePlaySucceeded() {
  // 컨트롤 UI를 재생중 상태로 업데이트합니다.
}
function handlePlayFailed() {
  // 사용자가 비디오를 명시적으로 시작할 수 있게 버튼을 표시하고,
  // 이미지를 포스터로 보여 비디오 대신 대체합니다.
}

let video = document.getElementById("video");
switch (navigator.getAutoplayPolicy(video)) {
  case "allowed":
    video.src = "video.webm";
    video.play().then(handlePlaySucceeded, handlePlayFailed);
    break;
  case "allowed-muted":
    video.src = "video.webm";
    video.muted = true;
    video.play().then(handlePlaySucceeded, handlePlayFailed);
    break;
  default:
    // 자동 재생이 허용되지 않으므로 리소스를 다운로드할 필요가 없습니다.
    handlePlayFailed();
    break;
}
특정 오디오 컨텍스트로 쿼리하는 예시. Web Audiosticky activation을 활용하여 AudioContext 를 시작할 수 있는지 판단합니다.
let ac = new AudioContext();
if (navigator.getAutoplayPolicy(ac) === "allowed") {
  ac.onstatechange = function() {
    if (ac.state === "running") {
      // 오디오 앱을 시작하세요.
    }
  }
} else {
  // 사용자에게 오디오 앱 시작을 요청하는 UI를 표시합니다.
  // 핸들러에서 ac.resume()을 호출하여 오디오를 시작할 수 있고,
  // 'onstatechange'로 오디오 스택이 준비된 시점을 알 수 있습니다.
}

4. 보안 및 개인정보 보호 고려 사항

Self-Review Questionnaire: Security and Privacy § questions를 기준으로 합니다.

본 명세에서 제공하는 API는 보안 및 개인정보 측면에서 매우 영향이 낮습니다. 사용자를 식별하는 데 이용될 수 있는 민감한 정보를 노출하지 않습니다. 센서나 사용자의 장치를 제어할 수 있는 능력을 노출하지 않습니다. 하나의 origin에 대해 브라우징 세션 전반에 걸쳐 지속되는 새로운 상태를 도입하지 않습니다. origin이 기본 플랫폼에 데이터를 전송할 수 있도록 허용하지 않습니다. 새로운 스크립트 실행 또는 로딩 메커니즘을 도입하거나 활성화하지 않습니다. origin이 사용자 에이전트의 기본 UI 위에 그릴 수 있도록 허용하지 않습니다. origin이 사용자가 프라이빗 브라우징 모드인지 비프라이빗 브라우징 모드인지 감지할 수 있도록 허용하지 않습니다.

5. 감사의 글

이 명세는 W3C 미디어 작업 그룹의 협업 결과물입니다.

에디터들은 본 명세서에 기여한 Alastor Wu, Becca Hughes, Christoph Guttandin, Chris Needham, Chris Pearce, Dale Curtis, Eric Carlson, François Daoust, Frank Liberato, Gary Katsevman, Jean-Yves Avenard, Jer Noble, Mattias Buelens, Mounir Lamouri, Paul Adenot, Tom Jenkinson에게 감사드립니다.

적합성

문서 규약

적합성 요구 사항은 설명적 단언과 RFC 2119 용어의 조합으로 표현됩니다. “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, 및 “OPTIONAL” 키워드는 이 문서의 규범 부분에서 RFC 2119에서 설명한 방식으로 해석되어야 합니다. 하지만 가독성을 위해, 본 명세에서는 이 단어들이 모두 대문자로 표시되지 않습니다.

이 명세의 모든 텍스트는 명시적으로 비규범적이라 표시된 섹션, 예시, 그리고 참고 사항을 제외하면 규범적입니다. [RFC2119]

이 명세의 예시는 “for example”이라는 단어로 도입되거나, class="example"처럼 규범 텍스트와 분리되어 나타납니다.

이것은 참고용 예시입니다.

정보성 참고 사항은 “Note”라는 단어로 시작하며, class="note"처럼 규범 텍스트와 분리되어 나타납니다.

Note, 이것은 정보성 참고 사항입니다.

적합 알고리즘

알고리즘의 일부로 지시문 형태로 표현된 요구 사항 (예: "앞의 공백 문자를 모두 제거한다" 또는 "false를 반환하고 이 단계들을 중단한다") 는 알고리즘 소개에서 사용된 키워드 ("must", "should", "may" 등) 의 의미로 해석되어야 합니다.

알고리즘 또는 특정 단계로 표현된 적합성 요구 사항은 최종 결과가 동등한 한, 어떤 방식으로든 구현할 수 있습니다. 특히, 이 명세에 정의된 알고리즘은 이해하기 쉽도록 되어 있으며, 성능을 우선시하도록 의도된 것이 아닙니다. 구현자는 최적화를 권장합니다.

색인

이 명세서에서 정의한 용어

참조로 정의된 용어

참고문헌

규범적인 참고문헌

[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. 1997년 3월. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[SECURITY-PRIVACY-QUESTIONNAIRE]
Theresa O'Connor; Peter Snyder; Simone Onofri. Self-Review Questionnaire: Security and Privacy. 2025년 4월 18일. NOTE. URL: https://www.w3.org/TR/security-privacy-questionnaire/
[SVG2]
Amelia Bellamy-Royds; et al. Scalable Vector Graphics (SVG) 2. 2018년 10월 4일. CR. URL: https://www.w3.org/TR/SVG2/
[WEBAUDIO]
Paul Adenot; Hongchan Choi. Web Audio API. 2021년 6월 17일. REC. URL: https://www.w3.org/TR/webaudio-1.0/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

설명 참고문헌

[SPEECH-API]
Web Speech API. Draft Community Group Report. URL: https://webaudio.github.io/web-speech-api/

IDL 색인

enum AutoplayPolicy {
  "allowed",
  "allowed-muted",
  "disallowed"
};

enum AutoplayPolicyMediaType { "mediaelement", "audiocontext" };

[Exposed=Window]
partial interface Navigator {
  AutoplayPolicy getAutoplayPolicy(AutoplayPolicyMediaType type);
  AutoplayPolicy getAutoplayPolicy(HTMLMediaElement element);
  AutoplayPolicy getAutoplayPolicy(AudioContext context);
};