상세 컨텐츠

본문 제목

[JavaScript] 자바스크립트에서 아이폰 IOS 사운드재생 Three.js IOS에서 audio 재생 관련

WEB/JavaScript

by AlrepondTech 2018. 1. 15. 02:14

본문

반응형
728x170

 

 

 

 

 

=======================

=======================

=======================

 

 

 

 

 

아이폰, 아이패드, IOS 계열 [WebGL] Three.JS 사운드 나오게 하기

 

WebGL 의 라이브러리 Three.js 에서 오디오를 재생시키려면 아이폰의 언락부터 먼저해야한다 아래 코드와 같이 함수부분을 먼저 실행하고 Three.JS의 사운드를 출력한다면 제대로 사운드가 출력이 될것이다.

 

WebGL오디오 부분도 아래와같이 응요하면 사운드가 IOS에서 나올것 같다.

 

 

<script type='module'>

 

unlockIOSSound()

{

    var listener = new THREE.AudioListener();

    var sound = new THREE.PositionalAudio(listener);

    var audioLoader = new THREE.AudioLoader();

 

    function playIOSUnlockSound()

    {

        window.removeEventListener('touchstart', playIOSUnlockSound);

        document.removeEventListener('touchstart', playIOSUnlockSound);

 

        var source = listener.context.createBufferSource();

        source.connect(listener.context.destination);

        source.start();

    }

 

    window.addEventListener('touchstart', playIOSUnlockSound);

    document.addEventListener('click', playIOSUnlockSound);

}

 

</script>

 

 

 

 

 

=======================

=======================

=======================

 

 

 

 

출처: https://github.com/mrdoob/three.js/issues/10404

 

 

This soved my issue:

