[HTML5 Game] Sound Effect

Posted in 모바일/HTML5 // Posted at 2013. 10. 11. 21:43
728x90

이번 글에서는 게임에 사운드(Sound) 효과를 추가해 볼 것이다.

 

이전 글(http://m.mkexdev.net/252)에서 스페이스 키를 누르면 총알이 발사되도록 해 봤으니, 여기서는 총알이 발사되는 소리를 구현해 보도록 하겠다.

 

사운드 처리는 HTML5 스펙에 새로이 추가된 Audio 요소를 이용할 것이다.(참고: http://m.mkexdev.net/63)

 

 

 

단순히 하나의 사운드를 재생하는 것은 매우 심플한 코드로 구현이 가능하다. 하지만 게임 사운드는 한 번에 하나의 사운드만 재생되는 것이 아니라 여러 사운드가 동시에 재생되어야 하는 경우가 많고 또한 하나의 사운드라 해도 그 사운드가 종료되기 전에 같은 사운드가 다시 재생되어야 하는 경우도 있다. 이러한 대표적인 경우가 총알이 발사되는 경우이다. 예를들어 총알 사운드의 플레이 타임이 3초인 경우, 첫번째 총알이 발새되고 3초가 지나기 전에 두 번째 총알이 발사되는 경우이다. 이를 위해서는 하나의 사운드를 여러개로 분리해서 각각 재생되도록 하는 기법이 필요하다.

 

바로 구현해 들어가 보자. 다음과 같이 총알 사운드를 추상화환 객체 기반을 준비한다.

여러 개의 총알 소리가 거의 동시에 같이 재생될 수 있도록 사운드 배열을 관리하고 플레이 가능한 사운드를 찾으면 그 사운드를 재생하고 바로 루프를 빠져 나간다. 또한 특정 사운드의 재생이 완료되면 명시적으로 paused(일시정지)처리를 하는데 이 함수에서는 이 속성값을 검사하여 재생가능한 사운드 파일을 탐색한다. 

function FireShot(sounds){
  this.sounds = sounds

  this.playSound = function(){   
    for(var i = 0; i < this.sounds.length; i++){  
      if(this.sounds[i].audio.paused){             
         this.sounds[i].audio.play();
         break;    
      }    
    }   
  }
}

 

이어지는 코드는 FireShort 객체를 이용하여 스페이스 키가 눌러졌을 때 사운드 재생을 처리하는 코드이다.

총알 소리로 사용되는 사운드 파일은 한개이지만, (앞서 설명한대로) 동시 재생을 위해 여러개의 Audio 요소를 동적으로 생성한다. 코드에서는 50개를 생성했는데 이것은 사운드 파일의 재생시간과 동시 재생 환경등을 고려하여 적절한 값을 지정해야 한다. 필자가 사용하는 (인터넷에서 다운받는) 사운드 파일의 재생시간은 대략 4초 가량 되며(너무 길다. 짧막한 총성소리에 비해 너무 긴 재생 시간이다. ㅡ,ㅡ;) 스페이스 키를 계속 누르고 있을 경우 소리가 끊임없이 나도록 해야 하기 때문에 50이라는 좀 과한(?) 값을 지정했다. (이렇게 해도 플레이타임이 길어서 매끄럽지 못하다.) 예제에서는 사운드 재생만이 목적이기 때문에 이러한 과도한 값을 지정했지만 실제 게임 개발시에는 자원의 낭비 및 성능의 저해가 없는 수준에서 적절한 선택을 해야 할 것이다.

 

참고로 크롬 브라우저의 경우 한번 재생한 Audio를 재사용 하기 위해서는 다시 로드해야 하는것을 주의하기 바라며 기타 코드는 HTML5의 Audio 요소를 사용하는 코드와 FireShot 객체를 호출하는 부분으로 이뤄져있다.

var sounds = []; 
var fireShot; 
var currentSoundLoadCount = 0;   


function init(){
 for(var i = 0; i < 50; i++){  
    var gunAudio = new Audio();
    gunAudio.src = 'audio/gun.mp3'
        
    gunAudio.addEventListener("canplaythrough", onSoundReadyComplete, false);  
    gunAudio.addEventListener("ended", function(){
       if(window.chrome) this.load();                    

         this.pause(); 
     },false); 
      
    document.body.appendChild(gunAudio);
  
    sounds.push({audio: gunAudio});  
 }               
}

 

function onSoundReadyComplete(){    
   if(++currentSoundLoadCount >= 50){         
     fireShot = new FireShot(sounds);             
 }
}

 

function onKeyDown(e){   
 if(e.keyCode = 32){        
    fireShot.playSound(); 
 }
}

 

window.addEventListener("load", init, false);
window.addEventListener("keydown",onKeyDown,false);

 

브라우저로 실행하여 사운드 효과를 감상(?)해 보자.

다시한번 말하지만, 사운드 파일의 재생시간과 동시 재생의 환경에 따라 적절히 수정을 가하며 테스트 해 보는 것이 좋다.

 

'모바일 > HTML5' 카테고리의 다른 글

[HTML5 Game] Shooting Down  (0) 2013.10.16
[HTML5 Game] Firing Bullet  (0) 2013.10.08
[HTML5 Game] Moving Object Ⅱ  (1) 2013.10.02
[HTML5 Game] Moving Object  (0) 2013.10.02
[HTML5 Game]Calculating FPS  (0) 2013.09.30

브라우저의 HTML5 오디오포맷 지원 여부

Posted in 모바일/HTML5 // Posted at 2010. 9. 2. 11:59
728x90

[HTML5] Video & Audio 글에서 HTML5의 비디오, 오디오 지원에 대해 알아 보았다
코덱의 비표준화 문제로 각 브라우저마다 지원되는 포맷이 상이한 문제도 다루었었다
자신의 브라우저가 어떤 오디오 포맷을 지원하는지 테스트 해 볼 수 있는 사이트를 소개한다

xguru 님 트위터에 소개된, 브라우저의 오디오 지원 테스트 페이지!http://textopia.org/androidsoundformats.html

이 사이트에서는 각 오디오 포맷별로 HTML5 의 <audio> 태그를 사용하여 정의해 두었다.
위 주소로 접속하면 현재 브라우저가 어떤 포맷을 지원하는지 시각적으로 확인 할 수 있다

현재 나의 데스크탑에 설치된 4대 브라우저를 테스트 해 봤다. 각 브라우저와 버전은 다음과 같다
1) 크롬, 버전 5.0
2) 사파리, 버전 5.0
3) 파이어폭스, 버전 3.6.8
4) 오페라, 버전 10.61


