Device: iPhone 15, iOS 26.6, Safari. Also reproduced on Android Chrome, so this is not only WebKit, but the missing rotation flag part is.
Setup: a web page asks for the front camera with getUserMedia, shows it in a video element, and records with MediaRecorder. Phone held upright.
What happens:
-
Requesting portrait dimensions (width 1080, height 1920) returns the sensor's wide preset, 1920 by 1080, unrotated. exact instead of ideal gives the same or an error. aspectRatio 9/16 gives the same. Requesting landscape numbers (width 1920, height 1080) lets Safari pick the preset and rotate the picture to match how the phone is held.
-
Even then, the video track's getSettings() reports width 1920 and height 1080, while the frame Safari draws into the video element is portrait. The preview looks right. The track lies.
-
MediaRecorder records the unrotated sensor buffer. On older iOS the file carried a displaymatrix rotation of minus 90 degrees and players honoured it. On 26.6 that flag is gone, so the file plays sideways. Thread 786803 has other people finding the same.
Workaround that works in production:
- Ask for the camera in landscape numbers.
- Do not trust getSettings(). Draw one frame of the video element onto a 16 by 16 canvas scaled from the larger reported dimension and check which corner has paint. If the bottom left is painted and the top right is not, the picture is tall.
- If the drawn picture is portrait but the track says landscape, record a canvas stream of the drawn picture at its own size instead of the raw track. If they agree, record the raw track.
- Put the H.264 High profile first in your mime type candidates. isTypeSupported says yes to Baseline and High, and list order decides, so Baseline first gives soft video.
Working code, MIT, with the dead ends left in as comments: https://github.com/lagudafuadtosin/web-teleprompter (src/lib/camera.ts)
Full write-up: https://dev.to/lagudafuad/why-your-web-teleprompter-records-sideways-on-iphone-and-the-fix-549m
Question for Apple: is the dropped displaymatrix on MediaRecorder output in 26.x intentional, and is there a supported way to read the capture rotation off the track?