googlecodelabs / webrtc-web

Realtime communication with WebRTC
https://codelabs.developers.google.com/codelabs/webrtc-web/
Apache License 2.0
753 stars 350 forks source link

WebRTC is not working connecting Safari with Chrome for Android #56

Open hermanfransen opened 6 years ago

hermanfransen commented 6 years ago

WebRTC is not working connecting Safari with Chrome for Android. From Chrome on Desktop to Safari there is no problem. Also Safari - Safari gives no problems.

I posted this question also on StackOverflow earlier but without any results.

Apple is natively supporting WebRTC since iOS 11 and Safari 11 on the desktop.

I installed the codelab on a Ubuntu server. For the test I used both devices within the same WiFi network, just to make sure.

It works WELL in these cases (see specifications devices):

It's NOT working in these cases:

Specifications of the devices:

Desktop/Chrome

Desktop/Safari

Android/Tab/Chrome

iPad/Safari

iPhone/Safari

1) Android/Tab/Chrome <-> iPad/Safari

Android/Tab/Chrome sends an offer, then iPad/Safari receives it, but then giving an error:

Unhandled Promise Rejection: OperationError (DOM Exception 34): 
Failed to set remote offer sdp: Session error code: ERROR_CONTENT. 
Session error description: Failed to set remote video description send parameters..

The sdp offer:

v=0
o=- 7644883235956031763 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS Yiel2ebiIcKBPDaLuAqKaFpR93Mbz1tSsNRm
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 9 0 8 105 13 110 113 126
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:mXxq
a=ice-pwd:T4vRjmDaHYES+J3WJ8NAx65S
a=ice-options:trickle
a=fingerprint:sha-256 B1:36:E3:06:6E:6F:73:59:96:BB:74:95:79:20:64:F6:45:AD:99:1A:43:78:AD:CA:CA:7A:D9:23:2C:D8:C5:07
a=setup:actpass
a=mid:audio
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=sendrecv
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:103 ISAC/16000
a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:105 CN/16000
a=rtpmap:13 CN/8000
a=rtpmap:110 telephone-event/48000
a=rtpmap:113 telephone-event/16000
a=rtpmap:126 telephone-event/8000
a=ssrc:1841783350 cname:RdL9LRY2OCXO8jbB
a=ssrc:1841783350 msid:Yiel2ebiIcKBPDaLuAqKaFpR93Mbz1tSsNRm e1a0f1a7-66bf-4921-9677-30e5e838ad02
a=ssrc:1841783350 mslabel:Yiel2ebiIcKBPDaLuAqKaFpR93Mbz1tSsNRm
a=ssrc:1841783350 label:e1a0f1a7-66bf-4921-9677-30e5e838ad02
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 102
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:mXxq
a=ice-pwd:T4vRjmDaHYES+J3WJ8NAx65S
a=ice-options:trickle
a=fingerprint:sha-256 B1:36:E3:06:6E:6F:73:59:96:BB:74:95:79:20:64:F6:45:AD:99:1A:43:78:AD:CA:CA:7A:D9:23:2C:D8:C5:07
a=setup:actpass
a=mid:video
a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:4 urn:3gpp:video-orientation
a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type
a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/video-timing
a=sendrecv
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:96 VP8/90000
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli
a=rtcp-fb:96 goog-remb
a=rtcp-fb:96 transport-cc
a=rtpmap:97 rtx/90000
a=fmtp:97 apt=96
a=rtpmap:98 VP9/90000
a=rtcp-fb:98 ccm fir
a=rtcp-fb:98 nack
a=rtcp-fb:98 nack pli
a=rtcp-fb:98 goog-remb
a=rtcp-fb:98 transport-cc
a=rtpmap:99 rtx/90000
a=fmtp:99 apt=98
a=rtpmap:100 red/90000
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=rtpmap:102 ulpfec/90000
a=ssrc-group:FID 659734980 914875391
a=ssrc:659734980 cname:RdL9LRY2OCXO8jbB
a=ssrc:659734980 msid:Yiel2ebiIcKBPDaLuAqKaFpR93Mbz1tSsNRm 53ce1350-e2ef-426e-9023-e91e4ea08dc6
a=ssrc:659734980 mslabel:Yiel2ebiIcKBPDaLuAqKaFpR93Mbz1tSsNRm
a=ssrc:659734980 label:53ce1350-e2ef-426e-9023-e91e4ea08dc6
a=ssrc:914875391 cname:RdL9LRY2OCXO8jbB
a=ssrc:914875391 msid:Yiel2ebiIcKBPDaLuAqKaFpR93Mbz1tSsNRm 53ce1350-e2ef-426e-9023-e91e4ea08dc6
a=ssrc:914875391 mslabel:Yiel2ebiIcKBPDaLuAqKaFpR93Mbz1tSsNRm
a=ssrc:914875391 label:53ce1350-e2ef-426e-9023-e91e4ea08dc6

