サイトトップ

Director Flash 書籍 業務内容 プロフィール

Macromedia Flash非公式テクニカルノート

ボリューム0でSound.loadSound()すると100に戻しても音が聴こえない

ID: FN0509001 Product: Flash

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.loadSound()メソッドを使った外部MP3のロードと再生については、「Sound.loadSound()メソッド」および「Sound.loadSoundメソッドでイベントサウンドを読込んで再生する」をご参照ください。。

原因
ふたつの要因により、再現される問題です。結論として、バグと考えます。

まず、(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日


Copyright © 2001-2006 Fumio Nonaka.  All rights reserved.