ФОН
У меня есть мультимедийный файл, который я постепенно загружаю в свое приложение Silverlight 4, используя WebClient.OpenReadAsync / OpenReadCompleted и Stream.BeginRead / AsyncCallback. Цель состоит в том, чтобы воспроизвести файл в MediaElement, вызвав метод SetSource, передав экземпляр нашего пользовательского MediaStreamSource, чтобы файл мог начать воспроизведение до того, как будет загружено все содержимое файла. Медиа-файл использует пользовательскую кодировку / декодирование, поэтому мы используем пользовательский MediaStreamSource. Наш MediaStreamSource создан для приема потока и начала анализа информации о треках и воспроизведения в 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?
Спасибо