Мой вопрос касается записи видеофайла на жесткий диск, который загружается из сети, и одновременного его воспроизведения с помощью Windows Media Player. Файл довольно большой, и его загрузка займет некоторое время. Это необходимо для загрузки, а не для потоковой передачи напрямую в проигрыватель Windows Media.
Что происходит, хотя я могу записывать в видеофайл и одновременно читать его из моего собственного тестового кода, этого нельзя сделать с помощью Windows Media Player (по крайней мере, я не понял этого). Я знаю, что это возможно, потому что это делают загрузки Amazon Unbox. Unbox позволяет воспроизводить файлы WMV во время их загрузки. А Unbox написан на .NET, так что ...
Я прочитал «чтение / запись файла C # не делает» Кажется, работает "вопрос и ответы на открытие файла с помощью флажков 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);
}
Кажется, это нормально работает. Файл записывается на диск и имеет правильные разрешения.
Но затем в другом потоке есть обработчик событий для воспроизведения видео.
// the playback thread
private void OnBufferingComplete(object sender, BufferingCompleteEventArgs e)
{
axWindowsMediaPlayer1.URL = e.MediaFile.FullName;
}
Проигрыватель Windows Media указывает, что он открывает файл, а затем просто останавливается с ошибкой, что файл не может быть открыт «уже открыт в другом процессе».
Я перепробовал все, что мог придумать. Что мне не хватает? Если парни из Amazon могут это сделать, то смогу и я, верно?
изменить: этот код работает с mplayer, VLC и Media Player Classic; только не проигрыватель Windows Media или проигрыватель Windows Media Center. IOW, единственные игроки, с которыми мне нужно работать. фу!
edit2: Я дошел до того, что использовал MiniHttp для потоковой передачи видео в Windows Media Player, чтобы посмотреть, может ли это «обмануть» WMP в воспроизведении загружаемого видео. Ничего не делая. Хотя WMP действительно открывал файл, он ждал, пока файл mpeg не будет полностью скопирован, прежде чем начать воспроизведение. Откуда это знать?
edit3: Покопавшись, я обнаружил проблему. Я работаю с файлами MPEG2. Проблема не обязательно в проигрывателе Windows Media, а в Microsoft MPEG2 DirectShow Splitter, который WMP использует для открытия файлов MPEG2, которые я пытаюсь воспроизвести и загрузить одновременно. Splitter открывает файлы в режиме без общего доступа. Не так с файлами WMV. WMP открывает их в общем режиме, и все работает как положено.