MediaFoundationでの音量操作 – c#

質問:


以前にTeraTailsのサイトに質問したのですが全く反応がないのでこちらに質問し直します。

C#で動画の制御をしたいと思いDirectShowとMediaFoundationを迷いましたが、MS的に後発であるし、.NETのライブラリがあると言う事でMediaFoundation.NETを使用することにしました。

https://sourceforge.net/projects/mfnet/

実際にはVS2017でNuGetのパッケージを入れております。

細かいところは省略しますが、動画再生に関する部分はほぼサンプル(MFSamples-2016-09)を使用しました。

厳密にやりたいのは動画の細かい制御(コマ送りだったり、再生スピード変更、二つの動画をそれぞれ再生位置を変更した後に同期再生・・等)ですが、とりあえずウィンドウ内のパネル等に動画を表示・再生・一時停止、TrackBarで再生位置を変更するような所までは出来るようになりました。

ですがいろんなサンプルを眺めたつもりなのですが音量操作の部分がどうしても分かりません。
MediaSessionから作成するのは同じだと思うのですが、IMFSimpleAudioVolumeが分かりやすい名前でしたが、調べるとMSがこれをサンプルでも使用していないとかのディスカッションが見つかります。

結局王道としてどうして良いのかさっぱり分からない状況です。

正直音量は細かい操作は必要ないのでこんな所に時間がかかるとは思わず、結構萎えてきてしまってる状況です。
(極端、元のボリュームとミュートが切り替えられるだけでも良いのですが、Windows自体のボリュームをミュートしてしまうのは不可なので)

サンプルがあれば一番良いですが、参考資料などございませんでしょうか?

よろしくお願い致します。

==9月5日追記==

コメント頂いたサイト(C++)を参考に

object ppvObject;
MFExtern.MFGetService(m_pSession, MFServices.MR_STREAM_VOLUME_SERVICE, typeof(IMFAudioStreamVolume).GUID, out ppvObject);
m_pAudioStreemVolume = (IMFAudioStreamVolume)ppvObject;

としてみたのですがm_pAudioStreemVolumeがnullになってしまいます・・・
(正確にはppvObjectがnullで返ってきてます)

手探りでここまで来たんですが行き詰まってしまいました。
何が間違っているのでしょうか・・・・
動画再生や再生速度変更、再生位置変更等は問題ないので、後は音関係だけなのですが・・・
海外サイトでも情報が少ないので結構キツイですね・・・・

質問者: ランディ

音量操作に使うのはIMFAudioStreamVolumeのようです。

C++での一連の記事があるようなので、参考にしてください。
MediaFoundationを使う 記事まとめ

関連するところを抽出すれば、以下になるでしょう。

MediaFoundationを使う (2) MediaFoundation管理クラスの宣言

使用するインターフェイスは?
今回再生で使用するMediaFoundationのインターフェイスは以下の通りになります。
インターフェイス名   役割
IMFMediaSession    メディア全体の状態を管理する。
IMFByteStream     MediaFoundation内でバイト単位のデータをやりとりするときに
             使うインターフェイス。
IMFMediaSource     メディアのソース部(ByteStreamも含む)を管理する
IMFPresentationClock  メディア再生時の基準時間の管理を行う。
IMFVideoDisplayControl ビデオ状態の管理を行う。
IMFAudioStreamVolume オーディオの音量管理を行う。

MediaFoundationを使う (4) MediaFoundation管理クラス実装その2

音量系の処理
//パンの変化を設定する
BOOL CMFSession::SetPan(int nAbsolutePan)
//音量の設定をする
BOOL CMFSession::SetVolume(int nAbsoluteVolume)
サポート関数のInnerSetVolumeに任せているだけなのでそちらでやります。

MediaFoundationを使う (5) MediaFoundation管理クラス実装その3

内部音量設定
//ボリュームを設定する
HRESULT CMFSession::InnerSetVolume(void)

追記部分について

としてみたのですがm_pAudioStreemVolumeがnullになってしまいます・・・

について、IMFAudioStreamVolumeには

The streaming audio renderer (SAR) exposes this interface as a service. To get a pointer to the interface, call IMFGetService::GetService with the service identifier MR_STREAM_VOLUME_SERVICE.

