A shim to insulate apps from WebRTC spec changes and browser prefix differences
Overall
score
98%
Safari-specific shims handle compatibility issues and behavioral differences in Safari browsers to ensure consistent WebRTC behavior across desktop and mobile Safari platforms.
Provides consistent local streams API for Safari browsers.
/**
* Shims local streams API for Safari browsers
* Ensures proper local stream handling and events
* @param window - Browser window object
*/
function shimLocalStreamsAPI(window: Window): void;What it fixes:
Provides consistent remote streams API for Safari browsers.
/**
* Shims remote streams API for Safari browsers
* Ensures proper remote stream handling and events
* @param window - Browser window object
*/
function shimRemoteStreamsAPI(window: Window): void;What it fixes:
Usage Examples:
import adapter from 'webrtc-adapter';
const pc = new RTCPeerConnection();
// Remote stream handling (automatically shimmed)
pc.ontrack = (event) => {
console.log('Received remote track:', event.track.kind);
// Streams array is properly populated in Safari
if (event.streams && event.streams.length > 0) {
const remoteStream = event.streams[0];
videoElement.srcObject = remoteStream;
}
};Provides callback-based API compatibility for legacy Safari WebRTC implementations.
/**
* Shims callbacks API for Safari browsers
* Provides legacy callback compatibility for older Safari versions
* @param window - Browser window object
*/
function shimCallbacksAPI(window: Window): void;What it fixes:
Usage Examples:
import adapter from 'webrtc-adapter';
const pc = new RTCPeerConnection();
// Legacy callback style (automatically shimmed to work in Safari)
pc.createOffer(
(offer) => {
console.log('Offer created successfully');
pc.setLocalDescription(offer);
},
(error) => {
console.error('Failed to create offer:', error);
},
{ offerToReceiveAudio: true, offerToReceiveVideo: true }
);Safari-specific getUserMedia compatibility shim.
/**
* Shims getUserMedia for Safari browsers
* Provides consistent media access API for Safari
* @param window - Browser window object
*/
function shimGetUserMedia(window: Window): void;What it fixes:
Usage Examples:
import adapter from 'webrtc-adapter';
// getUserMedia works consistently in Safari (automatically shimmed)
navigator.mediaDevices.getUserMedia({
video: { width: 640, height: 480 },
audio: { echoCancellation: true }
})
.then((stream) => {
console.log('Media access granted');
localVideo.srcObject = stream;
})
.catch((error) => {
console.error('Media access denied:', error);
});Normalizes media constraints for Safari-specific requirements.
/**
* Normalizes media constraints for Safari requirements
* Converts constraints to Safari-compatible format
* @param constraints - MediaStreamConstraints to normalize
*/
function shimConstraints(constraints: MediaStreamConstraints): void;What it fixes:
Normalizes RTCIceServer URL formats for Safari.
/**
* Shims RTCIceServer URLs for Safari browsers
* Converts STUN/TURN URLs to Safari-compatible format
* @param window - Browser window object
*/
function shimRTCIceServerUrls(window: Window): void;What it fixes:
Usage Examples:
import adapter from 'webrtc-adapter';
// ICE server configuration works in Safari (automatically shimmed)
const pc = new RTCPeerConnection({
iceServers: [
{ urls: 'stun:stun.l.google.com:19302' },
{
urls: ['turn:turn.example.com:3478'],
username: 'user',
credential: 'pass'
}
]
});Provides proper transceiver information in track events for Safari.
/**
* Shims track event transceiver information for Safari
* Ensures proper transceiver data in ontrack events
* @param window - Browser window object
*/
function shimTrackEventTransceiver(window: Window): void;What it fixes:
Provides legacy createOffer behavior compatibility for Safari.
/**
* Shims legacy createOffer behavior for Safari
* Handles older Safari createOffer implementation differences
* @param window - Browser window object
*/
function shimCreateOfferLegacy(window: Window): void;What it fixes:
Provides AudioContext compatibility for Safari browsers.
/**
* Shims AudioContext for Safari browsers
* Ensures consistent audio processing capabilities
* @param window - Browser window object
*/
function shimAudioContext(window: Window): void;What it fixes:
Usage Examples:
import adapter from 'webrtc-adapter';
// Audio context works consistently (automatically shimmed)
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
// Process audio from WebRTC stream
function processAudio(stream) {
const source = audioContext.createMediaStreamSource(stream);
const analyser = audioContext.createAnalyser();
source.connect(analyser);
// Audio processing works consistently across browsers
}All Safari-specific shims are available through the browser shim interface:
interface ISafariShim {
shimLocalStreamsAPI: (window: Window) => void;
shimRemoteStreamsAPI: (window: Window) => void;
shimCallbacksAPI: (window: Window) => void;
shimGetUserMedia: (window: Window) => void;
shimConstraints: (constraints: MediaStreamConstraints) => void;
shimRTCIceServerUrls: (window: Window) => void;
shimTrackEventTransceiver: (window: Window) => void;
shimCreateOfferLegacy: (window: Window) => void;
shimAudioContext: (window: Window) => void;
}These shims are automatically applied when Safari is detected and can be accessed via adapter.browserShim when the current browser is Safari.
Safari's Unified Plan support varies by version:
// Check Unified Plan support
if (adapter.browserDetails.supportsUnifiedPlan) {
console.log('Safari supports Unified Plan');
// Use modern transceiver-based API
} else {
console.log('Safari uses Plan-B');
// Use legacy stream-based API
}Mobile Safari has additional considerations:
Different Safari versions require different handling:
Install with Tessl CLI
npx tessl i tessl/npm-webrtc-adapterdocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10