メディアファイルの保存
Silverlight 4では、キャプチャーしたビデオやオーディオ情報をメモリーにため込んだり、ファイルに書き出したりする機能は、標準でサポートされていません。このため、キャプチャー情報をメディアファイルに書き出したい場合は、AudioSinkクラスやVideoSinkクラスを拡張し、ため込んだメディア情報をファイルなどに書き出す必要があります。
リスト4に、AudioSinkクラスを拡張して、キャプチャーした音声情報をメモリーに格納するMemoryAudioSinkクラスのサンプルを示します。ここでは解説しませんが、VideoSinkクラスもほぼ同じように拡張できます。ただし、音声に比べ動画ファイルはサイズが大きくなりがちなので、データの保存方法を考慮する必要があります。
/// <summary>
/// マイクから取得した音声をメモリー上に保存します。
/// </summary>
public class MemoryAudioSink: AudioSink
{
// 外部から参照するようにAudioFormatをプロパティーとして公開
public AudioFormat Format { get; private set; }
// 外部から参照するようにキャプチャーした音声情報をプロパティーとして公開
public MemoryStream Stream { get; private set; }
protected override void OnCaptureStarted()
{
Stream = new MemoryStream(2048);
}
protected override void OnCaptureStopped()
{
}
protected override void OnFormatChange(AudioFormat audioFormat)
{
Format = audioFormat;
}
protected override void OnSamples(long sampleTimeInHundredNanoseconds,
long sampleDurationInHundredNanoseconds,
byte[] sampleData)
{
Stream.Write(sampleData, 0, sampleData.Length);
}
}
| メソッド名 | 発生するタイミング | 実装する内容 |
| OnCaptureStarted | キャプチャーを開始したとき1度だけ | 初期化 |
| OnCaptureStopped | キャプチャーを停止したとき1度だけ | 後処理 |
| OnFormatChange | オーディオ形式の変更時 | AudioFormatの更新 |
| OnSamples | キャプチャー中に数回 | サンプリングデータの保存 |
単純にメモリー上に音声情報を格納するだけであれば、OnSamplesメソッドをオーバーライドして、サンプリングのタイミングで音声情報をメモリーに保存するだけです。後は、外部から保存された音声情報と、音声を書き出すときに必要となるAudioFormat情報をプロパティとして公開すれば、このメソッドの実装は完了です。
ファイルへの書き出し
メモリーにため込んだデータをファイルに書き出すには、どうすればいいでしょうか。
リスト5では、リスト4でため込んだ音声情報をWAVファイルに保存しています。ただし、Silverlightでは標準でメディア情報をファイルに書き出す機能がありません。このため、多少手間ですが、BinaryWriterクラスやMemoryStreamクラスなどでメディアファイルを直接作成する必要があります。今回はWAVファイルに音声データを保存していますが、WAVファイルの保存方法についてはここでは詳しく解説しません。添付のサンプルコードでは、WavFileWriterクラスにリスト5で利用している保存メソッドを実装しているので、確認してみてください。
private MemoryAudioSink _audioShink = null; // 音声をため込むSinkクラス
private void btnStart_Click(object sender, RoutedEventArgs e)
{
... 略 ...
// CaptureSource作成後にSink設定を追加
_audioShink = new MemoryAudioSink();
_audioShink.CaptureSource = _captureSource,
... 略 ...
}
// 音声データの保存ボタンのイベントハンドラー
private void btnCaptureAudio_Click(object sender, RoutedEventArgs e)
{
// ファイルの保存ダイアログを表示
var saveDialog = new SaveFileDialog() {
DefaultExt = ".wav",
Filter = "WAV ファイル (*.wav)|*.wav",
};
if (saveDialog.ShowDialog() == true)
{
using (var stream = saveDialog.OpenFile())
{
WavFileHelper.WriteWavData(_audioShink.Stream, _audioShink.Format, stream);
stream.Flush();
stream.Close();
}
}
}
MemoryAudioSinkクラスのインスタンスには、リスト2で作成したCaptureSourceのインスタンスを指定することで、ビデオデバイスやオーディオデバイスからのサンプリングが可能になります。ただし、当然ですが、メモリーにデータを蓄え続けることになるので、キャプチャーを放置しておくとOutOfMemoryExceptionが発生することがあります。
オーディオファイルなどのメディアファイルは大容量になることが多いので、分離ストレージではなく、ユーザーストレージに保存するほうが現実的です。リスト5では、SaveFileDialogを使って、ユーザーが任意の場所にファイルを保存できるようにしています。
まとめ
いかがでしょうか? これまでHTML-DOMに頼りきりだったカメラとマイクの分野が、Silverlightだけでも問題なく利用できることが分かっていただけたと思います。
拡張現実(AR)が出てきたときもそうでしたが、ビデオやマイクの利用方法は今後もアイデア次第で広がっていくように思えます。ぜひこれらの機能に触れてみてください。
次回は、業務アプリケーションには欠かせないn階層アプリケーション開発の要であるWCF RIA Servicesについて解説します。
