バックグラウンド
WebClient.OpenReadAsync/OpenReadCompleted と Stream.BeginRead/AsyncCallback を使用して、メディア ファイルを Silverlight 4 アプリケーションに段階的にダウンロードしています。目標は、SetSource メソッドを呼び出してカスタム MediaStreamSource のインスタンスを渡すことにより、MediaElement でファイルを再生することです。これにより、ファイルのコンテンツ全体がダウンロードされる前にファイルの再生を開始できます。メディア ファイルはカスタム エンコード/デコードを使用しているため、カスタム MediaStreamSource を使用しています。MediaStreamSource は、Stream を受け入れ、トラック情報の解析を開始し、MediaElement で再生するように構築されています。ファイルの内容を段階的にダウンロードしていることを確認しました。ダウンロード コードの概要は次のとおりです。
public void SetSource(string sourceUrl)
{
var uriBuilder = new UriBuilder(sourceUrl);
WebClient webClient = new WebClient();
// AllowReadStreamBuffering = false allows us to get the stream
// before it's finished writing to it.
webClient.AllowReadStreamBuffering = false;
webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted);
webClient.OpenReadAsync(uriBuilder.Uri);
}
void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
_inboundVideoStream = e.Result;
BeginReadingFromStream();
}
private void BeginReadingFromStream()
{
if (_inboundVideoStream.CanRead)
{
_chunk = new byte[_chunkSize];
_inboundVideoStream.BeginRead(_chunk, 0, _chunk.Length, new AsyncCallback(BeginReadCallback), _inboundVideoStream);
}
}
private void BeginReadCallback(IAsyncResult asyncResult)
{
Stream stream = asyncResult.AsyncState as Stream;
int bytesRead = stream.EndRead(asyncResult);
_totalBytesRead += bytesRead;
if (_playableStream == null)
_playableStream = new MemoryStream();
_playableStream.Write(_chunk, 0, _chunk.Length);
if (!_initializedMediaStream && _playableStream.Length >= _minimumToStartPlayback)
{
_initializedMediaStream = true;
// Problem: we can't hand the stream source a stream that's still being written to
// It's Position is at the end. Can I read and write from the same stream or is there another way
MP4MediaStreamSource streamSource = new MP4MediaStreamSource(_playableStream);
this.Dispatcher.BeginInvoke(() =>
{
mediaElement1.SetSource(streamSource);
});
}
if (_totalBytesRead < _fileSize)
{
ReadFromDownloadStream();
}
else
{
// Finished downloading
}
}
上記のように、MemoryStream への書き込みと読み取りの両方を同時に試みたほか、IsolatedStorageFile への書き込みと、書き込み中にそのファイルからの読み取りを試みました。これまでのところ、どちらのアプローチも機能させる方法を見つけることができません。
質問:
同じストリームを読み書きする方法はありますか? または、ストリームと MediaStreamSource を使用してこれを実装する標準的な方法はありますか?
ありがとう