If iPad/Safari first sends an offer, same error message on the Android/Tab/Chrome.

2) Same error in case:

Android/Tab/Chrome <-> iPhone/Safari
Android/Tab/Chrome <-> Desktop/Safari

Uncaught (in promise) DOMException: Failed to set remote offer sdp: 
Session error code: ERROR_CONTENT. Session error description: 
Failed to set remote video description send parameters..

UPDATE:

Since upgrading from iOS 11.1.2 to iOS 11.2.2 the other problem Desktop/Chrome <-> iPhone/Safari is solved. So this is working right now.

samdutton commented 6 years ago

Thanks @hermanfransen — looking into this now.

alvestrand commented 6 years ago

These are scenarios that should be tested by Kite - https://github.com/webrtc/kite @agouaillard - is this consistent with your tests, alternatively is there material here for better tests?

alvestrand commented 6 years ago

One obvious problem with the offer cited is that it only offers VP8 and VP9 video. I believe Apple/Safari still hasn't implemented that part of the spec that mandates VP8; it's H.264 only.

fippo commented 6 years ago

@alvestrand much of the pain is caused by not fixing https://bugs.chromium.org/p/webrtc/issues/detail?id=4957 ... I am interested in hearing why this is a P3.

The other issue is profile levels which is described in https://bugs.chromium.org/p/webrtc/issues/detail?id=8584

seiyuricardohiga commented 6 years ago

I've fixed the communication between Chrome and Safari by adding "playsinline" inside < video > and changing the methods "handleRemoteStreamAdded(event)" and "gotStream(stream)"

<div id="videos">
  <video id="localVideo" autoplay muted playsinline></video>
  <video id="remoteVideo" autoplay playsinline></video>
</div>
function handleRemoteStreamAdded(event) {
    console.log('Remote stream added.');
    try{
        remoteVideo.srcObject = event.stream;
    }catch (error){
        remoteVideo.src = window.URL.createObjectURL(event.stream);
    }
    remoteStream = event.stream;
}
function gotStream(stream) {
    console.log('Adding local stream.');
    try{
        localVideo.srcObject = stream;
    }catch (error){
        localVideo.src = window.URL.createObjectURL(stream);
    }
    localStream = stream;
    sendMessage('got user media');
    if (isInitiator) {
        maybeStart();
    }
}
seiyuricardohiga commented 6 years ago

I've hosted an example here for testing proposes: I've commented out these lines like @kekeoki said in the issue #14

// if (location.hostname !== 'localhost') {
//   requestTurn(
//     'https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913'
//   );
// }

And i've uncommented this line for getting a room name from the user

// var room = 'foo';
// Could prompt for room name:
var room = prompt('Enter room name:');

@hermanfransen you can try it and tell me if it works because i'm not able to test all the cases that you mention. I've tested in these cases:

hermanfransen commented 6 years ago

@seiyuricardohiga - Thanks for helping in this issue. I tested the following three cases with your hosted example, but unfortunately your fix didn't solve the problem.

It is giving the same error as reported before:

Unhandled Promise Rejection: OperationError (DOM Exception 34): 
Failed to set remote offer sdp: Session error code: ERROR_CONTENT. 
Session error description: Failed to set remote video description send parameters..

I'm pretty sure it has to do with this bug: https://bugs.chromium.org/p/webrtc/issues/detail?id=8584

Since upgrading from iOS 11.1.2 to iOS 11.2.2 the other problem Desktop/Chrome <-> iPhone/Safari is solved. So it is working right now.

Read this and this for the original bug report.

I updated the issue, also Desktop/Chrome <> Desktop/Safari was and is no problem. It's just a problem between Chrome for Android and Safari.

hermanfransen commented 6 years ago

@samdutton @fippo

Conclusion of this Issue:

There seam to be a bug #8584: Chrome Android does not offer/answer H.264 Constrained Baseline Profile.

This is causing Chrome for Android not to connect to Apple Safari. Also because Apple only supports H264.

