My Boundary As Much As I Experienced

모던 브라우저에서 오디오 자동재생을 구현하기 위한 노력.. 본문

FrontEnd/Frontend etc.

모던 브라우저에서 오디오 자동재생을 구현하기 위한 노력..

Bumang 2024. 7. 27. 11:31

전시 작품에 클릭을 안 하고도 음악이 자동으로 나오게 해야된다.

https://truth-in-pendulum.vercel.app/

 

7월 19일부터 27일까지 모두의 연구소에서 인터랙티브 코딩 랩의 첫 전시를 시작한다.

그런데 오디오/카메라존과 터치존이 나누어져 있고, 오디오존에서는 TV의 터치패널을 사용하여 클릭을 할 수 없었다.

그래서 내 작품의 오디오를 체험해보려면 터치를 하지 않고도 소리가 자동적으로 나오게 설정해야되는 상황이었다.

 

문제: 최신 브라우저에선 사용자가 의도치 않게 오디오가 자동재생 되는 것이 막혀있다.

그러나 최신 브라우저에선 mute된 상태로 사이트에 들어가도록 되어있었다.

그리고 사용자가 인터랙션을 발생시켜 사운드를 사직접 켜야만 소리가 재생되게 할 수 있다.

그런데 앞서 말했다시피 내 작품의 전시 환경에선 화면을 터치하기가 어려운 환경이라...

오디오 자동재생을 어떻게든 구현하려고 별의 별 노력을 다 해봤다.

 

첫 번째 시도. audio 태그의 자동재생

처음엔 그냥 html에 audio태그를 박아넣고 loop태그로 계속 반복하게 하고, autoplay 태그로 자동재생을 시켰다.

그러나 최신 브라우저에선 자동재생이 막혀 사실 유명무실한 태그가 되어 효과가 없었다.

    <audio id="audioNature" src="./asset/audio_nature.mp3" loop autoplay></audio>
    <audio id="audioDream" src="./asset/audio_the_dream_start.mp3" loop autoplay></audio>
    <audio id="audioForgiveMe" src="./asset/audio_never_forgive_me_never_forget_me.mp3" loop autoplay></audio>

 

두 번째 시도. volume을 0으로 해놨다가 로드된 후에는 볼륨을 올리기

DOMContentLoaded가 되기 전엔 volume을 0으로 해놔서 브라우저 정책을 준수하는 척을 한다. 

volume을 0로 하면 재생되지 않는 것으로 친다는 팁을 듣고 시도해봤다. 그러나 별 효과는 없었다.

const audioNature = document.getElementById("audioNature");
const audioDream = document.getElementById("audioDream");
const audioForgiveMe = document.getElementById("audioForgiveMe");

// DOMContent가 로드 된 후 발동
document.addEventListener("DOMContentLoaded", (event) => {
  const playButton = document.getElementById("playAudioButton");

  const audioNature = document.getElementById("audioNature");
  const audioDream = document.getElementById("audioDream");
  const audioForgiveMe = document.getElementById("audioForgiveMe");

  // 볼륨을 0으로 해놓기
  audioNature.volume = 0;
  audioDream.volume = 0;
  audioForgiveMe.volume = 0;

  // 플레이 함수
  function playAllAudio() {
    audioNature.play().catch((error) => {
      console.error("Error playing audioNature:", error);
    });
    audioDream.play().catch((error) => {
      console.error("Error playing audioDream:", error);
    });
    audioForgiveMe.play().catch((error) => {
      console.error("Error playing audioForgiveMe:", error);
    });
  }

  // 클릭하면 재생하는 이벤트리스너 실행
  playButton.addEventListener("click", () => {
    playAllAudio();
    playButton.style.display = "none"; // Hide the button after playing
  });

  // 클릭
  playButton.click()
});

 

세 번째 시도. mute해제 버튼을 opacity: 0로 숨겨놓고 click 메소드를 통해 클릭하기

mute 버튼을 넣고 이를 opacity: 0으로 하든 숨겨놓는다.

display: none으로 하면 언마운트된 것으로 인식하여