window.addEventListener('touchstart', function() {  	// create empty buffer 	var buffer = myContext.createBuffer(1, 1, 22050); 	var source = myContext.createBufferSource(); 	source.buffer = buffer;  	// connect to output (your speakers) 	source.connect(myContext.destination);  	// play the file 	source.noteOn(0);  }, false); 

Source: https://paulbakaus.com/tutorials/html5/web-audio-on-ios/

 

 

-------------------------------------------------------------------

 

i just spent a lot of time figuring this out because i want to use positional audio for a web project and finally got it working, so i figured i'd share here since this got me going in the right direction. basically the sourcecomes from the audioListener context.

this is in my init function:

function playSound() {   audioLoader.load("clips/theme_80.mp3", function(buffer) {     sound.setBuffer( buffer );     sound.setRefDistance( 20 );     sound.play();   });    var source = listener.context.createBufferSource();   source.connect(listener.context.destination);   source.start(); } window.addEventListener('touchstart', playSound); document.addEventListener('click', playSound); 

seems to work on mobile safari and chrome, though only tested on my iphone.

here's the test version:
https://owenroberts.github.io/char/sound.html

 

 

https://owenroberts.github.io/char/sound.html

 

링크는 소스는 맞는데 사운드path링크가 잘못되어, 안되는 코드로 인식할수도 있다.

내가 다시 사운드path를 바꾸어 코드를 수정 전체적으로 압축하였다.

 

test2.zip
다운로드

 

 

 

 

=======================

=======================

=======================

 

 

 

 

출처: https://paulbakaus.com/tutorials/html5/web-audio-on-ios/

 

 

First things first: Web Audio is the real deal, and works impressively well on iOS-running devices. Even the biggest annoying limitation of the ugly HTML5 Audio past is gone – being able to play back only one sound at a time.

Though, one important limitation remains on iOS: Web Audio is effectively muted until user activation.

What does this mean and what do I have to do?

This means that you can use almost any facette of the Web Audio API, but won’t actually hear anything. This is different from HTML5’s audio tag, as that one wouldn’t even load files. But since the preferred way of loading files in Web Audio is via XHR, Apple can”t block it. The official reason for this is to not annoy users with large upfront downloads and noisy websites.

The only way to unmute the Web Audio context is to call noteOn() right after a user interactionThis can be a click or any of the touch events (AFAIK – I only tested click and touchstart).

As soon as the Web Audio context is “unmuted”, it will stay that way for the entire session, and every other action won’t require a user event. Thus, if you are for instance building a HTML5 game, add a “tap to play” button for the iOS version in which an empty sound (or another non-empty one) is played to unlock the phone.

Example 1: Unlocking Web Audio, the simple way

window.addEventListener('touchstart', function() {  	// create new buffer source for playback with an already 	// loaded and decoded empty sound file 	var source = myContext.createBufferSource(); 	source.buffer = myDecodedBuffer;  	// connect to output (your speakers) 	source.connect(myContext.destination);  	// play the file 	source.noteOn(0);  }, false); 

This solution is decent and easy, but requires an additional HTTP request for the empty sound (not shown above).

Example 2: Unlocking Web Audio, the smart way

window.addEventListener('touchstart', function() {  	// create empty buffer 	var buffer = myContext.createBuffer(1, 1, 22050); 	var source = myContext.createBufferSource(); 	source.buffer = buffer;  	// connect to output (your speakers) 	source.connect(myContext.destination);  	// play the file 	source.noteOn(0);  }, false); 

Much better! We simply create a very low profile empty sound on the fly and play it back. Does the job, and doesn’t hurt.

How do I know when my context is unlocked?

Sure, the above will unlock the context, but there is no property on the context that you can query to find out about the locked/unlocked state.Turns out there is a way to find (thanks Richard!), but Apple doesn’t mention it, and hid it extremely well (gnah!).

To find out whether the context is still locked, query the playbackState on the source node shortly after calling noteOn(0) (but not directly – use a timeout). If the state is in PLAYING_STATE or FINISHED_STATE, your context is unlocked.

Example 3: Generic unlock function

var isUnlocked = false; function unlock() { 			 	if(isIOS || this.unlocked) 		return;  	// create empty buffer and play it 	var buffer = myContext.createBuffer(1, 1, 22050); 	var source = myContext.createBufferSource(); 	source.buffer = buffer; 	source.connect(myContext.destination); 	source.noteOn(0);  	// by checking the play state after some time, we know if we're really unlocked 	setTimeout(function() { 		if((source.playbackState === source.PLAYING_STATE || source.playbackState === source.FINISHED_STATE)) { 			isUnlocked = true; 		} 	}, 0);  } 

 

The beauty of above's unlock function is that you can call internally within a web audio library whenever the user is trying to play back a file, as it doesn't cost much. In my case, I have a play() function that also loads the file if it isn't loaded yet. Due to its async nature, it would never play the audio even though it came through a touch event. By calling unlock() internally right away and hoping the user comes from a touch event, all is good!


If you want to have future-proof, low latency polyphonic sound, this is the technology you are looking for. Today it is only available in Chrome and Safari, but Mozilla is working on an implementation.

 

 

 

 

=======================

=======================

=======================

 

 

 

 

출처: https://gist.github.com/kus/3f01d60569eeadefe3a1

 

 

Fix iOS AudioContext on Safari not playing any audio. It needs to be "warmed up" from a user interaction, then you can play audio with it as normal throughout the rest of the life cycle of the page.
  // Fix iOS Audio Context by Blake Kus https://gist.github.com/kus/3f01d60569eeadefe3a1
  // MIT license
  (function() {
  window.AudioContext = window.AudioContext || window.webkitAudioContext;
  if (window.AudioContext) {
  window.audioContext = new window.AudioContext();
  }
  var fixAudioContext = function (e) {
  if (window.audioContext) {
  // Create empty buffer
  var buffer = window.audioContext.createBuffer(1, 1, 22050);
  var source = window.audioContext.createBufferSource();
  source.buffer = buffer;
  // Connect to output (speakers)
  source.connect(window.audioContext.destination);
  // Play sound
  if (source.start) {
  source.start(0);
  } else if (source.play) {
  source.play(0);
  } else if (source.noteOn) {
  source.noteOn(0);
  }
  }
  // Remove events
  document.removeEventListener('touchstart', fixAudioContext);
  document.removeEventListener('touchend', fixAudioContext);
  };
  // iOS 6-8
  document.addEventListener('touchstart', fixAudioContext);
  // iOS 9
  document.addEventListener('touchend', fixAudioContext);
  })();
  <!doctype html>
  <html>
  <head>
  <meta charset="utf-8">
  <title>Fix iOS Audio Context</title>
  <meta name="author" content="Blake Kus">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  </head>
  <body>
  <h1>iOS Safari AudioContext Demo</h1>
  <p>Load on iOS device without touching the screen and it will not play a noise after 3 seconds.</p>
  <p>Refresh the page touch the screen (within 3 seconds of it loading) and the audio and any other audio will play outside of a user generated event.</p>
  <p id="status">Waiting 3 seconds to play audio...</p>
  <script type="text/javascript">
  // Fix iOS Audio Context by Blake Kus https://gist.github.com/kus/3f01d60569eeadefe3a1
  // MIT license
  (function() {
  window.AudioContext = window.AudioContext || window.webkitAudioContext;
  if (window.AudioContext) {
  window.audioContext = new window.AudioContext();
  }
  var fixAudioContext = function (e) {
  if (window.audioContext) {
  // Create empty buffer
  var buffer = window.audioContext.createBuffer(1, 1, 22050);
  var source = window.audioContext.createBufferSource();
  source.buffer = buffer;
  // Connect to output (speakers)
  source.connect(window.audioContext.destination);
  // Play sound
  if (source.start) {
  source.start(0);
  } else if (source.play) {
  source.play(0);
  } else if (source.noteOn) {
  source.noteOn(0);
  }
  }
  // Remove events
  document.removeEventListener('touchstart', fixAudioContext);
  document.removeEventListener('touchend', fixAudioContext);
  };
  // iOS 6-8
  document.addEventListener('touchstart', fixAudioContext);
  // iOS 9
  document.addEventListener('touchend', fixAudioContext);
  })();
   
  var $status = document.querySelector('#status');
   
  function playSound () {
  var path = '../sounds/laser.mp3';
  var context = window.audioContext;
  var request = new XMLHttpRequest();
  $status.innerHTML = 'Playing ' + path;
  request.open('GET', path, true);
  request.responseType = 'arraybuffer';
  request.addEventListener('load', function (e) {
  context.decodeAudioData(this.response, function (buffer) {
  var source = context.createBufferSource();
  source.buffer = buffer;
  source.connect(context.destination);
  source.start(0);
  });
  }, false);
  request.send();
  }
   
  setTimeout(playSound, 3000);
  </script>
  </body>
  </html>

@VirtualAirwaves
 

VirtualAirwaves commented on 4 Nov 2016  

I just tried this, copying your example exactly, except for putting my own sample audio file, and it doesn't work on iPad an iPhone. No errors, and the server did serve the audio file to the application. Works fine as-is on desktop Safari and Chrome; doesn't play anything on firefox.
I refresh and pressed the screen within 3 seconds. I tried adding a button just to have something to press, and that didn't help.
Did Apple change something recently?
I put it up here so you can see for yourself:
http://side.band/audio

 

 

-

 

 

=======================

=======================

=======================

 

 

 

 

기타관련링크:

 

https://qiita.com/naotaro0123/items/15800215d6e20342b7ce

 

 

https://paulbakaus.com/tutorials/html5/web-audio-on-ios/

 

 

https://stackoverflow.com/questions/44842321/audio-in-unity-webgl-on-ios-devices

 

 

https://docs.unity3d.com/560/Documentation/Manual/webgl-audio.html

 

 

 

 

=======================

=======================

=======================

 

 

 

 

 

반응형
그리드형


관련글 더보기

댓글 영역