or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

browser-detection.mdchrome-shims.mdcommon-shims.mdfactory-configuration.mdfirefox-shims.mdindex.mdsafari-shims.mdutility-functions.md

safari-shims.mddocs/

0

# Safari Shims

1

2

Safari-specific shims handle compatibility issues and behavioral differences in Safari browsers to ensure consistent WebRTC behavior across desktop and mobile Safari platforms.

3

4

## Capabilities

5

6

### Local Streams API Shimming

7

8

Provides consistent local streams API for Safari browsers.

9

10

```javascript { .api }

11

/**

12

* Shims local streams API for Safari browsers

13

* Ensures proper local stream handling and events

14

* @param window - Browser window object

15

*/

16

function shimLocalStreamsAPI(window: Window): void;

17

```

18

19

**What it fixes:**

20

- Standardizes local stream addition and management

21

- Provides consistent stream event handling

22

- Ensures proper track-to-stream association

23

24

### Remote Streams API Shimming

25

26

Provides consistent remote streams API for Safari browsers.

27

28

```javascript { .api }

29

/**

30

* Shims remote streams API for Safari browsers

31

* Ensures proper remote stream handling and events

32

* @param window - Browser window object

33

*/

34

function shimRemoteStreamsAPI(window: Window): void;

35

```

36

37

**What it fixes:**

38

- Standardizes remote stream reception and handling

39

- Provides consistent remote track events

40

- Ensures proper stream reconstruction from tracks

41

42

**Usage Examples:**

43

44

```javascript

45

import adapter from 'webrtc-adapter';

46

47

const pc = new RTCPeerConnection();

48

49

// Remote stream handling (automatically shimmed)

50

pc.ontrack = (event) => {

51

console.log('Received remote track:', event.track.kind);

52

53

// Streams array is properly populated in Safari

54

if (event.streams && event.streams.length > 0) {

55

const remoteStream = event.streams[0];

56

videoElement.srcObject = remoteStream;

57

}

58

};

59

```

60

61

### Callbacks API Shimming

62

63

Provides callback-based API compatibility for legacy Safari WebRTC implementations.

64

65

```javascript { .api }

66

/**

67

* Shims callbacks API for Safari browsers

68

* Provides legacy callback compatibility for older Safari versions

69

* @param window - Browser window object

70

*/

71

function shimCallbacksAPI(window: Window): void;

72

```

73

74

**What it fixes:**

75

- Adds callback-based createOffer/createAnswer support

76

- Provides legacy success/failure callback handling

77

- Maintains compatibility with older WebRTC patterns

78

79

**Usage Examples:**

80

81

```javascript

82

import adapter from 'webrtc-adapter';

83

84

const pc = new RTCPeerConnection();

85

86

// Legacy callback style (automatically shimmed to work in Safari)

87

pc.createOffer(

88

(offer) => {

89

console.log('Offer created successfully');

90

pc.setLocalDescription(offer);

91

},

92

(error) => {

93

console.error('Failed to create offer:', error);

94

},

95

{ offerToReceiveAudio: true, offerToReceiveVideo: true }

96

);

97

```

98

99

### GetUserMedia Shimming

100

101

Safari-specific getUserMedia compatibility shim.

102

103

```javascript { .api }

104

/**

105

* Shims getUserMedia for Safari browsers

106

* Provides consistent media access API for Safari

107

* @param window - Browser window object

108

*/

109

function shimGetUserMedia(window: Window): void;

110

```

111

112

**What it fixes:**

113

- Standardizes getUserMedia constraints handling

114

- Normalizes device access permissions

115

- Provides consistent error reporting

116

117

**Usage Examples:**

118

119

```javascript

120

import adapter from 'webrtc-adapter';

121

122

// getUserMedia works consistently in Safari (automatically shimmed)

123

navigator.mediaDevices.getUserMedia({

124

video: { width: 640, height: 480 },

125

audio: { echoCancellation: true }

126

})

127

.then((stream) => {

128

console.log('Media access granted');

129

localVideo.srcObject = stream;

130

})

131

.catch((error) => {

132

console.error('Media access denied:', error);

133

});

134

```

135

136

### Constraints Normalization

137

138

Normalizes media constraints for Safari-specific requirements.

139

140

```javascript { .api }

141

/**

142

* Normalizes media constraints for Safari requirements

143

* Converts constraints to Safari-compatible format

144

* @param constraints - MediaStreamConstraints to normalize

145

*/

146

function shimConstraints(constraints: MediaStreamConstraints): void;

147

```

148

149

**What it fixes:**

150

- Converts unsupported constraint formats

151

- Maps constraint names to Safari equivalents

152

- Ensures constraint value compatibility

153

154

### RTCIceServer URLs Shimming

155

156

Normalizes RTCIceServer URL formats for Safari.

157

158

```javascript { .api }

159

/**

160

* Shims RTCIceServer URLs for Safari browsers

161

* Converts STUN/TURN URLs to Safari-compatible format

162

* @param window - Browser window object

163

*/

164

function shimRTCIceServerUrls(window: Window): void;

165

```

166

167

**What it fixes:**

168

- Converts 'urls' array to 'url' string format

169

- Handles STUN/TURN server configuration differences

170

- Ensures ICE server compatibility

171

172

**Usage Examples:**

173

174

```javascript

175

import adapter from 'webrtc-adapter';

176

177

// ICE server configuration works in Safari (automatically shimmed)

178

const pc = new RTCPeerConnection({

179

iceServers: [

180

{ urls: 'stun:stun.l.google.com:19302' },

181

{

182

urls: ['turn:turn.example.com:3478'],

183

username: 'user',

184

credential: 'pass'

185

}

186

]

187

});

188

```

189

190

### Track Event Transceiver Shimming

191

192

Provides proper transceiver information in track events for Safari.

193

194

```javascript { .api }

195

/**

196

* Shims track event transceiver information for Safari

197

* Ensures proper transceiver data in ontrack events

198

* @param window - Browser window object

199

*/

200

function shimTrackEventTransceiver(window: Window): void;

201

```

202

203

**What it fixes:**

204

- Adds missing transceiver property to track events

205

- Provides proper transceiver-track association

206

- Ensures consistent event structure

207

208

### Legacy CreateOffer Shimming

209

210

Provides legacy createOffer behavior compatibility for Safari.

211

212

```javascript { .api }

213

/**

214

* Shims legacy createOffer behavior for Safari

215

* Handles older Safari createOffer implementation differences

216

* @param window - Browser window object

217

*/

218

function shimCreateOfferLegacy(window: Window): void;

219

```

220

221

**What it fixes:**

222

- Handles legacy createOffer options format

223

- Provides backward compatibility for older Safari versions

224

- Normalizes offer creation behavior

225

226

### AudioContext Shimming

227

228

Provides AudioContext compatibility for Safari browsers.

229

230

```javascript { .api }

231

/**

232

* Shims AudioContext for Safari browsers

233

* Ensures consistent audio processing capabilities

234

* @param window - Browser window object

235

*/

236

function shimAudioContext(window: Window): void;

237

```

238

239

**What it fixes:**

240

- Adds webkit-prefixed AudioContext support

241

- Provides consistent audio API access

242

- Handles Safari-specific audio context requirements

243

244

**Usage Examples:**

245

246

```javascript

247

import adapter from 'webrtc-adapter';

248

249

// Audio context works consistently (automatically shimmed)

250

const audioContext = new (window.AudioContext || window.webkitAudioContext)();

251

252

// Process audio from WebRTC stream

253

function processAudio(stream) {

254

const source = audioContext.createMediaStreamSource(stream);

255

const analyser = audioContext.createAnalyser();

256

source.connect(analyser);

257

258

// Audio processing works consistently across browsers

259

}

260

```

261

262

## Safari Shim Interface

263

264

All Safari-specific shims are available through the browser shim interface:

265

266

```javascript { .api }

267

interface ISafariShim {

268

shimLocalStreamsAPI: (window: Window) => void;

269

shimRemoteStreamsAPI: (window: Window) => void;

270

shimCallbacksAPI: (window: Window) => void;

271

shimGetUserMedia: (window: Window) => void;

272

shimConstraints: (constraints: MediaStreamConstraints) => void;

273

shimRTCIceServerUrls: (window: Window) => void;

274

shimTrackEventTransceiver: (window: Window) => void;

275

shimCreateOfferLegacy: (window: Window) => void;

276

shimAudioContext: (window: Window) => void;

277

}

278

```

279

280

These shims are automatically applied when Safari is detected and can be accessed via `adapter.browserShim` when the current browser is Safari.

281

282

## Safari-Specific Considerations

283

284

### Unified Plan Support

285

286

Safari's Unified Plan support varies by version:

287

288

```javascript

289

// Check Unified Plan support

290

if (adapter.browserDetails.supportsUnifiedPlan) {

291

console.log('Safari supports Unified Plan');

292

// Use modern transceiver-based API

293

} else {

294

console.log('Safari uses Plan-B');

295

// Use legacy stream-based API

296

}

297

```

298

299

### Mobile Safari Differences

300

301

Mobile Safari has additional considerations:

302

- Different getUserMedia behavior

303

- Limited codec support

304

- iOS-specific permissions model

305

- WebRTC background behavior restrictions

306

307

### Version-Specific Behavior

308

309

Different Safari versions require different handling:

310

- Legacy callback-based APIs for older versions

311

- Modern Promise-based APIs for newer versions

312

- Progressive enhancement based on feature detection