- PVSM.RU - https://www.pvsm.ru -
Не так давно, возникла необходимость захвата видео с web камеры и передавать его по сети используя .Net.
Так как с подобной задачей я столкнулся впервые, то первым делом начал искать информацию по этому вопросу.
Как выяснилось, что в чистом .Net нет поддержки работы с web камерами. Перебрав несколько различных библиотек, свой выбор остановил на Aforge.net.
Aforge.net — это фреймворк для решения целого ряда задач, из которого нам понадобится библиотеки AForge.Video.
Для захвата видео с устройства видео ввода существует класс AForge.Video.DirectShow.VideoCaptureDevice
. Ему необходимо задать моникер устройства с которого будет происходить захват. Так же необходимо задать обработчик события NewFrame
. Это событие возникает каждый раз, когда с устройства будет получен новый кадр, который и передается в обработчик в виде объекта Bitmap
, где его уже можно обработать:
private void VideoSourceNewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs)
{
var img = (Image) eventArgs.Frame;
using (var ms=new MemoryStream())
{
img.Save(ms,ImageFormat.Jpeg);
//Сохраняем изображение в массив байт, для последующего формирования mjpeg
_bufImage = ms.ToArray();
}
}
Запуск видеозахвата осуществляется вызовом метода Start()
.
Список доступных видеокамер, установленных в системе, можно получить с помощью класса FilterInfoCollection
, передав ему, в качестве параметра, необходимую категорию устройств:
var videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
Это класс представляет из себя коллекцию элементов FilterInfo, которые содержат в себе два поля:
Таким образом, получив моникер устройства мы можем передать его в класс VideoCaptureDevice
.
MJPEG (Motion JPEG) является простейшим алгоритмом видеосжатия, поэтому свой выбор я остановил именно на нем.
Поток видео MJPEG представляет из себя последовательно идущие кадры в JPEG формате дополненные http заголовком:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Transfer-Encoding: chunked
Content-Type: multipart/x-mixed-replace; boundary=--myboundary
Expires: -1
--myboundary
Content-Type: image/jpeg
Content-Length:96719
.....image.......
--myboundary
Content-Type: image/jpeg
Content-Length:96720
.....next image.......
Пример реализации:
public ActionResult Video()
{
Response.Clear();
//Устанавливает тип передаваемых данных и разделитель кадров
Response.ContentType = "multipart/x-mixed-replace; boundary=--myboundary";
//Отключаем кеширование
Response.Expires = 0;
Response.Cache.SetCacheability(HttpCacheability.NoCache);
var ae = new ASCIIEncoding();
//Передаем поток пока клиент не отключится
while (Response.IsClientConnected)
{
try
{
//_bufImage - переменная, в которой хранится новый кадр в формате jpeg
var buf = _bufImage;
//Формируем заголовок разделителя
var boundary = ae.GetBytes("rn--myboundaryrnContent-Type: image/jpegrnContent-Length:"
+ buf.Length + "rnrn");
Response.OutputStream.Write(boundary, 0, boundary.Length);
Response.OutputStream.Write(buf, 0, buf.Length);
Response.Flush();
//Усыпляем поток, для поддержки частоты кадров 20 кадров/с
Thread.Sleep(50);
}
catch (Exception)
{
}
}
Response.End();
return null;
}
Aforge.net [1]
MJPEG [2]
Ссылка на исходник [3]
Автор: vassav
Источник [4]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/net/32917
Ссылки в тексте:
[1] Aforge.net: http://www.aforgenet.com/
[2] MJPEG: http://ru.wikipedia.org/wiki/MJPEG
[3] Ссылка на исходник: https://doc-08-3c-docs.googleusercontent.com/docs/securesc/ha0ro937gcuc7l7deffksulhg5h7mbp1/j33bp12cb1e7d6t12t0e4f3k0nfkf3ru/1366747200000/06261314304369696350/*/0B88gxMJybTlxV1k5eXQ4ZU5yZXc?e=download
[4] Источник: http://habrahabr.ru/post/177793/
Нажмите здесь для печати.