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 şekilde başlayı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. Bu uygulama, videoyu kaydetmenizi ve ardından videoyu web sayfasına geri göndermenizi sağlar. Android'de ise kullanıcıya, videoyu web sayfasına geri göndermeden önce hangi uygulamada kaydedileceğini seçme hakkı verilir.
Birçok mobil cihazın birden fazla kamerası vardır. Tercihiniz varsa kameranın kullanıcıya dönük olmasını istiyorsanız capture
özelliğini user
, kameranın dışa 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ı kayıt işlemini tamamlayıp web sitesine geri döndüğünde, dosya verilerini bir şekilde almanız gerekir. Giriş öğesine bir onchange
etkinliği ekleyip ardından etkinlik nesnesinin files
özelliğini okuyarak hızlı erişim elde edebilirsiniz.
<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şlemi 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 spesifikasyonunda getUserMedia()
adlı bir API 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ı numaralandırabilirsiniz.
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.
Ham verilere kameradan erişin
Kameradan gelen ham video verilerine erişmek için her kareyi bir <canvas>
içine çizebilir ve pikselleri doğrudan değiştirebilirsiniz.
2D kanvaslarda bir <video>
öğesinin geçerli karesini zemine çizmek için 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 tuvale 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>
Örneğimizde verileri doğrudan bir diziye kaydediyoruz. Daha sonra bu diziyi Blob
biçimine dönüştürüyoruz. Daha sonra bu diziyi Web Sunucumuza veya doğrudan kullanıcının cihazındaki depolama alanına kaydedebiliriz.
Kamerayı sorumlu bir şekilde kullanmak için izin isteme
Kullanıcı daha önce sitenizin kameraya erişmesine izin vermediyse getUserMedia
hizmetini çağırdığınız anda tarayıcı kullanıcıdan sitenizin kameraya erişmesine izin 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ığı konusunda size bilgi vermez. Bu durum size bir sorun teşkil eder. Kullanıcının 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şiminiz olup olmadığını sorgulamak için sorgu yöntemine {name: 'camera'}
öğesini iletebilirsiniz. İşlem, aşağıdakilerden birini döndürür:
granted
— Kullanıcı daha önce size kamera için erişim izni verdiyse;prompt
— kullanıcı size erişim izni vermedi vegetUserMedia
numarasını aradığınızda bu kişiden istenecek;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 () {};
});