Получение кадров, частоты кадров и других атрибутов видеоклипа
Если у вас есть опыт написания приложений в Microsoft DirectShow Editing Services (кодовое имя Dexter), это будет звучать для вас очень знакомо. В среде Windows традиционно захват неподвижных кадров осуществлялся с использованием C ++ и библиотеки типов Dexter для доступа к COM-объектам DirectShow. Чтобы сделать это в .NET Framework, вы можете создать Interop-сборку DexterLib, которая указана в разделе «Ссылки COM» в VS 2005. Однако вам потребуется немало усилий, чтобы выяснить, как преобразовать код из C ++ в C # .NET. Проблема возникает, когда вам нужно передать ссылку на указатель в качестве аргумента собственной функции, CLR не поддерживает указатели напрямую, поскольку позиция памяти может меняться после каждого цикла сборки мусора. Вы можете найти много статей о том, как использовать DirectShow в CodeProject или в других местах, и мы стараемся сделать его простым. Здесь наша цель - преобразовать видеофайл в массив битовых карт, и я постарался сделать его как можно более коротким, конечно, вы можете написать свой собственный код, чтобы получить битовые карты из живого потока и буферизировать их незадолго до их отправки .
По сути, у нас есть два варианта использования DirectShow для преобразования нашего видеофайла в кадры в .NET:
Отредактируйте сборку Interop и измените ссылки на типы с указателей на типы C # .NET.
Используйте указатели с небезопасным ключевым словом.
Мы выбрали небезопасный (читай быстро) метод. Это означает, что мы извлекаем наши фреймы за пределы управляемой области .NET. Важно отметить, что «управляемый» не всегда означает «лучше», а «небезопасный» не означает «небезопасно»!
MediaDetClass mediaClass = new MediaDetClass ();
_AMMediaType mediaType;
... // загрузить видеофайл
int outputStreams = mediaClass.OutputStreams;
outFrameRate = 0,0;
for (int i = 0; i
}catch
{ // Not a valid meddia type? go to the next outputstream }
}
// Нет частоты кадров?
if (outFrameRate == 0.0)
сгенерировать новое NotSupportedException («Программа не может» +
"прочитать видеофайл.");
// у нас есть частота кадров? двигаться дальше...
...
// Создать массив для хранения растровых изображений и их использования
// другие объекты для хранения информации ...
небезопасно {
...
// создаем байтовый указатель для хранения BitmapBits
...
while (currentStreamPos
// добавляем растровое изображение кадра в frameArray
...
}
}
...
Передача извлеченных данных через HTTP
До сих пор мы конвертировали наше видео в массив растровых кадров. Следующим шагом является передача наших фреймов по HTTP до браузера клиента. Было бы неплохо, если бы мы могли просто отправить биты Bitmap клиенту, но мы не можем. HTTP предназначен для транспортировки текстовых символов, которые означают, что ваш браузер читает только те символы, которые определены в наборе символов HTML-страницы. Все остальное из этой кодировки не может быть отображено напрямую.
Чтобы выполнить этот шаг, мы используем кодировку Base64 для преобразования нашего растрового изображения в символы ASCII. Традиционно кодирование Base64 использовалось для встраивания объектов в электронные письма. Почти все современные браузеры, включая браузеры Gecko, Opera, Safari и KDE (не IE!), Поддерживают данные: стандарт схемы URI для отображения изображений в кодировке Base64. Большой! Теперь у нас есть готовые кадры для передачи по HTTP.
System.IO.MemoryStream memory = new System.IO.MemoryStream ();
while (currentStreamPos
Но мы не можем просто отправить закодированные кадры в виде гигантской строки. Мы создаем XML-документ, который содержит наши кадры и другую информацию о видео, а затем отправляем его клиенту. Таким образом, браузер может получать наши фреймы в виде XML-объекта DOM и легко перемещаться по ним. Представьте, как легко редактировать видео, хранящееся в формате XML:
+14,9850224700412
{Ширина = 160, Высота = 120}
6.4731334
/ 9J / 4AAQSkZJRgABAQEAYAB ....
....
Этот формат также имеет свои недостатки. Видео, преобразованные в файлы XML в кодировке Base64, имеют размер от 10% (в основном AVI-файлы) до 300% и более (некоторые файлы WMV) больше, чем их двоичный эквивалент.
Если вы используете файл XML, вам даже не нужен веб-сервер, вы можете открыть HTML из локального каталога, и он должен работать! В загрузочный файл статьи я включил исполняемый файл, который может преобразовать ваш видеофайл в документ XML, который позже можно будет отобразить в браузере. Однако использование больших файлов и видео высокого разрешения не очень хорошая идея!
Хорошо, теперь мы можем отправить наш XML-документ «Кодированное видео Base64», как мы это сделали бы с любым другим типом XML-файлов. Кто говорит, что XML-файлы всегда должны быть скучными записями?