Pull to refresh

Трансляция с камеры

Пришла мне однажды идея создать трансляцию с камеры, и я решил ее реализовать. Для создания этого дела нам понадобится 4 файла (5, если считать CSS).
1. Index.php. Где будет сама трансляция.
2. Save.php. Куда будет сохраняться изображение.
3. Now.php. Где будет храниться изображения в base:64.
4. Translate.php. Откуда будет вестись трансляция.

Принцип прост: на странице translate.php пользователь открывает доступ к камере, потом делается снимок каждую секунду, потом этот снимок отправляется на страницу index.php.

Приступим. Index.php. Тут ничего сложного нет.

<!doctype html>
<head>
<meta charset="utf-8">
	<title>Просмотр</title>
	<link rel="stylesheet" href="main.css" />
	<script>
		function g (id) {
				return document.getElementById(id);
			};
			var ajax = {
				init: function (method, url, query, callback) {
					query = typeof query === "string" ? query : ajax._params(query);

					var xhr = new XMLHttpRequest();
					xhr.open(method, url);
					xhr.send(query);
					xhr.onreadystatechange = function (event) {
						if (xhr.readyState === 4)
							callback && callback(JSON.parse(xhr.responseText));
					};
				},
				get: function (url, params, callback) {
					ajax.init("GET", url + "?" + ajax._params(params), null, callback)
				},
				post: function (url, params, callback) {
					ajax.init("POST", url, params, callback);
				},
				_params: function (params) {
					if (typeof params === "string" || params == null)
						return params;
					var data = [], key, d = encodeURIComponent;
					for (key in params)
						data.push(d(key) + "=" + d(params[key]));
					return data.join("&");
				}
			};
			function setLoad () {
				ajax.get("now.php", "", function (data) { //берется изображение
					g("img").src = data.image;
				});
			};
			
			setInterval(setLoad, 50);
	</script>
</head>
<body>
	<div id="title">
		Трансляция с вебкамеры
	</div>
	 
	<div id="viewer">
		<img src="data:base64," alt="" id="img" width="640" height="480" class="img-content" /> //берется изображение и выводится 
	</div>
</body>
</html>


save.php. Предельно прост:

<?
$data = $_REQUEST["data"]; // получаем изображение
$fh = fopen("now.png", "w+"); // создаем и открываем файл с изображением 
$save = fwrite($fh, $data); // записываем данные в него
fclose($fh); // закрываем файл

exit(json_encode(["success" => !!$save, "time" => time()]));
?>


now.php. Тоже ничего сложного:

<?
exit(json_encode(["image" => file_get_contents("./now.png")], JSON_UNESCAPED_UNICODE));
?>


translate.php. Вот тут и начинаются танцы с бубном:

<!doctype html>
<head>
<meta charset="utf-8">
	<title>Трансляция</title>
	<link rel="stylesheet" href="main.css" />
	<script>
		function g (id) {
				return document.getElementById(id);
			};
			var ajax = {
				init: function (method, url, query, callback) {
					query = typeof query === "string" ? query : ajax._params(query);

					var xhr = new XMLHttpRequest();
					xhr.open(method, url);
					xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
					xhr.send(query);
					xhr.onreadystatechange = function (event) {
						if (xhr.readyState === 4)
							callback && callback(JSON.parse(xhr.responseText));
					};
				},
				get: function (url, params, callback) {
					ajax.init("GET", url + "?" + ajax._params(params), null, callback)
				},
				post: function (url, params, callback) {
					ajax.init("POST", url, params, callback);
				},
				_params: function (params) {
					if (typeof params === "string" || params == null)
						return params;
					var data = [], key, d = encodeURIComponent;
					for (key in params)
						data.push(d(key) + "=" + d(params[key]));
					return data.join("&");
				}
			};

			Number.prototype.n2 = function () {
				return this < 10 ? "0" + this : this;
			};

			Date.prototype.getString = function () {
				return [
					this.getDate(),
					".",
					(this.getMonth() + 1).n2(),
					".",
					this.getFullYear(),
					" ",
					this.getHours(),
					":",
					this.getMinutes().n2(),
					":",
					this.getSeconds().n2()
				].join("");
			};

			var Media = {
				media: navigator.getUserMedia || navigator.msGetUserMedia || navigator.mozGetUserMedia || navigator.webkitGetUserMedia,
				url: window.URL.createObjectURL || window.URL.msCreateObjectURL || window.URL.mozCreateObjectURL || window.URL.webkitCreateObjectURL,
				video: null,
				canvas: null,
				ctx: null,
				init: function (video, canvas) {
					if (!Media.media || !Media.url)
						return alert("Не поддерживается Вашим браузером!");

					Media.canvas = canvas;
					Media.ctx = canvas.getContext("2d");
					Media.video = video;

					Media.media.call(navigator, {video: true}, Media.onSuccess, Media.onError);
				},
				onSuccess: function (stream) {
					var stream = Media.url(stream);
					Media.video.src = stream;
					Media.video.play();
					setTimeout(function () {
						Media.save(Media.getImage());
					}, 4000);
				},
				getImage: function () {
					Media.canvas.width = Media.canvas.width;
					Media.ctx.drawImage(Media.video, 0, 0, Media.canvas.width, Media.canvas.height);
					Media.ctx.font = "22px Tahoma";
					var date = new Date().getString();

					Media.ctx.fillStyle = "white";
					Media.ctx.fillText(date, 9, Media.canvas.height - 16);

					Media.ctx.fillStyle = "black";
					Media.ctx.fillText(date, 10, Media.canvas.height - 15);

					return Media.canvas.toDataURL("image/jpeg", .9);
				},
				save: function (data) {
					ajax.post("save.php", {
						data: data
					}, function (data) {
						Media.save(Media.getImage());
						if (data.success)
							g("time").innerHTML = "Время: " + (new Date(data.time * 1000).toLocaleString());
					});
				},
				onError: function(error) {
					alert("Видеокамера недоступна");
				}
			};
			window.onload = function (event) {
				Media.init(g("video"), g("canvas"));
			};
	</script>
</head>
<body>
	<div class="wrap">
			<div class="side fl">
				<h2>Веб-камера</h2>
				<div class="img-wrapper"><video id="video"></video></div>
			</div>
			<div class="side fr">
				<h2>Кадр на сайте</h2>
				<div class="img-wrapper"><canvas id="canvas" width="480" height="360"></canvas></div>
				<p id="time"></p>
			</div>
		</div>
</body>


На этом серверная часть готова. Можно теперь добавить чуть-чуть CSS.
			body{
				background-color: beige;
				font-family: ubuntu;
			}
			
/* Шрифт измените на свой, если он у вас есть */

			@font-face {
				font-family: Ubuntu;
				src: url("../Ubuntu.ttf") format("opentype");
			}

			#title{
				text-align: center;
				font-size: 30px;
			}
			
			#viewer{
				text-align: center;
				margin-top: 3%;
			}
			
			#viewer img{
				box-shadow: 0 0 50px rgba(0,0,0,5);
			}


Ну, вроде бы все. Теперь вы можете делать трансляцию с веб-камеры на сайт.

Исходники.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.