Предисловие
Не так давно, возникла необходимость захвата видео с 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, которые содержат в себе два поля:
- Name — название устройства
- MonikerString — моникер устройства.
Таким образом, получив моникер устройства мы можем передать его в класс VideoCaptureDevice
.
Формирование видео-потока MJPEG
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("\r\n--myboundary\r\nContent-Type: image/jpeg\r\nContent-Length:" + buf.Length + "\r\n\r\n"); 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; }
ссылка на оригинал статьи http://habrahabr.ru/post/177793/
Добавить комментарий