What to do if WebRTC on iOS shows a black box

By

Fix WebRTC video showing a black box on iOS Safari by adding the playsinline attribute to your video tags, which is written playsInline in JSX.

~~~

If your WebRTC video streams show up as a black box on iOS, the fix is most likely adding the playsinline attribute to your video tags. Here’s the story of how I found that out.

I was doing a project using WebRTC and in particular with the PeerJS library.

It worked fine on desktop but on iOS Safari, all I was seeing for the video streams was a black box.

Even for the local stream.

That last detail was the useful clue. The local stream comes straight from getUserMedia(), it never touches the network. So the problem couldn’t be the peer connection, the signaling, or PeerJS. It had to be the video element itself.

What I had to do was to add the playsinline attribute to the video tags for both the local and remote streams:

<video id="local" autoplay playsinline muted></video>
<video id="remote" autoplay playsinline></video>

(note: it’s playsInline in JSX)

Why does iOS need this?

iPhone Safari historically plays videos in fullscreen mode. When a video starts, it takes over the whole screen.

For a WebRTC app that’s useless. You want the streams rendered inline in your page layout, next to your controls, your chat, whatever else you built. The playsinline attribute tells Safari to allow exactly that.

Without it, Safari won’t render the stream inside the element. The video is playing as far as your JavaScript is concerned, no errors anywhere, but the box stays black. That’s what makes this so annoying to debug.

The muted attribute matters too

Notice the local video has muted on it. You want that for two reasons.

First, without it your own microphone plays back through your own speakers, and you get feedback.

Second, mobile browsers only allow autoplay on muted videos. An unmuted video with autoplay won’t start on its own, and a stream that never starts playing looks like, you guessed it, a black box.

If it’s still black

Check that you’re actually attaching the stream, with srcObject and not src:

video.srcObject = stream

And test with Low Power Mode off. When it’s on, iOS blocks autoplay entirely, and the video only starts after a user tap that calls video.play(). If your users report black boxes you can’t reproduce, that’s a good suspect.

~~~

Related posts about platform: