<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>180522</bug_id>
          
          <creation_ts>2017-12-06 22:41:06 -0800</creation_ts>
          <short_desc>Web audio without audio output should not require any user gesture on iOS</short_desc>
          <delta_ts>2022-05-06 13:26:09 -0700</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>WebRTC</component>
          <version>Safari 11</version>
          <rep_platform>iPhone / iPad</rep_platform>
          <op_sys>iOS 11</op_sys>
          <bug_status>NEW</bug_status>
          <resolution></resolution>
          
          <see_also>https://bugs.webkit.org/show_bug.cgi?id=180680</see_also>
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords>InRadar</keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Adam">adam</reporter>
          <assigned_to name="Nobody">webkit-unassigned</assigned_to>
          <cc>andrew</cc>
    
    <cc>brad</cc>
    
    <cc>daginge</cc>
    
    <cc>jer.noble</cc>
    
    <cc>jonlee</cc>
    
    <cc>webkit-bug-importer</cc>
    
    <cc>youennf</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>1379039</commentid>
    <comment_count>0</comment_count>
    <who name="Adam">adam</who>
    <bug_when>2017-12-06 22:41:06 -0800</bug_when>
    <thetext>We use the following code to analyse the audio input level in a local MediaStream coming from getUserMedia. This works fine in Safari on a Mac but on iOS you get constant 0 (because timeDomainData[idx] always returns 128).

navigator.mediaDevices.getUserMedia({audio:true}).then(stream =&gt; {
  const context = new (window.AudioContext || window.webkitAudioContext)();
  const sourceNode = context.createMediaStreamSource(stream);
  const analyser = context.createAnalyser();
  sourceNode.connect(analyser);
  const timeDomainData = new Uint8Array(analyser.frequencyBinCount);

  setInterval(() =&gt; {
    analyser.getByteTimeDomainData(timeDomainData);
    
    let max = 0;
    for (let idx = 0; idx &lt; timeDomainData.length; idx++) {
      max = Math.max(max, Math.abs(timeDomainData[idx] - 128));
    }
    audioLevel.innerHTML = (max / 128);
  }, 100);
}).catch(err =&gt; {
   alert(err.name + &apos; &apos; + err.message);
});


You can see it working at https://output.jsbin.com/rexolan</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1379042</commentid>
    <comment_count>1</comment_count>
    <who name="Adam">adam</who>
    <bug_when>2017-12-06 22:49:15 -0800</bug_when>
    <thetext>It also does not work for remote streams.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1379152</commentid>
    <comment_count>2</comment_count>
    <who name="youenn fablet">youennf</who>
    <bug_when>2017-12-07 10:40:40 -0800</bug_when>
    <thetext>(In reply to Adam from comment #1)
&gt; It also does not work for remote streams.

On iOS, AudioContext needs a user gesture.
Can you retry by starting AudioContext as part of user gesture?
We should probably remove that restriction when getUserMedia is on.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1379309</commentid>
    <comment_count>3</comment_count>
    <who name="Andrew Morris">andrew</who>
    <bug_when>2017-12-07 15:12:14 -0800</bug_when>
    <thetext>&gt; On iOS, AudioContext needs a user gesture.

Is it intended that AudioContext needs a user gesture even when there is no audio output? Being able to visualize the audio volume would be especially useful in exactly this use case when audio output is blocked.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1379319</commentid>
    <comment_count>4</comment_count>
    <who name="youenn fablet">youennf</who>
    <bug_when>2017-12-07 15:23:03 -0800</bug_when>
    <thetext>(In reply to Andrew Morris from comment #3)
&gt; &gt; On iOS, AudioContext needs a user gesture.
&gt; 
&gt; Is it intended that AudioContext needs a user gesture even when there is no
&gt; audio output? Being able to visualize the audio volume would be especially
&gt; useful in exactly this use case when audio output is blocked.

Good point, maybe the restriction should be targeted at the audio output.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1379639</commentid>
    <comment_count>5</comment_count>
    <who name="Radar WebKit Bug Importer">webkit-bug-importer</who>
    <bug_when>2017-12-08 10:48:47 -0800</bug_when>
    <thetext>&lt;rdar://problem/35938085&gt;</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1379640</commentid>
    <comment_count>6</comment_count>
    <who name="Radar WebKit Bug Importer">webkit-bug-importer</who>
    <bug_when>2017-12-08 10:48:49 -0800</bug_when>
    <thetext>&lt;rdar://problem/35938084&gt;</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1380091</commentid>
    <comment_count>7</comment_count>
    <who name="Adam">adam</who>
    <bug_when>2017-12-10 16:00:53 -0800</bug_when>
    <thetext>Yes, it does work if we create the audio context when you click a button.
https://output.jsbin.com/juzufum

Like Andrew said though it would be great if that wasn&apos;t the case.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1380673</commentid>
    <comment_count>8</comment_count>
    <who name="youenn fablet">youennf</who>
    <bug_when>2017-12-12 09:08:19 -0800</bug_when>
    <thetext>bug 180680 is fixing the case of a page capturing data.
Let&apos;s keep this bug open for the wider question of allowing web audio analysis without user gesture</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1380990</commentid>
    <comment_count>9</comment_count>
    <who name="Adam">adam</who>
    <bug_when>2017-12-12 17:57:41 -0800</bug_when>
    <thetext>Fantastic, thanks</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1402871</commentid>
    <comment_count>10</comment_count>
    <who name="Dag-Inge Aas">daginge</who>
    <bug_when>2018-03-01 05:37:57 -0800</bug_when>
    <thetext>We hit this bug as well, where we want to do an automated microphone check for users on their way into a conversation. Our code looks something like this:

function handleUserClick() {
    return mediaDevicesService
      .getUserMedia(constraints)
      .then(mediaStream =&gt; {
        this.setState({ mediaStream });
      })
      .then(() =&gt; enumerateDevices())
      .then(() =&gt; verifyMicrophoneWorks(this.state.mediaStream.stream))
      .then(isMicrophoneWorking =&gt;
        this.props.updateMicStatus(isMicrophoneWorking)
      )
      .catch(error =&gt; &lt;GetUserMediaErrorFeedback error={error} /&gt;);
}

This all happens in a single promise-chain, but because only the original button click is triggered as a user action, the audio context checking fails, even if all we do is check the getByteFrequencyData, and no audio is actually playing.

It would be great if we were allowed to play audio/handle AudioContext once getUserMedia permission is granted for the page for that session.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1402893</commentid>
    <comment_count>11</comment_count>
    <who name="youenn fablet">youennf</who>
    <bug_when>2018-03-01 07:41:28 -0800</bug_when>
    <thetext>daginge, I believe that would be addressed in bug 180680.
Can you try the latest iOS beta?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1411373</commentid>
    <comment_count>12</comment_count>
    <who name="Dag-Inge Aas">daginge</who>
    <bug_when>2018-04-03 01:14:36 -0700</bug_when>
    <thetext>Sorry for the late reply youenn. We decided to refactor as more browsers are adopting autoplay restrictions now, and we don&apos;t want to take the chance that this causes issues in the future. All of our AudioContext&apos;s are triggered by a user action now.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1411415</commentid>
    <comment_count>13</comment_count>
    <who name="youenn fablet">youennf</who>
    <bug_when>2018-04-03 08:36:07 -0700</bug_when>
    <thetext>(In reply to daginge from comment #12)
&gt; Sorry for the late reply youenn. We decided to refactor as more browsers are
&gt; adopting autoplay restrictions now, and we don&apos;t want to take the chance
&gt; that this causes issues in the future. All of our AudioContext&apos;s are
&gt; triggered by a user action now.

No problem daginge.
I believe we could tackle that issue by introducing some WebAudio specific constructs that would allow analyzing audio but not producing any audio.
In that case, we could bypass autoplay restrictions.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1411416</commentid>
    <comment_count>14</comment_count>
    <who name="youenn fablet">youennf</who>
    <bug_when>2018-04-03 08:45:05 -0700</bug_when>
    <thetext>Maybe OfflineAudioContext is what we want.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1411454</commentid>
    <comment_count>15</comment_count>
    <who name="youenn fablet">youennf</who>
    <bug_when>2018-04-03 10:32:02 -0700</bug_when>
    <thetext>(In reply to youenn fablet from comment #14)
&gt; Maybe OfflineAudioContext is what we want.

Discussed with Jer and this is not designed for this use case.
Filed https://github.com/WebAudio/web-audio-api/issues/1551</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>