Birçok tarayıcı artık kullanıcıdan gelen video ve ses girişine erişebiliyor. Ancak tarayıcıya bağlı olarak bu deneyim tamamen dinamik ve satır içi olabilir veya kullanıcının cihazındaki başka bir uygulamaya devredilebilir.
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 ses dosyalarını kabul edebileceğimizi belirten bir accept
filtresi ve doğrudan mikrofondan almak istediğimizi belirten bir capture
özelliği ekleyin.
<input type="file" accept="audio/*" capture />
Bu yöntem tüm platformlarda kullanılabilir. Masaüstünde, kullanıcıdan dosya sisteminden dosya yüklemesi istenir (capture
özelliği yoksayılır). iOS'teki Safari'de mikrofon uygulaması açılır ve ses kaydedip web sayfasına geri gönderebilirsiniz. Android'de ise kullanıcıya, sesi kaydedip web sayfasına geri göndermeden önce hangi uygulamayı kullanacağını seçme seçeneği sunulur.
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="audio/*" capture id="recorder" />
<audio id="player" controls></audio>
<script>
const recorder = document.getElementById('recorder');
const player = document.getElementById('player');
recorder.addEventListener('change', function (e) {
const file = e.target.files[0];
const url = URL.createObjectURL(file);
// Do something with the audio file.
player.src = url;
});
</script>
</audio>
Dosyaya eriştikten sonra istediğiniz işlemi yapabilirsiniz. Örneğin, şunları yapabilirsiniz:
- Oynayabilmek için doğrudan bir
<audio>
öğesine ekleyin. - Kullanıcının cihazına indirin
XMLHttpRequest
dosyasına ekleyerek bir sunucuya yükleyin.- Web Audio API'den geçirip filtreler uygulayın
Ses verilerine erişmek için giriş öğesi yöntemini kullanmak yaygın olsa da bu yöntem en az ilgi çekici seçenektir. Mikrofona erişmek ve doğrudan sayfada güzel bir deneyim sunmak istiyoruz.
Mikrofonu etkileşimli olarak kullanma
Modern tarayıcılar, mikrofonla doğrudan bağlantı kurabilir. Bu sayede, web sayfasıyla tamamen entegre olan ve kullanıcının tarayıcıdan hiç ayrılmadığı deneyimler oluşturabiliriz.
Mikrofona erişim elde etme
WebRTC spesifikasyonundaki getUserMedia()
adlı bir API'yi kullanarak mikrofona doğrudan erişebiliriz. getUserMedia()
, kullanıcıdan bağlı mikrofonlara ve kameralara erişim izni ister.
API başarılı olursa kameradan veya mikrofondan gelen verileri içeren bir Stream
döndürür. Ardından bu Stream
öğesini bir <audio>
öğesine, WebRTC akışına, Web Audio AudioContext
öğesine ekleyebilir veya MediaRecorder
API'yi kullanarak kaydedebiliriz.
Mikrofondan veri almak için getUserMedia()
API'ye iletilen constraints nesnesinde audio: true
değerini ayarlamamız yeterlidir.
<audio id="player" controls></audio>
<script>
const player = document.getElementById('player');
const handleSuccess = function (stream) {
if (window.URL) {
player.srcObject = stream;
} else {
player.src = stream;
}
};
navigator.mediaDevices
.getUserMedia({audio: true, video: false})
.then(handleSuccess);
</script>
Belirli bir mikrofonu seçmek istiyorsanız önce mevcut mikrofonları listeleyebilirsiniz.
navigator.mediaDevices.enumerateDevices().then((devices) => {
devices = devices.filter((d) => d.kind === 'audioinput');
});
Ardından, getUserMedia
'u aradığınızda kullanmak istediğiniz deviceId
'yi iletebilirsiniz.
navigator.mediaDevices.getUserMedia({
audio: {
deviceId: devices[0].deviceId,
},
});
Bu bilgi tek başına çok faydalı değildir. Tek yapabileceğimiz, ses verilerini alıp tekrar oynatmaktır.
Mikrofondaki ham verilere erişim
Mikrofondan alınan ham verilere erişmek için getUserMedia()
tarafından oluşturulan akışı almamız ve ardından verileri işlemek için Web Audio API'yi kullanmamız gerekir. Web Audio API, giriş kaynaklarını alıp bu kaynakları ses verilerini işleyebilecek (ör. kazancı ayarlayabilecek) düğümlere ve nihayetinde kullanıcının duyabilmesi için bir hoparlöre bağlayan basit bir API'dir.
Bağlanabileceğiniz düğümlerden biri AudioWorkletNode
'tır. Bu düğüm, özel ses işleme için düşük düzeyde bir özellik sunar. Gerçek ses işleme, AudioWorkletProcessor
içindeki process()
geri çağırma yönteminde gerçekleşir.
Giriş ve parametreleri beslemek ve çıkışları almak için bu işlevi çağırın.
Daha fazla bilgi edinmek için Ses İşleyicisi'ni kullanma başlıklı makaleyi inceleyin.
<script>
const handleSuccess = async function(stream) {
const context = new AudioContext();
const source = context.createMediaStreamSource(stream);
await context.audioWorklet.addModule("processor.js");
const worklet = new AudioWorkletNode(context, "worklet-processor");
source.connect(worklet);
worklet.connect(context.destination);
};
navigator.mediaDevices.getUserMedia({ audio: true, video: false })
.then(handleSuccess);
</script>
// processor.js
class WorkletProcessor extends AudioWorkletProcessor {
process(inputs, outputs, parameters) {
// Do something with the data, e.g. convert it to WAV
console.log(inputs);
return true;
}
}
registerProcessor("worklet-processor", WorkletProcessor);
Arabelleklerde tutulan veriler, mikrofondan gelen ham verilerdir ve bu verilerle yapabileceğiniz çeşitli işlemler vardır:
- Doğrudan sunucuya yükleyin
- Yerel olarak depolama
- WAV gibi özel bir dosya biçimine dönüştürün ve ardından sunucularınıza veya yerel olarak kaydedin
Mikrofondan gelen verileri kaydetme
Mikrofondan gelen 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>
const downloadLink = document.getElementById('download');
const stopButton = document.getElementById('stop');
const handleSuccess = function(stream) {
const options = {mimeType: 'audio/webm'};
const recordedChunks = [];
const mediaRecorder = new MediaRecorder(stream, options);
mediaRecorder.addEventListener('dataavailable', function(e) {
if (e.data.size > 0) recordedChunks.push(e.data);
});
mediaRecorder.addEventListener('stop', function() {
downloadLink.href = URL.createObjectURL(new Blob(recordedChunks));
downloadLink.download = 'acetest.wav';
});
stopButton.addEventListener('click', function() {
mediaRecorder.stop();
});
mediaRecorder.start();
};
navigator.mediaDevices.getUserMedia({ audio: true, video: false })
.then(handleSuccess);
</script>
Bizim durumumuzda, verileri doğrudan bir diziye kaydediyoruz. Bu diziyi daha sonra Blob
olarak dönüştürebiliriz. Blob
, verileri web sunucumuza veya doğrudan kullanıcının cihazındaki depolama alanına kaydetmek için kullanılabilir.
Mikrofonu sorumlu bir şekilde kullanmak için izin isteme
Kullanıcı daha önce sitenize mikrofon erişimi vermemişse getUserMedia
işlevini çağırdığınız anda tarayıcı, kullanıcıdan sitenize mikrofon erişimi vermesini ister.
Kullanıcılar, makinelerindeki güçlü cihazlara erişim isteğinde bulunulmasından nefret eder ve isteği sık sık engeller ya da istemin oluşturulduğu bağlamı anlamazlarsa yoksayar. Mikrofon erişimi için yalnızca ilk kez ihtiyaç duyulduğunda izin istemek en iyi uygulamadır. Kullanıcı erişim izni verdikten sonra bu istek tekrar gösterilmez. Ancak erişim iznini reddederse kullanıcıdan tekrar izin isteğinde bulunamazsınız.
Erişiminiz olup olmadığını kontrol etmek için izinler API'sini kullanın
getUserMedia
API, mikrofon erişiminiz olup olmadığı hakkında bilgi sağlamaz. Bu durum size bir sorun teşkil eder. Kullanıcının mikrofona 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 mikrofonuna erişiminizin olup olmadığını sorgulamak için sorgu yöntemine {name: 'microphone'}
değerini iletebilirsiniz. Bu yöntem aşağıdakilerden birini döndürür:
granted
: Kullanıcı daha önce size mikrofona erişim izni verdiyse;prompt
: Kullanıcı size erişim izni vermemişsegetUserMedia
'i aradığınızda izin istenir.denied
: Sistem veya kullanıcı mikrofon erişimini açıkça engellemiştir ve mikrofonu kullanamazsınız.
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: 'microphone'}).then(function (result) {
if (result.state == 'granted') {
} else if (result.state == 'prompt') {
} else if (result.state == 'denied') {
}
result.onchange = function () {};
});