테스드 대상 오디오 포맷은 다음과 같이 총 7개이다
- ogg, mp3, 3gp, m4a, wav, amr, mp4

4대 브라우저에서 테스트를 해 보니 아래와 같은 결과가 나왔다

크롬

사파리


파이어폭스


오페라

그리고 아이폰 3 사파리로 테스트한 결과, 데스크탑 사파리와 동일한 결과가 나왔다



정리 해 보면, 각 브라우저 별로 지원되는 오디오 포맷은 다음과 같다
크롬: ogg, mp3, m4a, mp4
사파리: mp3, 3gp, m4a, wav, amr, mp4(아이폰 3GS, 모바일 사파리 동일)
파이어폭스: ogg, wav
오페라: ogg, wav

'모바일 > HTML5' 카테고리의 다른 글

[HTML5] Cross Document Messaging  (3) 2010.09.03
HTML5 템플릿 제공 사이트 소개  (0) 2010.09.03
[HTML5] Server-Sent Events  (4) 2010.08.31
[HTML5] Notifications (알림)  (2) 2010.08.30
[HTML5] 웹 양식(Web Form)의 개선, 폼 태그  (4) 2010.08.26

[HTML5] Video & Audio

Posted in 모바일/HTML5 // Posted at 2010. 8. 24. 13:39
728x90

멀티미디어 지원
HTML 5 를 지원하는 브라우저는 비디오, 오디오와 같은 멀티미디어 형식을 자체적으로 지원한다
HTML 5 는 이러한 멀티미디어 파일을 웹 페이지에 삽입할 수 있는 태그를 정의하고 있으며 
재생과 관련한 각종 제어를 수행할 수 있는 스크립트 API가 제공된다
 