と説明されていますから、MFExtern.MFGetService()の第一引数はstreaming audio renderer (SAR)オブジェクトを渡す必要があります。

出典

Related Posts:

C言語のポインターで詰まっている。 [クローズ済み] – c
質問: 下記でコンパイルエラーになる。 #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char *buf="<title>sample</title>"; char work; char *p; ...
文字列の部分置換 – c# .net
質問: 文字列の部分置換を行いたいと思うのですが 簡単な方法を教えてください。 例えば String data = "かきくけこさしくせそあいくえお"; 最後の"く"を "う" に置換したい。 次は、"く" を "す" に置換したい。 例では、規則性があるように見えますが、実際の データは、置換する文字列の前後は、規則性がありませんので 正規表現は、使用できません。 以上 質問者: Devai kaorun 通常、このような条件だとsayuriさんの例のように正規表現で処理するのが常道かと思います。 が、どうしても、System.Text.RegularExpressions名前空間は親の仇で使えない等の理由があるのであれば、お手軽なメソッドは用意されていないと思われるので、String.LastIndexOf()と.Substring()を使ってちまちま切張りするのがおそらく一番ストレートなアプローチになるでしょう。 static void Main(string args) { var source = "かきくけこさしくせそあいくえお"; ...
読み込みと表示について – c++
質問: 演習1ー5が書けなくて困ってます。まだ始めたてなので教えてください🙏 実行結果に自分が入力した数字を入れられなくて困ってます #include<stdio.h> int main() { int no; printf(“整数を入力してください。n”); scanf(“%d”,&no); printf(“に12を加えると%dです。n”,12+no); return 0; } 質問者: user30430 printf(“に12を加えると%dです。n”,12+no); を printf("%dに12を加えると%dです。n",no, 12+no); にすれば解決すると思います。 詳しくはprintfの使い方とフォーマット指定子を調べてください。 その書籍がなんだかわかりませんが、基本的なことなのでその書籍内でもどこかで説明があると思います。 実行するにはコンパイルを行っているはずですが、コンパイルを行った際に何かメッセージは出ていませんか? 質問文に貼ってあるプログラムは{, }や"などが全角記号で入力されており、実際のソースコードも全角のままだとするとコンパイルの段階でエラーになります。 これらの記号を半角に直してコンパイルをしたところ、生成されたプログラム(a.out)を実行した分には特に問題ありませんでした。 出典
ヨーダスタイルについて [クローズ済み] – c coding-style
質問: とある回答への某コメントで I was tempted to give you an upvote until I saw "Yoda style". That style was horrible even when it was useful. ...
「可変長なスタック,キュー」というデータ構造のプログラムを作成せよ – c
質問: #include <stdio.h> #include <stdlib.h> typedef struct { //?? } STACK; typedef struct { //?? } QUEUE; void push(STACK*, int); int pop(STACK*); void printSTACK(STACK*); void put(QUEUE*, int); int get(QUEUE*); void ...
SQLについてご教授お願いします – c# sql linq
質問: お世話になってます。 IDと日付と連番が同じでコードが1234と1235のデータを取得したいと考えています。 tableA ID  日付    連番  コード 1 20060223 1 ...
C言語についての質問 – c gtk
質問: #include <gtk/gtk.h> #include <math.h> gboolean redraw(GtkWidget *w, gpointer user_data); gboolean draw(GtkWidget *w, gpointer user_data); int main(int argc, char **argv) { GtkWidget *win, *l1, *l2, *l3, *l4, *vbox, *hbox, ...
C言語のポインターに詰まっています。 – c
質問: 下記の結果で、文字化けをする。 #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char *in="abc"; char *out; while(*out++ = *in++); printf("%sn",out); return 1; } 質問者: yamada 2つ問題があります。 書き込む先のメモリが確保されておらず、outが初期化されていませんので、不明の場所に書き込むと,最悪プログラムが異常終了します。 結果を表示するときのoutが、文字終端の次を指しているので、そこにどんなデータがあるか予測できませんので、期待した結果が表示されません。 1の問題はメモリを確保してそのアドレスをoutにセットします。 例: char buf; out = buf; 2の問題は、表示する際、メモリの先頭アドレスをprintfに渡します。 例: printf("%sn", buf); 修正方法はsoramimiさんが答えられているので、何が起こっているのかを説明します。 初期状態 'a', ...
“mbctype.h”, “stdafx.h” のコンパイルが通らない – c
質問: 数年前に組んだCのコンパイルが通らなくなってしまい困っています。 どうやら、 #include "mbctype.h" #include "stdafx.h" のコンパイルが通らないようです。 こちらの2つは使うのに何か条件があるのでしょうか? よろしくおねがいします。 コメントによるとエラーメッセージは $ gcc a.c a.c:3:10: fatal error: 'mbctype.h' file not found #include <mbctype.h> ^ 1 error generated. とのこと。 ...
(C#) win10 Microsoft.Office.Interop.Word でメモリーリーク発生 – c#
質問: vs1015,win7でワード(.doc)からテキスト抽出するのに以下のソースでおこなっていましたがwin10にしたところメモリーリークが発生するようになってしまいました。どう対処したら良いのかご教示の程よろしくお願いします。 Microsoft.Office.Interop.Word.Application word = null; Microsoft.Office.Interop.Word.Document docs = null; try { word = new Microsoft.Office.Interop.Word.Application(); object miss = System.Reflection.Missing.Value; ...
Linux mintのc言語の開発環境について [クローズ済み] – linux c
質問: 今日、Linux mintをダウンロードし、c言語の開発環境を整えたいと思っているのですがどうしたらいいのかわかりません どなたか解決方法を教えてください 質問者: 河地いつき ※ これは、Linux Mint を立ち上げられた上で、どのようにC言語の開発環境を整えるかについて解説した回答です。 どうやってソフトウェアをインストールするか Linux Mint で新しいソフトウェアをインストールするには、Software Manager を使う方法と、Synaptic または apt コマンドを使う方法があります。 Sofware Manager と Synaptic は、Linux Mint のメニューから選択することで起動できます。apt は、ターミナルの上でコマンドを打つことで利用できます。 詳しくは ...
#define に関して – c++ preprocessor
質問: 今、C++のマクロを自力で展開しようとしています。 そこで、"#define" を見つけたのですが、このようになっていました。 #ifndef OuHolder_h #define OuHolder_h このような"#define"は「OuHolder_hが定義されている」ということを表すようなのですが、 これをどう展開すればよいか分かりません。 どうすればいいでしょうか? 質問者: penginest 何をされようとしているのかは分かりませんが、以下は俗にインクルードガードと呼ばれるものです。説明には書かれていませんが、そのファイルの末尾に『endif』も居るはずです。 #ifndef OuHolder_h #define OuHolder_h // 省略 #endif まず、『ifdef』と『ifndef』は違いますので、ご注意を... 『ifndef』から『endif』内は『OuHolder_h』が定義されていなかった場合にのみ実行されます。 なので、2行目の『define』で『OuHolder_h』が定義されると、『ifndef』から『endif』内は実行されません。 これは、同じheader fileを複数ファイルから読んでいる場合に、何度も同じheader fileを読み込まないようにするためのものです。 まずは、簡単なことから理解して徐々にやりたいことを試して行くことをオススメします。 言い換えるなら #ifndef はその定義がまだ定義されていなければ、という意味です。 そのため、定義されていなければ定義する、ということになります。 ...
ViewportRectの参照 – c# unity3d
質問: 題の通り、CameraのViewportRectの値をC#Script内で変更したいのですが、 如何すればよいのでしょうか。 ご教授お願いします。 質問者: Yossy Unity 4.x で試したところ下記の方法で設定可能でした。 var camera = 何かしらの方法でCameraを取得 camera.rect = new Rect(0.0f, 0.0f, 1.0f, 1.0f); 出典
SQLで条件にマッチするレコードが存在するか判定したい – c# sql
質問: tableA ID YMD DAY SE   CSE    CODE 22 ...
「ダブルタップでUIImageViewをズーム」ができません – ios objective-c xcode
質問: ダブルタップでタップした箇所をズームする機能を実装したいのですが、scrollViewに乗せたUIImageViewをズームできません。 (参考サイトはこちらです。)http://cocoadays.blogspot.jp/2010/09/3.html imageViewをズームさせるにはどのようにすれば良いでしょうか? - (void)viewDidLoad { scrollView = initWithFrame:self.view.bounds]; scrollView.frame = self.view.bounds; scrollView.backgroundColor = ; ...

You Might Also Like

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です