정상작동하지 않을 수 있을거 같아 opacity: 0으로 하는 방법을 선택했다.

그리고 DOM Content가 로드된 것을 보장된 시점에 click을 발생시킨다.

 

그러나 이 방법도 실패했는데, click이벤트의 속성에 isTrusted 속성 때문이었다.

실제 사용자가 발생시킨 클릭은 isTrusted 속성이 true가 되고,

프로그래밍적인 조작으로 발생시킨 클릭은 isTrusted 속성이 false가 된다.

isTrusted가 false인 이벤트는 실제로 유효하게 작동하지 않았다.

  document.addEventListener('DOMContentLoaded', (event) => {
    const audio = document.getElementById('myAudio');
    const unmuteButton = document.getElementById('unmuteButton');

    audio.muted = true;
    
    // DOM Content 로드 후에 클릭 이벤트리스너를 넣는다.
    unmuteButton.addEventListener('click', () => {
      audio.muted = false;
      audio.play();
    });

    // 클릭!
    unmuteButton.click();
  });

 

네 번째 시도. 다른 사이트에서 iframe을 통해 작품을 끌어다와 오디오 재생시키기

모든 작품 전체 수합 및 전시용 페이지는 iframe을 사용하여 배포된 각 참가자들의 작품을 재생시킨다.

그런데 여기서, iframe을 이용하여 참조사이트의 오디오를 자동재생 시키는 방법이 있다고 한다.

바로, iframe 태그에 allow="autoplay; encrypted-media" 속성을 추가하면 참조사이트의 오디오가 자동재생이 된다고 한다.

또한 해당 사이트가 autoplay 기능을 지원하는지 확인하고, 관련 매개변수를 URL에 추가해야 한다.  "...?autoplay=1"

 

랩장님께서 allow="autoplay"는 넣어주셨는데, 내가 encrypted-media나 쿼리스트링까지 있어야한다는 얘기를 안 해서인지

실제로 소리가 재생되지 않았다.

 

<iframe width="560" height="315" src="https://www.youtube.com/embed/VIDEO_ID?autoplay=1" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>


https://developer.chrome.com/blog/autoplay?hl=ko#iframe_delegation

 

다섯 번째 시도. 비디오 사용권한을 받고 비디오가 켜졌으면 음악을 재생

비디오 사용 권한을 받고 비디오가 켜졌으면 음악을 재생하는 것이다.

이 방법은 처음에 비디오 사용권한을 받아야 하니 엄밀히 말하면 자동재생은 아니다.

 

그러나 한 번 비디오 사용권한을 받아놓으면 다음 접속 시에도 비디오 사용권한은 유지되기 때문에

전시 장소에서 1회 비디오 사용권한 세팅을 받아놓고 계속 오디오가 재생되도록 유지시킬 수 있었다.

let flag = true;


...
navigator.mediaDevices
  .getUserMedia({ video: true })
  .then(function (video) {
    if (flag) {
      playAllAudio();
      audioNature.volume = 1;
      audioDream.muted = false;
      audioNature.muted = false;
      audioForgiveMe.muted = false;

      flag = false;
    }
  })
  .catch(function (err) {
    console.log("The following error occurred: " + err.name);
  });

 

 

이제 어떻게 음악 재생을 개선할 것인가?

이제 전시도 끝났으니 카메라가 켜지는걸 포착해서 소리를 재생시키는 로직은 삭제하려고 한다.

사용자는 이게 오디오 자동재생을 위한 꼼수인지 모르기 때문에,

실제로 카메라가 작품 내에 필요하지도 않는데 카메라를 키라고 강요하는 것은 확실히 무서울 것이다..

(심지어 작품도 약간 수상한 분위기의 공포물이다.)

 

그리고 오디오는 그냥 mute/unmute버튼을 만들어서 원하는 사용자만 소리를 듣도록 하고,

대신 카메라 기능을 아예 빼기보단 실제로 카메라가 필요한 기능을 하나 추가해서 활용하려 한다.

약간의 패럴랙스 효과를 카메라로 구현하려 하는데, 이것도 다 하면 따로 포스팅을 하겠다.