Мой вопрос о написании видеофайла на жесткий диск, который загружается из сети и воспроизводится в то же время с помощью проигрывателя Windows Media. Файл довольно большой и потребуется некоторое время для загрузки. Необходимо загрузить его, а не просто передать его прямо в Windows Media Player.Воспроизведение больших файлов на проигрывателе Windows Media во время загрузки
Случается, что, хотя я могу писать в видеофайл и читать его в то же время из собственного тестового кода, это невозможно сделать с помощью проигрывателя Windows Media (по крайней мере, я этого не понял). Я знаю, что это возможно, потому что Amazon Unbox загружает это. Unbox позволяет воспроизводить WMV во время загрузки. И Unbox написан на .NET так ...
Я прочел вопрос «C# file read/write fileshare doesn’t appear to work» и ответил, открывая файл с флагами FileShare. Но это не работает для меня. Process Monitor говорит, что Media Player открывает файл с флагами Fileshare, но он ошибается.
В буферным нити у меня есть этот код для чтения файла из сети и не писать его в файл (без обработки ошибок или других вещей, чтобы сделать его более удобным для чтения):
// the download thread
void StartStreaming(Stream webStream, int bufferFullByteCount)
{
int bytesRead;
var buffer = new byte[4096];
var fileStream = new FileStream(MediaFile.FullName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
var writer = new BinaryWriter(fileStream);
var totalBytesRead = 0;
do
{
bytesRead = webStream.Read(buffer, 0, 4096);
if (bytesRead != 0)
{
writer.Write(buffer, 0, (int)bytesRead);
writer.Flush();
totalBytesRead += bytesRead;
}
if (totalBytesRead >= bufferFullByteCount)
{
// fire an event to a different thread to tell
// Windows Media Player to start playing
OnBufferingComplete(this, new BufferingCompleteEventArgs(this, MediaFile));
}
} while (bytesRead != 0);
}
Это похоже на работу хорошо. Файл записывается на диск и имеет правильные разрешения.
Но Heres обработчик событий в другом потоке для воспроизведения видео
// the playback thread
private void OnBufferingComplete(object sender, BufferingCompleteEventArgs e)
{
axWindowsMediaPlayer1.URL = e.MediaFile.FullName;
}
Windows Media Player указывает, что его открытие файла, а затем просто останавливается с ошибкой, что файл не может быть открыт «уже открыт в другом процессе».
Я пробовал все, что мог придумать. Что мне не хватает? Если ребята из Amazon могут это сделать, тогда я тоже, правильно?
Редактировать: Этот код работает с mplayer, VLC и Media Player Classic; просто не проигрыватель Windows Media Player или проигрыватель Windows Media Center. IOW, единственные игроки, с которыми мне нужно работать. тьфу!
Редактировать2: Я зашел так далеко, чтобы использовать MiniHttp для потокового видео в Windows Media Player, чтобы увидеть, будет ли это «дурачить» WMP в воспроизведении видео, которое загружается. Ничего не делая. Пока WMP открывал файл, он ждал, пока файл mpeg не будет полностью скопирован, прежде чем он начнет воспроизводиться. Как это знать?
edit3: После некоторого рытья я обнаружил проблему. Я работаю с файлами MPEG2. Проблема не всегда связана с проигрывателем Windows Media, но с разветвителем DirectShow Microsoft MPEG2, который WMP использует для открытия файлов MPEG2, которые я пытаюсь воспроизвести и загрузить одновременно. Splitter открывает файлы в режиме без совместного доступа. Не так с WMV-файлами. WMP открывает их в режиме общего доступа, и все работает так, как ожидалось.
@Bevan, указав FileShare.Write при создании файла, означает, что медиа-плеер никогда не сможет открыть файл для чтения. –
@ дарин - спасибо за головы. FileShare не означает, что я думал, что это так. Я обновил свой ответ в соответствии с моим улучшенным пониманием. – Bevan