none
【ActiveX】ActiveXの中にMediaPlayerクラスを利用して、音声を再生できますか? RRS feed

  • 質問

  • 皆さん、おはようございます。Icyfireです

    朝っぱらから、質問して、申し訳ございません。

    要件としては、カード認証ActiveXでカード認証OK・失敗時、各自の音声を再生したいです。

    現在カード認証自体は問題ありませんが、C#のMediaPlayerクラスでオブジェクトを作って、音声を再生しようと、

    成功しませんでした。何のエラーも出ておりません。

    ※音声ファイルはカード認証ActiveXプロジェクトの直下に追加してます。(プロジェクトに含まれている)

    ※MediaPlayerクラスの利用ソース:

    MediaPlayer media = new MediaPlayer();
    media.Open(new Uri("./card_ok.mp3", UriKind.RelativeOrAbsolute));
    media.Play();

    ここで、皆さんに確認したいのは

    ・ActiveXで音声の再生はできますか(音声はプロジェクトに含まれている状態)

    できるなら、どうすればよろしいのか。

    ・もし、この方法がだめだったら、ほかの解決道がありますか。

    皆さんのお知恵をかしたいです。ご教授いただけると、ありがたいです。

    ※補足:

    上記の音声パスを相対パスではなく、ローカルの絶対パス(F:/.../.../card_ok.mp3)にしたら、再生できます。


    2016年8月25日 0:32

回答

  • こんばんは、非常に嬉しいです。

    ネット上で探して、やっと解決できました。

    時間がかかりましたけど、解決できて、嬉しいです。^_^

    解決方法としては二つあります。

    方法1:

    1:ソリューションプロパティのリソースタブに音声ファイル(card_OK.mp3)をリソースとして追加

    2:NAudio をネットから、ダウンロードして、プロジェクトに追加

    ☆NAudio はMp3ファイルを再生するためのライブラリ。

    ☆WAVの音声のみを再生するなら、このライブラリ不要。

    3:下記の形で音声を再生する

    MemoryStream mediaStream = new MemoryStream(Properties.Resources.card_OK);
    WaveStream blockAlignedStream = default(WaveStream);
    blockAlignedStream = new BlockAlignReductionStream(WaveFormatConversionStream.CreatePcmStream(new Mp3FileReader(mediaStream)));
    
    using (WaveOut waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback()))
        {
             waveOut.Init(blockAlignedStream);
             waveOut.Play();
             while (waveOut.PlaybackState == PlaybackState.Playing)
               {
                  System.Threading.Thread.Sleep(100);
                }
         }

    方法2:

    1:card_OK.mp3を普通のアイテムとして、プロジェクトに追加

    2:card_OK.mp3 のプロパティを変更

     ☆ビルドアクション:埋め込まれたリソース

    3:下記の形で、埋め込まれたリソースを読み取る

    Assembly modulePath = Assembly.GetExecutingAssembly();
    // リソース名は「名前空間名 + リソース名」とする
    var mediaStream = (MemoryStream)modulePath.GetManifestResourceStream("名前空間.card_OK.mp3");
    
    
    

    これで、音声ファイルの中身がmediaStream に格納されていた。



    • 回答としてマーク icyfire028 2016年8月26日 8:01
    • 回答としてマークされていない icyfire028 2016年8月26日 8:01
    • 回答としてマーク icyfire028 2016年9月16日 3:07
    2016年8月25日 15:01