이전의 브라우저 환경
HTML 5가 등장하기 전, 브라우저 환경에서는 멀티미디어 재생을 자체적으로 할 수 없었다
대신 외부 기술, 즉 브라우저에 별도로 설치되는 플러그인(Plug in)의 힘을 빌어 멀티미디어를 표현할 수 있었다. 멀티미디어 재생을 위한 플로그인 기술로는 다음과 같은 것들이 있다
- 윈도우 미디어 플레이어
- 어도비 플래시 플레이어
- 애플 퀵타임 플레이어
- 마이크로소프트 실버라이트

이러한 플러그인이 브라우저에 따로 설치되어야만 멀티미디어 재생이 가능하였으며 이는 곧 표준과는 거리가 먼 개념이 되어 버렸다

웹 응용환경의 일관되고 표준적인 플랫폼을 지향하는 HTML5가 멀티미디어 재생을 위한 스펙이 마련된 것은 어찌보면 당연한 순리라 하겠다. 그 만큼 현재의 웹은 멀티미디어를 빼고 논할 수는 없는 것이다


브라우저 지원 현황
다른 HTML5 스펙과는 달리 비디오,오디오는 브라우저 별로 지원되는 코덱이 상이하다
즉 HTML 5 의 멀티미디어 구현은 지원하더라도 각기 다른 코덱을 지원하는 것이다
Video, Audio 스펙은 표준으로 정해졌지만 코덱은 아직 표준으로 정해진 것이 없기 때문이다

따라서 브라우저가 Video,Audio 를 지원하다고 해도 어떤 코덱을 지원하는 것인지 추가 확인이 필요하다. 우선 Video,Audio 를 지원하는 브라우저 현황을 살펴보자

Video, Audio 지원 현황
- Video 지원 현황



- Audio 지원 현황

출처: http://caniuse.com/

대부분의 최신 브라우저에서 Video, Audio를 지원하고 있다
또한 다음의 코드로 브라우저 지원 여부를 체크해 볼 수 있다

if(!!document.createElement('video').canPlayType) {
     alert("현재 브라우저는 비디오를 지원합니다")
}
else{
      alert("현재 브라우저는 비디오를 지원하지 않습니다")
}

이제 브라우저별로 각기 달리 지원되는 코덱에 대해 살펴보자

코덱 지원 현황
멀티미디어 형식에 대한 표준이 HTML5 사양에는 포함되지 않았다.
따라서 멀티미디어 재생을 위한 코덱의 비 표준화로 현재 브라우저 마다 동영상 재생 형식이 서로 다르다비디오 코덱으로는 H.264 Theora 가 있으며 오디오 코덱으로는 AAC,MP3 Vorbis 형식이 HTML5 용으로 사용되고 있다

모질라와 오페라는 라이선스가 없는 오픈 소스 Theora를 선호하며 애플과 구글은 H.264 코덱을 선호한다. 또한 마이크로소프트의 IE.9 에서는 H.264코덱만 지원한다고 발표한 바 있다

오디오 코덱 역시 라이선스가 없는
Vorbis형식과 특허로 제한되어 있는 MP3, ACC 형식으로 이분화 되어 있다. 그리고 또 하나의 변수로 최근 구글이 동영상 코덱 개발사인 On2를 인수해 VP8 코덱을 오픈 하기로 하였다. 이에 모질라 및 오페라 등이 동참하기로 하였지만 애플의 참여는 알 수 없는 상황이다.

따라서 표준이 정립되기 전까지는 두 형식에 대한 브라우저 호환성을 유지해야 하는 부담이 있다
아래 표는 브라우저 별 지원되는 비디오/오디오 코덱 정보이다

 

파일 형식

비디오 코덱

오디오 코덱

사파리

MP4

MPEG/H.264

AAC/MP3

크롬

Ogg/MP4

Theora/H.264

Vorbis/AAC/MP3

파이어폭스

