Bug 197688 - Safari resumes autoplay audio elements after getUserMedia
Summary: Safari resumes autoplay audio elements after getUserMedia
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Media (show other bugs)
Version: Safari Technology Preview
Hardware: Mac macOS 10.14
: P2 Normal
Assignee: youenn fablet
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2019-05-08 01:24 PDT by Szymon Witamborski
Modified: 2019-12-19 01:03 PST (History)
14 users (show)

See Also:


Attachments
Patch (7.87 KB, patch)
2019-12-16 01:52 PST, youenn fablet
no flags Details | Formatted Diff | Diff
Patch (7.99 KB, patch)
2019-12-18 02:23 PST, youenn fablet
no flags Details | Formatted Diff | Diff
Patch for landing (7.96 KB, patch)
2019-12-18 07:02 PST, youenn fablet
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Szymon Witamborski 2019-05-08 01:24:52 PDT
Audio elements that have autoplay attribute start playing after getUserMedia resolves.

Steps to reproduce:

1. have an <audio src="..." loop autoplay> element in the document
   - loop is optional but helps to demonstrate the issue, it could be just a long audio file instead
2. start playback by either:
   - setting "Allow All Auto-Play" for the site
   - starting playback manually
3. stop playback by either:
   - calling pause() method on the play element
   - removing the audio element from DOM
4. request access to the microphone via getUserMedia({ audio: true })

After getUserMedia resolves successfully, the audio element starts playing again, even emits "play" event, even if the element is not in the DOM any more.

I found out that removing the autoplay attribute from the element before calling getUserMedia works around it.

Here's a codepen that demonstrates the issue with the "remove from DOM" approach but it's the same when calling pause() method instead:

https://codepen.io/brainshave/pen/LoVaRj

I'm guessing this is related to Safari lifting up constraints on autoplay after successful getUserMedia request. Resuming explicitly paused elements seems like an undesired side-effect though.

Tested on Safari 12.1 and TP 81. Tried to run Nightly but I seem to be getting a case of https://bugs.webkit.org/show_bug.cgi?id=194808
Comment 1 Radar WebKit Bug Importer 2019-12-05 13:13:24 PST
<rdar://problem/57674395>
Comment 2 Jer Noble 2019-12-05 13:16:25 PST
Here's the stack trace of the play() called after getUserMedia() promise returns:

  4 468288 WebCore::HTMLMediaElement::play():entry 
              WebCore`WebCore::HTMLMediaElement::play()
              WebCore`WebCore::HTMLMediaElement::resumeAutoplaying()+0xac
              WebCore`WebCore::Document::updateIsPlayingMedia(unsigned long long)+0x29d
              WebCore`WebCore::MediaStreamTrackPrivate::forEachObserver(WTF::Function<void (WebCore::MediaStreamTrackPrivate::Observer&)> const&) const+0x2bc
              WebCore`WebCore::MediaStreamTrackPrivate::sourceStarted()+0x39
              WebCore`WebCore::RealtimeMediaSource::forEachObserver(WTF::Function<void (WebCore::RealtimeMediaSource::Observer&)> const&) const+0x2bc
              WebCore`WebCore::RealtimeMediaSource::start()+0xad
              WebCore`WebCore::MediaStreamPrivate::startProducingData()+0xad
              WebCore`WebCore::MediaStream::startProducingData()+0xc7
Comment 3 pauldconlin 2019-12-05 13:19:28 PST
We're also experiencing this same bug with Flipgrid. Our case involves a video tag instead of audio tag, but the result is the same. We also have a codepen here to reproduce - https://codepen.io/mg0stisha/pen/OJPVEzm

Steps to reproduce:
- Play the video
- Pause the video
- Click the 'click me' button (this will remove the video from the DOM)
- Accept the camera permissions
    
Expected: Camera and audio are now in place of the previous video
    
Actual: Camera is shown but audio from previous video is playing

Firefox: no repro
Chrome: no repro
Edge: no repro

This is currently a production issue for us. The user impact is they are watching other students videos, and then they go to record their own video. Upon accepting camera permissions, the audio of the previous videos they watched then plays in the background causing a jarring experience. 

We really want to create a great experience for Safari users, and currently we are recommending users to download Chrome/New Edge. We're also in the process of developing a workaround for this issue, but would love to help get it resolved if possible instead.

Thank you in advance for your help!
Comment 4 Jer Noble 2019-12-05 13:47:22 PST
This is in HTMLMediaElement.h:

```
    void mediaStreamCaptureStarted() { resumeAutoplaying(); }
```

This doesn't seem right; as it's broadcast to every element in the page when capture is started.
Comment 5 youenn fablet 2019-12-16 01:52:37 PST
Created attachment 385743 [details]
Patch
Comment 6 youenn fablet 2019-12-18 02:23:23 PST
Created attachment 385948 [details]
Patch
Comment 7 youenn fablet 2019-12-18 05:57:25 PST
Comment on attachment 385948 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=385948&action=review

> Source/WebCore/ChangeLog:13
> +        Previously, we were piggy backing on resuming autoplay, which happens after intteruption.

s/tt/t/
Comment 8 Eric Carlson 2019-12-18 06:00:42 PST
Comment on attachment 385948 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=385948&action=review

>> Source/WebCore/ChangeLog:13
>> +        Previously, we were piggy backing on resuming autoplay, which happens after intteruption.
> 
> s/tt/t/

s/piggy backing/piggybacking/
Comment 9 youenn fablet 2019-12-18 07:02:08 PST
Created attachment 385969 [details]
Patch for landing
Comment 10 WebKit Commit Bot 2019-12-19 01:03:14 PST
Comment on attachment 385969 [details]
Patch for landing

Clearing flags on attachment: 385969

Committed r253742: <https://trac.webkit.org/changeset/253742>
Comment 11 WebKit Commit Bot 2019-12-19 01:03:16 PST
All reviewed patches have been landed.  Closing bug.