すべての返信

  • media.Open(new Uri("./card_ok.mp3", UriKind.RelativeOrAbsolute));

    上記の音声パスを相対パスではなく、ローカルの絶対パス(F:/.../.../card_ok.mp3)にしたら、再生できます。

    念のため確認ですが、相対パスというのはカレントディレクトリからの相対パスなわけですが、カレントディレクトリがどこに設定されているか把握できていますか?
    2016年8月25日 2:08
  • media.Open(new Uri("./card_ok.mp3", UriKind.RelativeOrAbsolute));

    上記の音声パスを相対パスではなく、ローカルの絶対パス(F:/.../.../card_ok.mp3)にしたら、再生できます。

    念のため確認ですが、相対パスというのはカレントディレクトリからの相対パスなわけですが、カレントディレクトリがどこに設定されているか把握できていますか?

    ご回答頂き、有難うございます。

    おっしゃるとおりです。普通のAPPだと、Exeファイルのあるフォルダーがカレントディレクトリになっていますが、

    ActiveXやComだと、カレントディレクトリはどこになるのでしょう?

    確認方法はご存知でしょうか?もしご存知でしたら、教えて頂けますか?

    もしCABファイルなどを作成しておいて、Browserからダウンロードして、インストールさせるなら、相対パスでも使えるかな(疑問?)

    最初、私の発想としては、メディアファイルは既にプロジェクトに含まれ、同じDllにあるのですから、識別できるはずと思ってましたが、

    残念ながら、見つからないようですね。(WPFなど、Exeに含まれると、相対パスでもアクセスできます)

    この方法に限らず、ほかの解決手法もあったら、ぜひ、教えてください。

    2016年8月25日 2:29
  • 回答が中途半端でした。以下、加筆しようとしていましたが先に返信をいただいてしまったので、追加の回答とします。

    カレントディレクトリはプロセス内で共有される設定ですので、質問者さんの意にそぐわないディレクトリに設定されていたと判明したとして、むやみに変更すべきではありません。

    ということになれば絶対パスで指定すべきです。F:/.../ のようなアドレスをソースコードにハードコーディングしたくないということでしたら実行時にパスを組み立てるべきです。例えば基準となるモジュールの置かれているディレクトリ+相対パスをPath.Combine()で結合するなど。

    2016年8月25日 2:40
  • 回答が中途半端でした。以下、加筆しようとしていましたが先に返信をいただいてしまったので、追加の回答とします。

    カレントディレクトリはプロセス内で共有される設定ですので、質問者さんの意にそぐわないディレクトリに設定されていたと判明したとして、むやみに変更すべきではありません。

    ということになれば絶対パスで指定すべきです。F:/.../ のようなアドレスをソースコードにハードコーディングしたくないということでしたら実行時にパスを組み立てるべきです。例えば基準となるモジュールの置かれているディレクトリ+相対パスをPath.Combine()で結合するなど。

    ご回答頂き、有難うございます。

    ネット上に検索してみたら、確かに今動いているDLLのパスを取得できそうです。

    Assembly.GetExecutingAssembly メソッド

    では、今、上記のメソッドでDLLのパスを取得したとして、再生したいメディアはリソースとして既にDLLと一緒にコンパイルされていましたので、メディアを再生する方法は同じく下記のようですか??なんか、不気味ですね。

    string modulePath = Assembly.GetExecutingAssembly(); media.Open(new Uri(modulePath + "./card_ok.mp3", UriKind.RelativeOrAbsolute));

    2016年8月25日 4:57
  • 回答が中途半端でした。以下、加筆しようとしていましたが先に返信をいただいてしまったので、追加の回答とします。

    カレントディレクトリはプロセス内で共有される設定ですので、質問者さんの意にそぐわないディレクトリに設定されていたと判明したとして、むやみに変更すべきではありません。

    ということになれば絶対パスで指定すべきです。F:/.../ のようなアドレスをソースコードにハードコーディングしたくないということでしたら実行時にパスを組み立てるべきです。例えば基準となるモジュールの置かれているディレクトリ+相対パスをPath.Combine()で結合するなど。

    補足です。

    このActiveXは<OBJECT>タグでHTMLに埋め込んでいます。

    HTMLにあるボタンを押されたら、ActiveXを呼び出されます。

    つまり、このActivXはIEのプラグイン(アドオン)です。

    現在ではMediaPlayerクラスのオブジェクトでプラグインと同梱したリソースファイル(音声ファイル)を再生したいです。

    だがうまくいかないので、この質問をさせたというわけです。

    2016年8月25日 5:01
  • こんばんは、非常に嬉しいです。

    ネット上で探して、やっと解決できました。

    時間がかかりましたけど、解決できて、嬉しいです。^_^

    解決方法としては二つあります。

    方法1:

    1:ソリューションプロパティのリソースタブに音声ファイル(card_OK.mp3)をリソースとして追加

    2:NAudio をネットから、ダウンロードして、プロジェクトに追加

    ☆NAudio はMp3ファイルを再生するためのライブラリ。

    ☆WAVの音声のみを再生するなら、このライブラリ不要。

    3:下記の形で音声を再生する

    MemoryStream mediaStream = new MemoryStream(Properties.Resources.card_OK);
    WaveStream blockAlignedStream = default(WaveStream);
    blockAlignedStream = new BlockAlignReductionStream(WaveFormatConversionStream.CreatePcmStream(new Mp3FileReader(mediaStream)));
    
    using (WaveOut waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback()))
        {
             waveOut.Init(blockAlignedStream);
             waveOut.Play();
             while (waveOut.PlaybackState == PlaybackState.Playing)
               {
                  System.Threading.Thread.Sleep(100);
                }
         }

    方法2:

    1:card_OK.mp3を普通のアイテムとして、プロジェクトに追加

    2:card_OK.mp3 のプロパティを変更

     ☆ビルドアクション:埋め込まれたリソース

    3:下記の形で、埋め込まれたリソースを読み取る

    Assembly modulePath = Assembly.GetExecutingAssembly();
    // リソース名は「名前空間名 + リソース名」とする
    var mediaStream = (MemoryStream)modulePath.GetManifestResourceStream("名前空間.card_OK.mp3");
    
    
    

    これで、音声ファイルの中身がmediaStream に格納されていた。



    • 回答としてマーク icyfire028 2016年8月26日 8:01
    • 回答としてマークされていない icyfire028 2016年8月26日 8:01
    • 回答としてマーク icyfire028 2016年9月16日 3:07
    2016年8月25日 15:01