Ogg

Theora

Vorbis

 (스마트폰 브라우저의 경우 해상도 및 초당 프레임 등 추가 제약사항이 있을 수 있음)
 출처: HTML5 & API 입문, 시라이시 슌페이 저)



Video & Audio 재생하기
웹 페이지에 멀티미디어 형식을 삽입하고 재생하고 컨트롤 하는 기본적인 태그에 대해 알아보자

<video> , <audio> 태그
비디오, 오디오를 단순히 재생한 시키고자 할 경우 간단한 마크업 만으로도 충분하다
비디오 재생을 위한 <video> 태그와 오디오 재생을 위한 <audio> 태그가 제공되며
각 태그에 멀티미디어 파일의 위치(소스)를 제공해 주기만 하면 된다

<!DOCTYPE html>
<html>
<head></head>
<body>
  <video controls autoplay loop     
       src="http://www.double.co.nz/video_test/transformers480.ogg"></video>
  <br>  
  <audio controls autoplay loop
       src="http://www.miaowmusic.com/audio/mp3/Miaow-07-Bubble.mp3"></audio>
</body>
</html>


구글 크롬 브라우저 실행화면

간단한 태그만으로 웹 페이지에 비디오,오디오 형식을 재생할 수 있다
예제에서 사용된 <video>,<audio> 태그의 속성은 다음과 같다
- src: 비디오, 오디오 파일(소스)를 지정한다
- controls: 재생을 컨트롤 하는 컨트롤 바를 보이게 한다
- autoplay: 자동으로 재생을 시작한다


대체 요소 출력
HTML5 의 비디오, 오디오가 지원되지 않는 브라우저를 위한 대체요소 출력이 지원된다
아래와 같이 <video>,<audio> 태그 사이에 대체요소를 정의하면 된다

<video src="http://www.double.co.nz/video_test/transformers480.ogg">
    HTML5 Video 를 지원하지 않는 브라우저 입니다
</video
<br>   
<audio src="http://www.miaowmusic.com/audio/mp3/Miaow-07-Bubble.mp3">
    HTML5 Audio 를 지원하지 않는 브라우저 입니다
</audio>

위 코드를 MS IE 8.0 이하 버전에서 실행해 보면 대체 텍스트가 표시될 것이다
 

Video & Audio 제어하기
HTML5 에는 비디오, 오디오의 재생과 관련한 다양한 스크립트 API를 정의하고 있다

재생과 관련된 제어라 함은 시작, 중지, 일시정지, 재생위치파악, 재생길이, 재생속도, 볼륨크기, 음소거 등이 있으며 재생 간 발생하는 각종 이벤트 처리를 일컫는다

스크립트 API를 통해 제어를 하기 위해서는 Video(Audio)의 DOM 객체를 대상으로 수행하면 된다

var video1 = document.getElementById("video1");
video1.play(); //비디오를 재생함

Video, Audio 를 위한 다양하고 많은 속성과 함수 그리고 이벤트들이 제공된다
다음이 url에서 멀티미디어 관련 API 들을 확인해 보기 바란다


몇 가지 주요한 API를 알아보고 관련 데모를 제작해 보도록 하자

주요 속성
- src: 멀티미디어 파일 소스 지정
- currentTime: 현재 재생 위치를 초 단위로 반환
- duration: 전체 재생시간을 초 단위로 반환
- paused: 일시정지 여부 반환
- ended: 재생 종료 어부 반환
- muted: 음소거 여부 반환
- volume: 볼륨 값(0.0 ~ 1.0 범위를 가짐)
- error: 에러 정보를 반환
- networkState: 멀티미디어 파일과 관련된 네트워크 상태 반환(접속전, 로딩 중, 완료, 로딩 실패 등)

주요 함수
- load(): 멀티미디어를 읽어 들임(재생하지는 않음)
- play(): 멀티미디어를 재생함
- pause(): 일시 정지

주요 이벤트
- play: 재생될 때 발생
- progress: 멀티미디어 파일을 로딩중에 지속적(그리고 간헐적) 발생
- timeupdate: 재생 중에 지속적 발생
- ended: 재생 종료시 발생
- error: 멀티미디어 로딩, 재생과 관련한 에러가 있을 시 발생

