Birçok tarayıcı artık kullanıcıdan gelen video ve ses girişine erişebiliyor. Ancak tarayıcıya bağlı olarak tam dinamik ve satır içi bir deneyim olabilir veya kullanıcının cihazındaki başka bir uygulamaya yetkilendirilebilir.
Basit ve kademeli bir başlangıç yapın
En kolay yöntem, kullanıcıdan önceden kaydedilmiş bir dosya istemektir. Bunu yapmak için basit bir dosya girişi öğesi oluşturun ve yalnızca video dosyalarını kabul edebileceğimizi belirten bir accept
filtresi ve dosyayı doğrudan kameradan almak istediğimizi belirten bir capture
özelliği ekleyin.
<input type="file" accept="video/*" capture />
Bu yöntem tüm platformlarda kullanılabilir. Masaüstünde, kullanıcıdan dosya sisteminden bir dosya yüklemesi istenir (capture
özelliği yoksayılır). iOS'teki Safari'de kamera uygulaması açılır ve video kaydedip web sayfasına geri gönderebilirsiniz. Android'de ise kullanıcıya, videoyu kaydedip web sayfasına geri göndermeden önce hangi uygulamayı kullanacağını seçme seçeneği sunulur.
Birçok mobil cihazda birden fazla kamera bulunur. Bir tercihiniz varsa kameranın kullanıcıya dönük olmasını istiyorsanız capture
özelliğini user
, kameranın dışarıya dönük olmasını istiyorsanız environment
olarak ayarlayabilirsiniz.
<input type="file" accept="video/*" capture="user" />
<input type="file" accept="video/*" capture="environment" />
Bunun yalnızca bir ipucu olduğunu unutmayın. Tarayıcı bu seçeneği desteklemiyorsa veya istediğiniz kamera türü kullanılamıyorsa tarayıcı başka bir kamera seçebilir.
Kullanıcı kaydı tamamlayıp web sitesine geri döndüğünde, dosya verilerini bir şekilde almanız gerekir. Giriş öğesine bir onchange
etkinliği ekleyerek ve ardından etkinlik nesnesinin files
mülkünü okuyarak hızlıca erişebilirsiniz.
<input type="file" accept="video/*" capture="camera" id="recorder" />
<video id="player" controls></video>
<script>
var recorder = document.getElementById('recorder');
var player = document.getElementById('player');
recorder.addEventListener('change', function (e) {
var file = e.target.files[0];
// Do something with the video file.
player.src = URL.createObjectURL(file);
});
</script>
Dosyaya eriştikten sonra istediğiniz işlemleri yapabilirsiniz. Örneğin, şunları yapabilirsiniz:
- Oynayabilmek için doğrudan bir
<video>
öğesine ekleyin. - Kullanıcının cihazına indirin
XMLHttpRequest
dosyasına ekleyerek bir sunucuya yükleyin.- Çerçeveleri bir kanvas üzerine çizip filtre uygulayın
Video verilerine erişmek için giriş öğesi yöntemini kullanmak yaygın olsa da bu yöntem en az ilgi çekici seçenektir. Kameraya erişmek ve doğrudan sayfada güzel bir deneyim sunmak istiyoruz.
Kameraya etkileşimli olarak erişme
Modern tarayıcılar, kameraya doğrudan bağlanabilir. Bu sayede, web sayfasıyla tamamen entegre olan ve kullanıcının tarayıcıdan hiç ayrılmadığı deneyimler oluşturabiliriz.
Kameraya erişim elde etme
WebRTC spesifikasyonundaki getUserMedia()
adlı bir API'yi kullanarak kameraya doğrudan erişebiliriz. getUserMedia()
, kullanıcıdan bağlı mikrofonlara ve kameralara erişim izni ister.
İşlem başarılı olursa API, kameradan veya mikrofondan gelen verileri içeren bir Stream
döndürür. Ardından bu Stream
öğesini bir <video>
öğesine, WebRTC akışına ekleyebilir veya MediaRecorder
API'yi kullanarak kaydedebiliriz.
Kameradan veri almak için getUserMedia()
API'ye iletilen constraints nesnesinde video: true
değerini ayarlamamız yeterlidir.
<video id="player" controls></video>
<script>
var player = document.getElementById('player');
var handleSuccess = function (stream) {
player.srcObject = stream;
};
navigator.mediaDevices
.getUserMedia({audio: true, video: true})
.then(handleSuccess);
</script>
Belirli bir kamerayı seçmek istiyorsanız önce mevcut kameraları sayabilirsiniz.
navigator.mediaDevices.enumerateDevices().then((devices) => {
devices = devices.filter((d) => d.kind === 'videoinput');
});
Ardından getUserMedia
numaralı telefonu aradığınızda kullanmak istediğiniz deviceId değerini iletebilirsiniz.
navigator.mediaDevices.getUserMedia({
audio: true,
video: {
deviceId: devices[0].deviceId,
},
});
Bu bilgi tek başına çok faydalı değildir. Tek yapabileceğimiz, video verilerini alıp oynatmaktır.
Kameradan ham verilere erişme
Kameradan gelen ham video verilerine erişmek için her kareyi bir <canvas>
içine çizebilir ve pikselleri doğrudan değiştirebilirsiniz.
2D bir tuval için <video>
öğesinin mevcut çerçevesini tuvale çizmek üzere bağlamın drawImage
yöntemini kullanabilirsiniz.
context.drawImage(myVideoElement, 0, 0);
WebGL kanvaslarında, doku kaynağı olarak <video>
öğesini kullanabilirsiniz.
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.RGBA,
gl.RGBA,
gl.UNSIGNED_BYTE,
myVideoElement,
);
Her iki durumda da oynatılan videonun mevcut karesinin kullanılacağını unutmayın. Birden fazla kareyi işlemek için videoyu her seferinde kanvas üzerinde yeniden çizmeniz gerekir.
Bu konu hakkında daha fazla bilgiyi resimlere ve videolara gerçek zamanlı efekt uygulama konulu makalemizde bulabilirsiniz.
Kameradaki verileri kaydetme
Kameradaki verileri kaydetmenin en kolay yolu MediaRecorder
API'yi kullanmaktır.
MediaRecorder
API, getUserMedia
tarafından oluşturulan akışı alır ve ardından akıştaki verileri tercih ettiğiniz hedefe kademeli olarak kaydeder.
<a id="download">Download</a>
<button id="stop">Stop</button>
<script>
let shouldStop = false;
let stopped = false;
const downloadLink = document.getElementById('download');
const stopButton = document.getElementById('stop');
stopButton.addEventListener('click', function() {
shouldStop = true;
})
var handleSuccess = function(stream) {
const options = {mimeType: 'video/webm'};
const recordedChunks = [];
const mediaRecorder = new MediaRecorder(stream, options);
mediaRecorder.addEventListener('dataavailable', function(e) {
if (e.data.size > 0) {
recordedChunks.push(e.data);
}
if(shouldStop === true && stopped === false) {
mediaRecorder.stop();
stopped = true;
}
});
mediaRecorder.addEventListener('stop', function() {
downloadLink.href = URL.createObjectURL(new Blob(recordedChunks));
downloadLink.download = 'acetest.webm';
});
mediaRecorder.start();
};
navigator.mediaDevices.getUserMedia({ audio: true, video: true })
.then(handleSuccess);
</script>
Bizim durumumuzda verileri doğrudan bir diziye kaydediyoruz. Bu diziyi daha sonra Blob
olarak dönüştürebiliriz. Blob
, web sunucumuza veya doğrudan kullanıcının cihazındaki depolama alanına veri kaydetmek için kullanılabilir.
Kamerayı sorumlu bir şekilde kullanmak için izin isteme
Kullanıcı daha önce sitenize kamera erişimi vermemişse getUserMedia
çağrısını yaptığınız anda tarayıcı, kullanıcıdan sitenize kamera erişimi vermesini ister.
Kullanıcılar, makinelerindeki güçlü cihazlara erişim isteminden nefret eder ve isteği sık sık engeller ya da istemin oluşturulduğu bağlamı anlamazlarsa yoksayar. Kameraya erişimi yalnızca ilk kez ihtiyaç duyulduğunda istemek en iyi uygulamadır. Kullanıcı erişim izni verdikten sonra bu istek tekrar gösterilmez. Ancak kullanıcı erişim iznini reddederse kullanıcıdan izin istemek için tekrar erişim izni alamazsınız.
Erişiminiz olup olmadığını kontrol etmek için izinler API'sini kullanın
getUserMedia
API, kameraya erişiminiz olup olmadığı hakkında bilgi sağlamaz. Bu durum size bir sorun çıkarır. Kullanıcının size kameraya erişim izni vermesini sağlamak için güzel bir kullanıcı arayüzü sunmanız gerekir.
Bu sorun, bazı tarayıcılarda Permission API kullanılarak çözülebilir. navigator.permission
API, belirli API'lere erişme yeteneğiyle ilgili durumu tekrar istemek zorunda kalmadan sorgulamanıza olanak tanır.
Kullanıcının kamerasına erişiminizin olup olmadığını sorgulamak için sorgu yöntemine {name: 'camera'}
parametresini iletebilirsiniz. Bu parametre şu değerleri döndürür:
granted
: Kullanıcı daha önce size kameraya erişim izni verdiyse;prompt
: Kullanıcı size erişim izni vermemişsegetUserMedia
'i aradığınızda izin istenir.denied
: Sistem veya kullanıcı kameraya erişimi açıkça engellemiştir ve kameraya erişemezsiniz.
Artık kullanıcı arayüzünüzü, kullanıcının yapması gereken işlemlere uygun olacak şekilde değiştirmeniz gerekip gerekmediğini hızlıca kontrol edebilirsiniz.
navigator.permissions.query({name: 'camera'}).then(function (result) {
if (result.state == 'granted') {
} else if (result.state == 'prompt') {
} else if (result.state == 'denied') {
}
result.onchange = function () {};
});