Web APIs Cheatsheet
Media Devices
Use this Web APIs reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
getUserMedia — Camera and Microphone
// Basic camera + mic const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true, }); video.srcObject = stream; await video.play(); // Advanced constraints const stream = await navigator.mediaDevices.getUserMedia({ video: { width: { ideal: 1280, max: 1920 }, height: { ideal: 720, max: 1080 }, facingMode: 'user', // 'user' | 'environment' (front/back cam) frameRate: { ideal: 30, max: 60 }, deviceId: { exact: selectedDeviceId }, }, audio: { sampleRate: 48000, channelCount: 1, echoCancellation: true, noiseSuppression: true, autoGainControl: true, deviceId: micDeviceId, }, });
Stopping the Stream
// Stop all tracks stream.getTracks().forEach(track => track.stop()); // Stop specific track stream.getVideoTracks().forEach(t => t.stop()); stream.getAudioTracks().forEach(t => t.stop());
MediaStream and MediaStreamTrack
stream.id; // unique string stream.active; // true if any track is live stream.getTracks(); // MediaStreamTrack[] stream.getVideoTracks(); stream.getAudioTracks(); stream.getTrackById(id); stream.addTrack(track); stream.removeTrack(track); stream.clone(); // shallow clone (tracks shared) // Events stream.addEventListener('addtrack', e => e.track); stream.addEventListener('removetrack', e => e.track);
const track = stream.getVideoTracks()[0]; track.kind; // 'video' | 'audio' track.label; // device label (e.g. 'FaceTime HD Camera') track.id; track.enabled; // false = mute/pause (stream still flows, just black/silent) track.muted; // true when track source is muted by hardware/OS track.readyState; // 'live' | 'ended' track.stop(); // end the track track.clone(); // Apply constraints on live track await track.applyConstraints({ width: 640, height: 480 }); track.getConstraints(); // last applied constraints track.getCapabilities(); // browser support ranges track.getSettings(); // current actual values // Events track.addEventListener('mute', () => {}); track.addEventListener('unmute', () => {}); track.addEventListener('ended', () => {});
getDisplayMedia — Screen Sharing
const stream = await navigator.mediaDevices.getDisplayMedia({ video: { displaySurface: 'monitor', // 'monitor' | 'window' | 'browser' frameRate: { max: 30 }, width: { ideal: 1920 }, }, audio: true, // system audio (where supported) selfBrowserSurface: 'exclude', systemAudio: 'include', monitorTypeSurfaces: 'include', }); // Screen share ended by user stream.getVideoTracks()[0].addEventListener('ended', stopSharing);
enumerateDevices — List Devices
const devices = await navigator.mediaDevices.enumerateDevices(); // Returns MediaDeviceInfo[] for (const d of devices) { d.kind; // 'audioinput' | 'audiooutput' | 'videoinput' d.label; // empty string until permission granted d.deviceId; // unique id (changes if cookies cleared) d.groupId; // same for physically connected devices } const cameras = devices.filter(d => d.kind === 'videoinput'); const mics = devices.filter(d => d.kind === 'audioinput'); const speakers = devices.filter(d => d.kind === 'audiooutput'); // Device change navigator.mediaDevices.addEventListener('devicechange', async () => { const updated = await navigator.mediaDevices.enumerateDevices(); });
Capture Photo from Camera
const canvas = document.createElement('canvas'); canvas.width = video.videoWidth; canvas.height = video.videoHeight; canvas.getContext('2d').drawImage(video, 0, 0); const blob = await new Promise(res => canvas.toBlob(res, 'image/jpeg', 0.9));
ImageCapture API
const track = stream.getVideoTracks()[0]; const capture = new ImageCapture(track); const blob = await capture.takePhoto({ fillLightMode: 'flash' }); const frame = await capture.grabFrame(); // ImageBitmap of current frame const capabilities = await capture.getPhotoCapabilities(); // capabilities.fillLightMode, .imageWidth, .imageHeight, .redEyeReduction, … await capture.setOptions({ zoom: 2, torch: true });
MediaRecorder — Record Audio / Video
const recorder = new MediaRecorder(stream, { mimeType: 'video/webm;codecs=vp9,opus', // check with MediaRecorder.isTypeSupported() audioBitsPerSecond: 128000, videoBitsPerSecond: 2500000, bitsPerSecond: 2628000, // overrides the two above }); const chunks = []; recorder.addEventListener('dataavailable', e => { if (e.data.size > 0) chunks.push(e.data); }); recorder.addEventListener('stop', () => { const blob = new Blob(chunks, { type: recorder.mimeType }); const url = URL.createObjectURL(blob); videoEl.src = url; }); recorder.start(); // start without slicing recorder.start(1000); // fire 'dataavailable' every 1000 ms recorder.pause(); recorder.resume(); recorder.stop(); // fires 'dataavailable' + 'stop' recorder.requestData(); // force 'dataavailable' immediately recorder.state; // 'inactive' | 'recording' | 'paused' recorder.mimeType; recorder.stream; recorder.addEventListener('start', e => {}); recorder.addEventListener('pause', e => {}); recorder.addEventListener('resume', e => {}); recorder.addEventListener('stop', e => {}); recorder.addEventListener('error', e => e.error); // Check support MediaRecorder.isTypeSupported('video/mp4'); MediaRecorder.isTypeSupported('video/webm;codecs=vp9');
Web Audio API
const ctx = new AudioContext({ latencyHint: 'interactive', sampleRate: 48000 }); ctx.state; // 'suspended' | 'running' | 'closed' await ctx.resume(); // must be called in user gesture context await ctx.suspend(); await ctx.close(); ctx.currentTime; // high-precision timestamp in seconds ctx.sampleRate; // samples per second ctx.destination; // AudioDestinationNode (speakers) ctx.listener; // AudioListener (for 3D audio)
Common Audio Nodes
// OscillatorNode — generates a tone const osc = ctx.createOscillator(); osc.type = 'sine'; // 'sine' | 'square' | 'sawtooth' | 'triangle' | 'custom' osc.frequency.value = 440; osc.start(); osc.stop(ctx.currentTime + 1); // GainNode — volume control const gain = ctx.createGain(); gain.gain.value = 0.5; // BiquadFilterNode const filter = ctx.createBiquadFilter(); filter.type = 'lowpass'; filter.frequency.value = 800; // AnalyserNode — visualizations const analyser = ctx.createAnalyser(); analyser.fftSize = 2048; const buffer = new Uint8Array(analyser.frequencyBinCount); analyser.getByteFrequencyData(buffer); analyser.getByteTimeDomainData(buffer); // waveform // Connect graph: source → gain → analyser → destination osc.connect(gain).connect(analyser).connect(ctx.destination); // MediaStreamSource — from getUserMedia const source = ctx.createMediaStreamSource(stream); source.connect(analyser).connect(ctx.destination); // MediaElementSource — from <audio>/<video> const elSource = ctx.createMediaElementSource(audioEl); elSource.connect(gain).connect(ctx.destination); // Buffer (preloaded sound) const res = await fetch('/sound.mp3'); const rawBuffer = await res.arrayBuffer(); const audioBuffer = await ctx.decodeAudioData(rawBuffer); const player = ctx.createBufferSource(); player.buffer = audioBuffer; player.loop = true; player.connect(ctx.destination); player.start(0); // start now player.start(ctx.currentTime + 2, 0.5, 2); // start in 2 s, offset 0.5 s, duration 2 s player.stop();
AudioParam Scheduling
gain.gain.setValueAtTime(0, ctx.currentTime); gain.gain.linearRampToValueAtTime(1, ctx.currentTime + 0.5); gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 2); gain.gain.setTargetAtTime(0, ctx.currentTime, 0.3); // time constant gain.gain.setValueCurveAtTime([0, 0.5, 1, 0.5, 0], ctx.currentTime, 2); gain.gain.cancelScheduledValues(ctx.currentTime); gain.gain.cancelAndHoldAtTime(ctx.currentTime);
HTMLMediaElement (audio / video)
const video = document.querySelector('video'); // Playback video.play(); // Returns Promise video.pause(); video.load(); // reload source video.currentTime = 30; // seek to 30 s video.playbackRate = 1.5; video.defaultPlaybackRate = 1; video.volume = 0.8; // 0–1 video.muted = true; video.loop = true; // Properties video.duration; // total seconds (NaN before metadata) video.currentTime; video.paused; // boolean video.ended; video.seeking; video.readyState; // 0=HAVE_NOTHING … 4=HAVE_ENOUGH_DATA video.networkState; // 0=EMPTY, 1=IDLE, 2=LOADING, 3=NO_SOURCE video.buffered; // TimeRanges video.played; // TimeRanges video.seekable; // TimeRanges video.videoWidth; video.videoHeight; // intrinsic dimensions // Source video.src = '/video.mp4'; video.currentSrc; // active source video.canPlayType('video/mp4'); // '' | 'maybe' | 'probably' // Tracks video.textTracks; // TextTrackList video.audioTracks; // AudioTrackList video.videoTracks; // VideoTrackList // Fullscreen video.requestFullscreen({ navigationUI: 'hide' }); // Picture-in-Picture await video.requestPictureInPicture(); await document.exitPictureInPicture(); document.pictureInPictureElement; document.pictureInPictureEnabled;
setSinkId — Audio Output Device
// Route audio to a specific speaker await audioEl.setSinkId(deviceId); audioEl.sinkId; // current output device id
Permissions
const cam = await navigator.permissions.query({ name: 'camera' }); const mic = await navigator.permissions.query({ name: 'microphone' }); const screen = await navigator.permissions.query({ name: 'display-capture' }); cam.state; // 'granted' | 'denied' | 'prompt' cam.addEventListener('change', () => console.log(cam.state));