자주 응용 될 법한 주요 API에 대한 설명이다. 추가 API 설명은 반드시 관련 자료를 다로 보기 바란다


비디오 데모 만들어 보기
주요 속성과 함수, 이벤트 몇 가지를 응용하여 비디오 재생을 제어하는 간단한 데모를 만들어 보자

- 데모 실행 화면
아래 화면은 데모를 구글 크롬에서 실행한 화면이다.
progress 이벤트에서 구현한 데이터 로딩 부분이 정상 동작 하지 않는다(하단 undefined)
재생, 정지, 음소거, 볼륨 등은 모두 정상 동작한다
 

그리고 아래 화면은 파이어폭스에서 데모를 실행한 화면이다
파이어폭스의 경우 모든 기능이 잘 동작한다(데이터 로딩 부분 역시 정상 동작함)
그러나 볼륨을 위한 range input 컨트롤이 아직 지원되지 않는 것 같다


이렇듯 브라우저별로 몇 가지 상이한 동작을 하는 것은 HTML5 가 아직 표준화가 완료되지 않는 것을 의미한다. 이제 데모 코드를 살펴 보자
<!DOCTYPE html>
<html>
<head></head>
<body>
  <video id="video1" controls  
             src="http://www.double.co.nz/video_test/transformers480.ogg"></video>  
  <br>
  <button onclick="play()">재생</button>
  <button onclick="pause()">일시정지</button>
  <button onclick="mute()">음소거</button>
 
  볼륨:<input id="volumecontrol" type="range" max="1" step="any" onchange="updateVolume()">
 
  <div id="time"></div>
  <div id="downLoadState"></div>
</body>
</html>

<script type="text/javascript">
  var video1 = document.getElementById("video1");    
            
  //비디오 재생 
  function play(){
    video1.play();
    video1.volume = volumecontrol.value;   
  } 
  //비디오 일시정지
  function pause(){
    video1.pause();
  }    
  //음소거
  function mute(){
    video1.muted = !video1.muted;
  } 
  //볼륨조절       
  function updateVolume() {
    video1.volume = volumecontrol.value;
  } 
 
  //timeupdate 이벤트 구현(재생시간 현황 표시)
  video1.addEventListener("timeupdate",
    function(){       
      document.getElementById("time").innerHTML =
               Math.floor(video1.currentTime) + "/" + Math.floor(video1.duration) + "(초)";
    }
    , false
  );  
    
  //progress 이벤트 구현(비디오 다운로드 현황 표시)
  video1.addEventListener("progress",
    function(e){
      var downLoadState = document.getElementById("downLoadState");
     
      if(video1.networkState == 2){
        downLoadState.innerHTML = e.loaded + "/" + e.total + "byte";       
      }
      else if(video1.networkState == 3){
        downLoadState.innerHTML = "완료";
      }
    }
    , false
  );       
</script>


브라우저 호환성 확보
앞서 Video, Audio 에 대한 브라우저 지원 현황을 알아 보았다
Video, Audio 는 두 가지 지원 현황을 파악해야 한다고 했는데 요약하자면 다음과 같다
1) Video, Audio 지원 현황
2) 코덱 지원 현황

즉 브라우저가 Video, Audio 자체를 지원하다고 하더라도 지원되는 코덱이 서로 상이하기 때문에
브라우저가 지원하는 코덱정보를 정확히 알고 있어야 원활한 서비스가 가능하다는 것이다

HTML5 멀티미디어 구현을 위해 브라우저 호환성을 확보하기 위한 모든 방법을 알아 보자

1) Video 지원 여부 확인하기
앞에서 알아 본 방법이다.
if(!!document.createElement('video').canPlayType) ...
으로 브라우저가 Video 태그를 지원하는지 체크할 수 잇다

2) 대체 요소 출력
역시 앞에서 알아 본 방법이다. 태그 사이에 대체 요소를 출력한다
<video src="http://www.double.co.nz/video_test/transformers480.ogg">
    HTML5 Video 를 지원하지 않는 브라우저 입니다
