Platform: All
Version: MX 2004 and above
問題
Sound.loadSound()メソッドで、外部MP3をロードした場合の問題です[*1]。Sound.setVolume()メソッドによりボリュームを0に設定してサウンドを読込むと、ボリュームを100に戻しても音は聴こえてこないという現象が報告されています。
たとえば、以下のスクリプトは外部MP3をストリーミングサウンドとしてロードし、フェードインで再生しようとするものです(スクリプト001)。ところが、ボリュームの値(Sound.getVolume()メソッドの戻り値)が100を返しても、サウンドは聴こえません。イベントサウンドとしてロードしても、同様の現象が発生します。
Flash MX 2004 7.2/Mac OS X.3.9およびWindows XP (SP1)で確認されています。また、Flash 8.0/Mac OS X.4.5でも、同じ問題が確認されました。
スクリプト001■ストリーミングサウンドをフェードイン: 音が出ない
// フレームアクション
//[1]Soundインスタンス生成
var my_sound:Sound = new Sound();
//[2]ボリュームを0に設定
var nVolume:Number = 0;
my_sound.setVolume(nVolume);
//[3]ストリーミングサウンドのロード
my_sound.loadSound("test.mp3", true);
trace(my_sound.getVolume()); // テスト用
//[4]フェードイン
this.onEnterFrame = function() {
nVolume += 5; // ボリュームアップ
if (nVolume>=100) { // 100%に達したら
// ボリュームを100%に設定
my_sound.setVolume(100);
// フェードイン処理クリア
delete this.onEnterFrame;
} else { // 100%未満なら
// ボリューム設定
my_sound.setVolume(nVolume);
}
trace(my_sound.getVolume()); // テスト用
};
|
原因
ふたつの要因により、再現される問題です。結論として、バグと考えます。
まず、(1)インスタンス生成時、コンストラクタ関数SoundにターゲットのMovieClipを指定していないことです。「ターゲットインスタンスを指定しないと、Soundオブジェクトは ムービー内のすべてのサウンドを制御します」(Flash MX 2004[ActionScriptリファレスンガイド] > [Soundクラス])。つぎに、(2)Sound.setVolume()メソッドを使って、Sound.loadSound()で外部MP3サウンドをロードする前に、ボリュームを0に設定しています。
(1)(2)のふたつの要素が備わると、外部MP3サウンドロード後にボリュームを100に戻しても、音が聴こえなくなります。なお、Sound.attachSound()メソッドで[ライブラリ]のリンケージMP3サウンドを配置した場合には、この現象は確認されませんでした。
対処法
ふたつの要因(1)(2)のうちひとつを解決すれば、少なくともサウンドは聴こえるようになります。
まず、(1)Soundインスタンスの生成には、基本的にターゲットのMovieClipを指定することが推奨されます。ムービー全体のサウンドを対象としたい場合には、通常_rootをターゲットとすれば足りるでしょう。ターゲットとして_rootを指定しても、この問題は解消されます。
さらに、(2)Sound.loadSound()メソッドで外部MP3サウンドをロードする前には、ボリュームの設定は100にしておく方がよいでしょう。本来、外部MP3サウンドをロードすると、ボリュームの値は100にリセットされます。そのため、ロード前に100以下に設定することは効果がなく[*2]、それが有効である前提でスクリプティングを行うと、予想外の結果になる可能性があります。
たとえば、上記スクリプト001で、Soundコンストラクタにターゲットthisを与え、new Sound(this)とすると、サウンドのフェードインは動作します。しかし、ロード直後にボリュームが100にリセットされるため、一瞬フルボリュームのサウンドが立上がって、つぎのフレーム(onEnterFrame)からフェードインが始まるという挙動になります。したがって、ロード前のボリュームは100を前提とし、ロード後からコントロールを開始するのがよいでしょう(スクリプト002)。
スクリプト002■ストリーミングサウンドをフェードイン: 正しく動作
// フレームアクション
//[1]Soundインスタンス生成
var my_sound:Sound = new Sound(this); // ターゲットを指定
//[2]ボリュームの初期値を0に設定
var nVolume:Number = 0;
// my_sound.setVolume(100); // ボリューム設定が変動する可能性のあるときは100に戻す
//[3]ストリーミングサウンドのロード
my_sound.loadSound("test.mp3", true);
//[4]ボリュームを設定【ロード開始後】
my_sound.setVolume(nVolume);
trace(my_sound.getVolume()); // テスト用
//[5]フェードイン
this.onEnterFrame = function() {
nVolume += 5; // ボリュームアップ
if (nVolume>=100) { // 100%に達したら
// ボリュームを100%に設定
my_sound.setVolume(100);
// フェードイン処理クリア
delete this.onEnterFrame;
} else { // 100%未満なら
// ボリューム設定
my_sound.setVolume(nVolume);
}
trace(my_sound.getVolume()); // テスト用
};
|
[*2] 今回の問題の場合にも、ロード後のSound.getVolume()メソッドの戻り値は100にリセットされます。しかし、実際のボリュームは、事前の音量のまま変化しません。つまり、その音量をボリューム100の状態と誤認してしまうことが、問題の原因となっているようです。
したがって、事前のボリュームを10に設定すると、音が聴こえなくなる現象は生じないものの、ボリュームを100に戻しても10の音量でしか再生されない状態になります。ですから、外部MP3サウンドロード前のボリュームの値は、100に設定しておくことが確実といえます。
|
_____
作成者: 野中文雄
更新日: 2006年4月5日 Flash 8.0で同じ問題が確認された旨を追加
作成日: 2005年9月2日