Захват изображения с камеры в браузере с помощью getUserMedia (с зеркальным отображением)
Друзья! Близятся те времена, когда почти все, для чего нужен был флеш в браузере, можно будет делать и без него. Не знаю как у вас, а у меня это вызывает кучу положительных эмоций. Одним из шагов на пути вытеснения flash становится реализация в браузерах getUserMedia (Stream) javascript API. На данный момент Stream API для видеопотока реализовано в последних десктопных версиях Chrome и Opera. Firefox на подходе. Аудиопоток “coming soon”. Даже не знаю, ждать ли чего-то от IE .. по идее, он скорее умрет (..а он умрет), чем начнет догонять всех остальных.
Подробнее о поддержке в браузерах можно посмотреть тут – /caniuse.com/stream
Давайте взглянем на пример, а потом посмотрим, как это работает:
Давайте разберемся, как это работает.
Для начала нам понадобятся такие элементы, как:
- video , в котором мы будем воспроизводить поточное видео с камеры пользователя
- canvas , в который мы будем помещать кадры для сохранения
- кнопка для захвата изображения
- подсказка для юзера, который не понял, что вообще от него хотят.
Далее нам нужно спросить у пользователя разрешения использовать его видеопоток.
Как видно, в случае удачи в callback вернется объект stream, на основе которого можно получить url видеопотока. Сделать это можно с помощью window.URL.createObjectURL(stream) , которая может быть вам знакома, если вы когда-либо использовали js file API.
- передаем этот url объекту video
- при нажатии на кнопку захватываем текущий кадр video в canvas
- забираем data:url получившегося изображения из canvas
- и все, готово! Можно делать с ним все, что угодно: отправить на сервер, отфильтровать, передать другу через сокет и тп. Подробнее про base64 и data:url формат можно почитать тут.
Давайте рассмотрим код примера в начале статьи для наглядности
Конечно, лучше и красивее создать все элементы (canvas, video, ..) динамически, но для наглядности и понимания давайте изначально расположим их статически на странице:
Зеркальное отображение при съемке
В примере выше мы делали захват изображений с зеркальным отображением по горизонтали. Зачем, спросите вы. Иногда можно встретить такие задачи. Это особенно актуально, когда вам нужно точно спозиционировать свое изображение по отношению к фрейму или окружающим предметам. Например, поместить свое лицо в заданную область для сканирования, совместить с предустановленной маской и т.п. В этом случае для пользователя будет удобнее, если изображение, получаемое с камеры, отображается на мониторе зеркально (по горизонтали).
Как мы этого достигли:
Во-первых, мы сделали css transform для video
Во-вторых, повернули изображение на canvas таким же образом
Если вам не нужно зеркальное отображение, просто удалите эту часть js и css
Удачи! Жду вопросов и поправок в комментариях.
28 comments on “ Захват изображения с камеры в браузере с помощью getUserMedia (с зеркальным отображением) ”как раз вчера клиент просил такую фичу и я думал, что придется оборачивать приложение в phonegap для снабжения его большей свободой :( – А тут очень кстати твой пост! Супер!
Будьте осторожны с поддержкой браузеров, эта штука пока очень сырая :( http://caniuse.com/stream
Добрый день, подскажите как отправить base64dataUrl на сервер?
Мы сейчас на проекте обсуждаем альтернативы нативному iOS приложению, которое нам пока не удалось сделать достаточно стабильным. Т.к. есть разработчики которые делают веб-приложение, то рассматриваем альтернативы типа phonegap или appcelerator.
Но ни у кого нет опыта работы с ними. Есть понимание, что простые вещи там можно сделать, а вот запись видео/фото/аудио, отправка на сервер да так, чтобы это работало стабильно… мы не знаем.
Может есть опыт и знание этих платформ и можете подсказать, возможно ли там такое реализовать?
Так получилось, что последнее время мы делаем мини приложения для http://urturn.com у которого есть phonegap based ios app. Мы используем нативную objective C часть для захвата с камеры, а в webview (web часть) только для интерфейсов и всей пост обработки (canvas, svg, разные стикеры, эффекты и тп). Сразу хочу сказать, работать в ios uiwebview с phonegap – это кошмар. Очень много ограничений, нужно следить за памятью, дебажить очень сложно + сотни непонятных багов сходных по уровню магии с ie6. Если Вы хотите сделать приложеие с хорошим быстрым юзер-интерфейсом, обработкой видео или аудио или даже просто фото и все это для IOS.. лучше сделать его нативым (( Я думаю что apple еще долго будет искуственно тормозить развитие web-based приложений, и это связано в основном с политикой компании. Что касается android, firefoxOS, blackberryOS, TizenOS.. то через несколько лет, все перейдут (если уже не перешли) к web-based приложениям. Но это уже совсем другая история :)
ковыряюсь с программаой. на ноуте все работает, на смартфоне – нет. как разрешить на смартфоне использование камеры? у меня самсунг GT-S6810 с андроидом 4.1.2 как браузеры стоят хром и мозила 5.0 эта страничка открвается, но нету диалога(или скорее я не могу его найти) о том, что есть запрос на использование камеры. подскажите, где почитать спасибо заранее
К сожалению, ничего пока не получится. На данный момент (08.2013) ни один мобильный браузер толком не поддерживает getUserMedia API. Подробнее тут http://caniuse.com/#search=getusermedia
chrome для андроид теперь поддерживает getUserMedia (03.2014)
Немного не по теме, но близко. Нужен захват “видео” из окна браузера. Пользователь работает с корпоративным сайтом и для саппорта очень бы помогло увидеть то, что видит пользователь. Может быть подскажите в какую сторону копать и возможно ли вообще такое?
посмотрите скриншаринг с использованием webRTC (но это пока очень на ранней стадии, только в хроме с включеным флагом)http://stackoverflow.com/questions/17542384/accomplish-screen-sharing-using-webrtc
Другое решение – написать расширение для браузера. Там точно можно делать скриншоты и отправлять их куда вам надо ;)
Пробую скопировать код, всё отрабатывает, но при отправке на сервер и base64_decode получаю чёрную картинку… Что может быть не так?
перед отправкой на сервер, попробуйте вставить base64 url в img.
и посмотрите, как это выглядит, дейсвительно ли вы отправляете не черную картинку. Если все ок, ищите проблемы по пути передачи или декодирования. Конкретнее, к сожалению, ничего не посоветую.
var base64dataUrl = canvas.toDataURL(‘image/png’);
если подставлять параметры то получается ошибка https://pp.vk.me/c623927/v623927444/1eae4/Dvb4PN_cGlc.jpg просто исправте на
var base64dataUrl = canvas.toDataURL();
Замечательно! Как раз искал варианты для вызова камеры со смартфона из HTML+JS
Подскажите, пожалуйста! При сохранении переданного изображения BASE64 на сервере сохраняется неверный формат, который не отображается. Клиент:
Спасибо за статью. Тестировал Вашу программу на firefox и хроме под android – всё работает. Скажите подалуйста, как получить управление фокусировкой и другими настройками камеры?
сапасибо за статью. с видео все получилось и в мобильных браузерах работает. а как можно сделать что бы аудио записывалось. ну там, например 5с после нажатия кнопки. как мне потом этот stream в файл аудио запихнуть. может подскажите? ну или с видео: что бы не просто скриншот брался, а тоже скажем 5с видео сохранялось в файл.
Отличная штука. Осталось решить, как лучше “убить” видеозахват, когда он более не нужен на странице.
А это очень просто: Повесить обработчик на кнопку или куда-то ещё, и прописать:
Подскажите, как получить доступ к основной камере мобильного телефона? по умолчанию включается фронтальная камера
И второй вопрос, можно ли разрешить использование камеры по умолчанию, а не спрашивать каждый раз пользователя об этом?
C начала 2016 г. ваша демка перестала работать в Chrome, в Mozille работает, в чем может быть проблема?
As of Chrome 47, the getUserMedia API cannot be called from insecure origins. Открывайте ссылку по https в Chrome.
Спасибо за подробное описание. Надеюсь этой темой Вы занимаетесь и за прошедшие годы стали ассом. Чтобы смотреть себя в браузере много где теперь написано. Но никак не найду как можно между двумя и более людьми видеопоказ устроить. Типа один показывает, а несколько смотрят. На флэше с RED5 сделал, но скоро обещают что его не будет. Хочется на новом HTML5, а никак. Может поможете или направите в полезное место? Нашел только тех кто через свой сервер делает. А хочется независимо сделать на своем.