</video> 

3) 코덱 호환성 확보
마지막으로 브라우저별로 상이한 코덱 지원을 검사하여 정상적인 동작을 보장해야 한다
예를들어 사파리의 경우 H.264 를 지원하고 파이어폭스의 경우 Theora를 지원하기 때문에
모든 브라우저에서 정상 동작 시키기 위해서는 각 브라우저가 지원하는 형식으로 서비스를 해야 한다

브라우저가 특정 코덱을 지원하는지 검사하려면 Video 의 canPlayType() 함수를 이용하면 된다
아래 코드는 theora 비디어코덱과 vorbis 오디오 코덱으로 구성된 ogg컨테이너 형식의 멀티미디어를
지원하는지 체크하는 코드이다
var video1 = document.getElementById("video1");
return video1.canPlayType('video/ogg; codecs="theora, vorbis"'


그리고 더 쉽게 코덱 호환성을 확보 할 수 있는 방법이 있는데,
바로 <video>,<audio> 태그 사이에 정의되는 <source> 태그를 이용하는 방법이다
<soruce> 태그는 멀티미디어 파일의 위치(소스)를 지정하는 src 속성의 역할과 동일하다

다만 이 태그는 여러개를 중복해서 정의할 수 있는데, 이 경우 멀티미디어 파일의 형식 즉 코덱정보를 명시하여 지정할 수 있다. 브라우저는 여러개의 <source> 태그를 차례대로 검사해서 자신이 지원하는 코덱과 일치하는 <source> 를 채택하여 재생시킨다

그리고 <source> 태그를 이용하면 HTML5 이전의 멀티미디어 환경 즉 플래시나 실버라이트와 같은
형식의 지정도 가능하다. 즉 브라우저가 HTML5 자체를 지원하지 않을 경우 플래시로 대체하는 코드 작성이 가능하다는 것이다(물론 각 버전에 맞는 동영상이 미리 준비되어 있어야 겠지만...)

결과적으로 <soruce> 태그를 이용하여 코덱과 관련한 브라우저 호환성을 쉽게 확보할 수 있는 것이다
아래 코드는 코덱 호환성 확보를 위한 몇 가지 샘플 코드이다
(출처: http://dev.opera.com/articles/view/everything-you-need-to-know-about-html5-video-and-audio/)
- ogv 와 mp4 지원
<video controls>
  <source src="video.ogv" type='video/ogg; codecs="theora, vorbis"'>
  <source src="video.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
video not supported
</video>

- ogv, applet 지원
<video controls>
<source src="video.ogv" type='video/ogg; codecs="theora, vorbis"'
         onerror="fallback(this.parentNode)">
<object type="application/x-java-applet" width="480" height="288">
  <param name="archive" value="cortado-ovt-stripped-wm_r51500.jar">
  <param name="code" value="com.fluendo.player.Cortado.class">
  <param name="url" value="video.ogv">
  video and Java not supported
</object>
</video>

- mp4, swf 지원
<video controls>
<source src="video.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'
         onerror="fallback(this.parentNode)">
<object data="videoplayer.swf">
  <param name="flashvars" value="video.mp4">
  video and Flash not supported
</object>
</video>

HTML Video, Audio 태그가 지원되지 않을 때 플래시나 윈도우 미디어로 대체하는 스크립트를
제공해 주는 다음의 사이트를 참고하기 바란다


마지막으로 Video, Audio 와 관련된 데브 오페라 사이트를 참고해 추가 학습하도록 하자
http://dev.opera.com/articles/view/everything-you-need-to-know-about-html5-video-and-audio/

'모바일 > HTML5' 카테고리의 다른 글

[HTML5] 웹 양식(Web Form)의 개선, 폼 태그  (4) 2010.08.26
HTML5 관련 유용한 레퍼(참조) 사이트  (0) 2010.08.26
[HTML5] Canvas  (3) 2010.08.19
[HTML5] Web SQL Database  (0) 2010.08.17
[HTML5] 오프라인 웹 어플리케이션  (0) 2010.08.12