Is there any workaround for this issue?

samdutton commented 6 years ago

Thanks @seiyuricardohiga!

@nitobuendia — we should add the playsinline fix suggested. Could you do a PR at some stage? We should make sure to use only srcObject() throughout, since this is now well supported and URL.createObjectURL() is deprecated.

@hermanfransen

Is there any workaround for this issue?

Not that I'm aware of, but @fippo may well know more.

fippo commented 6 years ago

SDP munging -- I still wonder in what flakes @alvestrand got his magic profile level decoder ring...

seiyuricardohiga commented 6 years ago

@hermanfransen you're right. I'm using video services from tokbox and i didn't realize that they have the same issue here Now I've tried with Android/Tab/Chrome <-> iPhone/Safari and I think they did a little workaround because everything works fine on Android but i'm not able to receive the video stream on Safari, just audio.

odivorra commented 6 years ago

FYI: https://bugs.chromium.org/p/chromium/issues/detail?id=793038 I believe things should improve starting on Chrome Android 65 (now Canary)

hermanfransen commented 6 years ago

@seiyuricardohiga - In my test it was working. What Android device did you use?

May be you bumped into the second issue?

At present H.264 video codec is limited to Qualcomm (Kitkat and later) and Samsung Exynos (Lollipop and later) chipsets. As there is no software H.264 encoder implementation, only the aforementioned chipsets are supported.

nitobuendia commented 6 years ago

@samdutton On it.

odivorra commented 6 years ago

FYI: Another issue with Chrome Android H264 in close relation: https://bugs.chromium.org/p/monorail/issues/detail?id=3424 HW H264 from the device I tested fails to work well with SFUs as the encoder is not inserting SPS (NALU 7) with IDRs (NALU 5) except for the very first IDR. In P2P works because the latter.

hermanfransen commented 6 years ago

I just tested it with Chrome Canary 66.0.3334.0 but still same error I am getting

huynhquocmy commented 6 years ago

Hello @hermanfransen , I would like to know if you have any update ? I got same issue. Thanks!

hermanfransen commented 6 years ago

Hi @huynhquocmy , when I reed this the bug is fixed and they say it will probably be merged into Chrome M65.

You should be aware there are two different issues (that are often mixed up) making a WebRTC connection between Chrome on Android and iOS/Safari not working. See here for more info.

huynhquocmy commented 6 years ago

Thanks for your quick response @hermanfransen. Appreciate it!

jlberrocal commented 6 years ago

is there any new about this? still getting the same issue on version 67

huynhquocmy commented 6 years ago

@jlberrocal: I haven't checked since 5 months ago. please help to verify again!

jlberrocal commented 6 years ago

well in fact i have been working this week in a tool for use camera to take a picture and seems that chromium based browsers are failing on android they just display a black screen instead of the stream with no errors on console

neilkinnish commented 6 years ago

This issue seems to exist still even in Canary version 69.

Still getting...

Unhandled Promise Rejection: OperationError (DOM Exception 34): 
Failed to set remote offer sdp: Session error code: ERROR_CONTENT. 
Session error description: Failed to set remote video description send parameters..

On android chrome when using h264.

I've looked into all the sdp mundge options but have not found a resolve for this yet

suman commented 5 years ago

I am able to run the following example on browsers of Linux computer. But the remote video is not displaying when I run this example between Google-chrome 69 of Window 10(desktop) and Safari of iPad 11.4.1.

It displays only local stream not remote stream. However each user has getting remote stream and when I debug this stream, it has the property muted with true value. While in example-working case, it has value false.

Following is the screen shot of remote media stream when video is not displaying.

Remote Media stream alt text

chevsky commented 5 years ago

@bogatisuman got the same thing

wiwengweng commented 5 years ago

Hi, all. I see the samples work on https, and I just deploy on http, the samples works on Android phones, but faile on ios 11. Do the samples need https on ios??

HPODEV commented 5 years ago

i have same problem Video format not supported, i follow

alakhera commented 4 years ago

I am also experiencing similar issue on ios 12/13. I do have added code for onunmute event like

e.track.onunmute = () => { console.log('onunmute called for',e) if (!remoteVideo.srcObject) { remoteVideo.srcObject = e.streams[0]; remoteVideo.setAttribute('playsinline', true); } }

In case this works, the track's muted state is false, and when this doesn't work, even inside the onunmute event the track's muted state is true.

Has anyone found a solution getting the iOS working with more than 3-4 peers?