2013/09/02(月) [n年前の日記]
#1 [haxe] Haxeで音を鳴らす実験
FlashDevelop + Haxe3 + OpenFL とやらで音が鳴らせるか実験中。一応鳴らせたように見えるけど…。
_Flash版
_html5版 (Firefox、Google Chrome、Opera は鳴る。IE10 と Safari は鳴りません)
サウンドファイルは、assets/sound/以下に入れておくとして。
application.xml
Main.hx
flash、neko で出力したら鳴ってくれた。
html5 で出力した場合は問題有り。
canPlayType() を使えれば、ブラウザで対応しているサウンドフォーマットを判別して、拡張子を変更して、対応ブラウザを増やすこともできそうなのだけど。Haxe3 でそれをやる方法が分からず。
まあ、全てのブラウザ上で音を鳴らしたいなら、Flash で出力すればいいだけの話なんだけど…。
_Flash版
_html5版 (Firefox、Google Chrome、Opera は鳴る。IE10 と Safari は鳴りません)
サウンドファイルは、assets/sound/以下に入れておくとして。
. ├─assets │ │ openfl.svg │ │ │ ├─img │ └─sound │ bgm.mp3 │ bgm.ogg │ bgm.wav │ se1.mp3 │ se1.ogg │ se1.wav │ se2.mp3 │ se2.ogg │ se2.wav
application.xml
<?xml version="1.0" encoding="utf-8"?>
<project>
<!-- NMML reference: https://gist.github.com/1763850 -->
<!-- metadata, make sure 'package' is at least 3 segments (ie. com.mycompany.myproject) -->
<meta title="haxe_openfl_sound" package="haxeopenflsound" version="1.0.0" company="mieki256" />
<!-- output -->
<app main="Main" file="haxeopenflsound" path="bin" />
<window background="#CCCCCC" fps="60" />
<window width="640" height="360" unless="mobile" />
<window orientation="landscape" vsync="false" antialiasing="4" if="cpp" />
<!-- classpath, haxe libs -->
<source path="src" />
<haxelib name="openfl" />
<haxelib name="actuate" />
<!-- assets -->
<icon path="assets/openfl.svg" />
<assets path="assets/img" rename="img" />
<assets path="assets/sound" rename="sound" />
<assets path="assets/sound/se1.mp3" id="se1" if="flash" />
<assets path="assets/sound/se2.mp3" id="se2" if="flash" />
<assets path="assets/sound/bgm.mp3" id="bgm" if="flash" />
<assets path="assets/sound/se1.ogg" id="se1" unless="flash" />
<assets path="assets/sound/se2.ogg" id="se2" unless="flash" />
<assets path="assets/sound/bgm.ogg" id="bgm" unless="flash" />
<!-- optimize output
<haxeflag name="-dce full" /> -->
</project>
肝(?)は、以下の部分。
<assets path="assets/sound/se1.mp3" id="se1" if="flash" />
<assets path="assets/sound/se1.ogg" id="se1" unless="flash" />
サウンドファイルにidを割り当てつつ、flash と flash以外で、使うファイルを変える。Main.hx
package ;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.Lib;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.text.TextField;
import openfl.Assets;
/**
* Haxe + OpenFLでサウンドを鳴らすテスト
* @author mieki256
*/
class Main extends Sprite
{
var inited:Bool;
var bgm:Sound;
var se1:Sound;
var se2:Sound;
var sekind:Int;
/* ENTRY POINT */
function resize(e)
{
if (!inited) init();
// else (resize or orientation change)
}
function init()
{
if (inited) return;
inited = true;
if (false) {
// application.xml 内で使うファイルを変えた場合
// BGM
bgm = Assets.getSound("bgm");
// SE read
se1 = Assets.getSound("se1");
se2 = Assets.getSound("se2");
} else {
// ソース内で使うファイルを決めていく場合
var ext:String = "ogg";
#if flash
// flash出力時はここを通る
ext = "mp3";
#elseif html5
// html5出力時はここを通る
ext = "ogg";
// ここで canPlayType() を使って対応形式を判別できれば
// 対応ブラウザを増やせるのだけど…
#end
// BGM
bgm = Assets.getSound('sound/bgm.$ext');
// SE
se1 = Assets.getSound('sound/se1.$ext');
se2 = Assets.getSound('sound/se2.$ext');
}
// BGM 再生開始
var channel:SoundChannel = bgm.play(0, 9999);
#if (flash || neko)
// 音量変更。html5出力時は利用できないみたい
var trans = channel.soundTransform;
trans.volume = 0.5;
channel.soundTransform = trans;
#end
// 文字表示
var tf:TextField = new TextField();
tf.selectable = false;
tf.text = "Click me!";
tf.textColor = 0x333333;
tf.width = 640;
Lib.current.stage.addChild(tf);
sekind = 0;
// マウス左クリック時のイベントを登録
Lib.current.stage.addEventListener(MouseEvent.CLICK, onMouseDown);
}
/**
* マウス左クリック時の処理
* @param e
*/
function onMouseDown(e:MouseEvent):Void
{
// SEを鳴らす
if (sekind == 0) {
se1.play();
} else {
se2.play();
}
sekind = (sekind + 1) % 2;
}
/* SETUP */
public function new()
{
super();
addEventListener(Event.ADDED_TO_STAGE, added);
}
function added(e)
{
removeEventListener(Event.ADDED_TO_STAGE, added);
stage.addEventListener(Event.RESIZE, resize);
#if ios
haxe.Timer.delay(init, 100); // iOS 6
#else
init();
#end
}
public static function main()
{
// static entry point
Lib.current.stage.align = flash.display.StageAlign.TOP_LEFT;
Lib.current.stage.scaleMode = flash.display.StageScaleMode.NO_SCALE;
Lib.current.addChild(new Main());
}
}
肝は、
se1 = Assets.getSound("se1");
se1.play();
だろうか…。xml内で、各サウンドファイルにidを割り当ててあれば、ide文字列を指定するだけで読み込める・再生できるはず。flash、neko で出力したら鳴ってくれた。
html5 で出力した場合は問題有り。
- Firefox、Google Chrome、Opera は鳴った。
- IE10では鳴らなかった。IE10 は ogg 再生に対応してないから、だと思う。
canPlayType() を使えれば、ブラウザで対応しているサウンドフォーマットを判別して、拡張子を変更して、対応ブラウザを増やすこともできそうなのだけど。Haxe3 でそれをやる方法が分からず。
まあ、全てのブラウザ上で音を鳴らしたいなら、Flash で出力すればいいだけの話なんだけど…。
[ ツッコむ ]
以上です。