Code Monkey home page Code Monkey logo

mediasoup-client-flutter's Introduction

mediasoup_client_flutter

Android iOS macOS Windows Linux Web
Unified-Plan

No datachannels yet;

Usage Example

import 'package:mediasoup_client_flutter/mediasoup_client_flutter.dart';
import 'package:my_project/my_signaling.dart';

// Create a device.
final device = Device();

// Communicate with server app to retrieve router RTP capabilities.
final Map<String, dynamic> routerRtpCapabilities = await mySignaling.request('getRouterCapabilities');

// Load the device with the router RTP capabilities.
final rtpCapabilities = RtpCapabilities.fromMap(routerRtpCapabilities);
await device.load(routerRtpCapabilities: rtpCapabilities);

// Check wheter we can produce video to the router.
if (!device.canProduce(RTCRtpMediaType.RTCRtpMediaTypeVideo)) {
    print('cannot produce video');
    // Abort next steps.
}

// Create a transport in the server for sending our media through it.
final Map transportInfo = await mySignaling.request('createTransport', {
    'forceTcp': false,
    'producing': true,
    'consuming': false,
    'sctpCapabilities': device.sctpCapabilities.toMap(),
});

// Create a callback for producers.
void _producerCallback(Producer producer) {
    /* Your code. */
}

final sendTransport = device.createSendTransportFromMap(
    transportInfo,
    producerCallback: _producerCallback,
);

// Set transport "connect" event handler.
sendTransport.on('connect', (Map data) {
// Here we must communicate our local parameters to our remote transport.
mySignaling.request('transport-connect', {
    'transportId': _sendTransport.id,
    'dtlsParameters': data['dtlsParameters'].toMap(),
})
// Done in the server, tell our transport.
.then(data['callback'])
// Something was wrong in server side.
.catchError(data['errback']);
});

// Set transport "produce" event handler.
_sendTransport.on('produce', (Map data) async {
// Here we must communicate our local parameters to our remote transport.
    try {
        Map response = await mySignaling.request(
            'produce',
            {
                'transportId': sendTransport.id,
                'kind': data['kind'],
                'rtpParameters': data['rtpParameters'].toMap(),
                if (data['appData'] != null)
                'appData': Map<String, dynamic>.from(data['appData'])
            },
        );
        // Done in the server, pass the response to our transport.
        data['callback'](response['id']);
    } catch (error) {
        // Something was wrong in server side.
        data['errback'](error);
    }
});

// Produce our webcam video.
Map<String, dynamic> mediaConstraints = <String, dynamic>{
    'audio': false,
    'video': {
        'mandatory': {
            // Provide your own width, height and frame rate here.
            'minWidth': '1280', 
            'minHeight': '720',
            'minFrameRate': '30',
        },
    },
};

final MediaStream stream = await navigator.mediaDevices.getUserMedia(mediaConstraints);
final MediaStreamTrack track = stream.getVideoTracks().first;
sendTransport.produce(
    stream: stream,
    track: track,
    source: 'webcam',
);
// Producer will return through _producerCallback.

Check example for more information;

mediasoup-client-flutter's People

Contributors

blancduman avatar macrow avatar zackmitkin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mediasoup-client-flutter's Issues

Video and screenshot freezes when iOS is backgrounded

I'm having a problem with iOS.
Video and screen recording stops when the application is placed in the background.
The audio stream continues.
In this case, is it necessary to use callkit or replay kit for ios?
Is there a different solution?

mediasoup_client_flutter: ^0.8.1
flutter_webrtc: ^0.8.0
webrtc_interface: 1.0.5

Flutter 3.7.3

feat/example error

Hi all,

Are there anyone who tried feat/example ? It is not complete, gives some type errors :

Debug service listening on ws://127.0.0.1:50020/mFMvVhL3x3E=/ws [Logger::WebTransport] DEBUG: constructor() [url:wss://v3demo.mediasoup.org:4443/?roomId=1&peerId=zxcvvczx, options:null] [Peer] DEBUG: constructor() [Logger::WebTransport] DEBUG: onOpen [Peer] DEBUG: emit "open" [Peer] DEBUG: request() [method:getRouterRtpCapabilities, id: 2309840] {codecs: [{kind: audio, mimeType: audio/opus, clockRate: 48000, channels: 2, rtcpFeedback: [{type: transport-cc, parameter: }], parameters: {useinbandfec: 1, stereo: 1}, preferredPayloadType: 100}, {kind: video, mimeType: video/VP8, clockRate: 90000, rtcpFeedback: [{type: nack, parameter: }, {type: nack, parameter: pli}, {type: ccm, parameter: fir}, {type: goog-remb, parameter: }, {type: transport-cc, parameter: }], parameters: {x-google-start-bitrate: 1500}, preferredPayloadType: 101}, {kind: video, mimeType: video/rtx, preferredPayloadType: 102, clockRate: 90000, parameters: {apt: 101}, rtcpFeedback: []}, {kind: video, mimeType: video/H264, clockRate: 90000, parameters: {packetization-mode: 1, level-asymmetry-allowed: 1, profile-level-id: 42e032}, rtcpFeedback: [{type: nack, parameter: }, {type: nack, parameter: pli}, {type: ccm, parameter: fir}, {type: goog-remb, parameter: }, {type: transport-cc, parameter: }], preferredPayloadType: 103}, {kind: video, mimeType: video/rtx, preferredPayloadType: 104, clockRate: 90000, parameters: {apt: 103}, rtcpFeedback: []}, {kind: video, mimeType: video/VP9, clockRate: 90000, rtcpFeedback: [{type: nack, parameter: }, {type: nack, parameter: pli}, {type: ccm, parameter: fir}, {type: goog-remb, parameter: }, {type: transport-cc, parameter: }], parameters: {x-google-start-bitrate: 1500}, preferredPayloadType: 105}, {kind: video, mimeType: video/rtx, preferredPayloadType: 106, clockRate: 90000, parameters: {apt: 105}, rtcpFeedback: []}], headerExtensions: [{kind: audio, uri: urn:ietf:params:rtp-hdrext:sdes:mid, preferredId: 1, preferredEncrypt: false, direction: sendrecv}, {kind: video, uri: urn:ietf:params:rtp-hdrext:sdes:mid, preferredId: 1, preferredEncrypt: false, direction: sendrecv}, {kind: video, uri: urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id, preferredId: 2, preferredEncrypt: false, direction: recvonly}, {kind: video, uri: urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id, preferredId: 3, preferredEncrypt: false, direction: recvonly}, {kind: audio, uri: http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time, preferredId: 4, preferredEncrypt: false, direction: sendrecv}, {kind: video, uri: http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time, preferredId: 4, preferredEncrypt: false, direction: sendrecv}, {kind: audio, uri: http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01, preferredId: 5, preferredEncrypt: false, direction: recvonly}, {kind: video, uri: http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01, preferredId: 5, preferredEncrypt: false, direction: sendrecv}, {kind: video, uri: http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07, preferredId: 6, preferredEncrypt: false, direction: sendrecv}, {kind: video, uri: urn:ietf:params:rtp-hdrext:framemarking, preferredId: 7, preferredEncrypt: false, direction: sendrecv}, {kind: audio, uri: urn:ietf:params:rtp-hdrext:ssrc-audio-level, preferredId: 10, preferredEncrypt: false, direction: sendrecv}, {kind: video, uri: urn:3gpp:video-orientation, preferredId: 11, preferredEncrypt: false, direction: sendrecv}, {kind: video, uri: urn:ietf:params:rtp-hdrext:toffset, preferredId: 12, preferredEncrypt: false, direction: sendrecv}]} mediasoup-client:Device load() [routerRtpCapabilities:Instance of 'RtpCapabilities'] mediasoup-client:Browser getNativeRtpCapabilities() SdpTransform: trying to add null key parsed: {version: 0, origin: {username: -, sessionId: 7340973776351648000, sessionVersion: 2, netType: IN, ipVer: 4, address: 127.0.0.1}, name: -, invalid: [{value: -}, {value: extmap-allow-mixed}], timing: {start: 0, stop: 0}, groups: [{type: BUNDLE, mids: 0 1}], msidSemantic: {semantic: null, token: WMS}, media: [{rtp: [{payload: 111, codec: opus, rate: 48000, encoding: 2}, {payload: 103, codec: ISAC, rate: 16000, encoding: null}, {payload: 104, codec: ISAC, rate: 32000, encoding: null}, {payload: 9, codec: G722, rate: 8000, encoding: null}, {payload: 0, codec: PCMU, rate: 8000, encoding: null}, {payload: 8, codec: PCMA, rate: 8000, encoding: null}, {payload: 106, codec: CN, rate: 32000, encoding: null}, {payload: 105, codec: CN, rate: 16000, encoding: null}, {payload: 13, codec: CN, rate: 8000, encoding: null}, {payload: 110, codec: telephone-event, rate: 48000, encoding: null}, {payload: 112, codec: telephone-event, rate: 32000, encoding: null}, {payload: 113, codec: telephone-event, rate: 16000, encoding: null}, {payload: 126, codec: telephone-event, rate: 8000, encoding: null}], fmtp: [{payload: 111, config: minptime=10;useinbandfec=1}], type: audio, port: 9, protocol: UDP/TLS/RTP/SAVPF, payloads: 111 103 104 9 0 8 106 105 13 110 112 113 126, connection: {version: 4, ip: 0.0.0.0}, rtcp: {port: 9, netType: IN, ipVer: 4, address: 0.0.0.0}, iceUfrag: xTAe, icePwd: ATHm2EYb8Tr46rQEzXX6X0Mu, iceOptions: trickle, fingerprint: {type: sha-256, hash: 5D:EB:BD:B5:4B:E3:E0:F2:F8:8E:CD:01:49:63:47:FD:9D:10:2D:03:84:B2:F6:B6:1B:A2:EF:36:12:B1:C1:71}, setup: actpass, mid: 0, ext: [{value: 1, direction: null, uri: urn:ietf:params:rtp-hdrext:ssrc-audio-level, config: null}, {value: 2, direction: null, uri: http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time, config: null}, {value: 3, direction: null, uri: http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01, config: null}, {value: 4, direction: null, uri: urn:ietf:params:rtp-hdrext:sdes:mid, config: null}, {value: 5, direction: null, uri: urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id, config: null}, {value: 6, direction: null, uri: urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id, config: null}], direction: sendrecv, msid: - cfd87847-d834-4b11-be64-141e3aedcdf0, rtcpMux: rtcp-mux, rtcpFb: [{payload: 111, type: transport-cc, subtype: null}], ssrcs: [{id: 3993446316, attribute: cname, value: 2vCenoo+cznp2Rdl}, {id: 3993446316, attribute: msid, value: - cfd87847-d834-4b11-be64-141e3aedcdf0}, {id: 3993446316, attribute: mslabel, value: -}, {id: 3993446316, attribute: label, value: cfd87847-d834-4b11-be64-141e3aedcdf0}]}, {rtp: [{payload: 96, codec: VP8, rate: 90000, encoding: null}, {payload: 97, codec: rtx, rate: 90000, encoding: null}, {payload: 98, codec: VP9, rate: 90000, encoding: null}, {payload: 99, codec: rtx, rate: 90000, encoding: null}, {payload: 100, codec: VP9, rate: 90000, encoding: null}, {payload: 101, codec: rtx, rate: 90000, encoding: null}, {payload: 102, codec: H264, rate: 90000, encoding: null}, {payload: 121, codec: rtx, rate: 90000, encoding: null}, {payload: 127, codec: H264, rate: 90000, encoding: null}, {payload: 120, codec: rtx, rate: 90000, encoding: null}, {payload: 125, codec: H264, rate: 90000, encoding: null}, {payload: 107, codec: rtx, rate: 90000, encoding: null}, {payload: 108, codec: H264, rate: 90000, encoding: null}, {payload: 109, codec: rtx, rate: 90000, encoding: null}, {payload: 35, codec: AV1X, rate: 90000, encoding: null}, {payload: 36, codec: rtx, rate: 90000, encoding: null}, {payload: 124, codec: H264, rate: 90000, encoding: null}, {payload: 119, codec: rtx, rate: 90000, encoding: null}, {payload: 123, codec: H264, rate: 90000, encoding: null}, {payload: 118, codec: rtx, rate: 90000, encoding: null}, {payload: 114, codec: red, rate: 90000, encoding: null}, {payload: 115, codec: rtx, rate: 90000, encoding: null}, {payload: 116, codec: ulpfec, rate: 90000, encoding: null}], fmtp: [{payload: 97, config: apt=96}, {payload: 98, config: profile-id=0}, {payload: 99, config: apt=98}, {payload: 100, config: profile-id=2}, {payload: 101, config: apt=100}, {payload: 102, config: level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f}, {payload: 121, config: apt=102}, {payload: 127, config: level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f}, {payload: 120, config: apt=127}, {payload: 125, config: level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f}, {payload: 107, config: apt=125}, {payload: 108, config: level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f}, {payload: 109, config: apt=108}, {payload: 36, config: apt=35}, {payload: 124, config: level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=4d001f}, {payload: 119, config: apt=124}, {payload: 123, config: level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=64001f}, {payload: 118, config: apt=123}, {payload: 115, config: apt=114}], type: video, port: 9, protocol: UDP/TLS/RTP/SAVPF, payloads: 96 97 98 99 100 101 102 121 127 120 125 107 108 109 35 36 124 119 123 118 114 115 116, connection: {version: 4, ip: 0.0.0.0}, rtcp: {port: 9, netType: IN, ipVer: 4, address: 0.0.0.0}, iceUfrag: xTAe, icePwd: ATHm2EYb8Tr46rQEzXX6X0Mu, iceOptions: trickle, fingerprint: {type: sha-256, hash: 5D:EB:BD:B5:4B:E3:E0:F2:F8:8E:CD:01:49:63:47:FD:9D:10:2D:03:84:B2:F6:B6:1B:A2:EF:36:12:B1:C1:71}, setup: actpass, mid: 1, ext: [{value: 14, direction: null, uri: urn:ietf:params:rtp-hdrext:toffset, config: null}, {value: 2, direction: null, uri: http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time, config: null}, {value: 13, direction: null, uri: urn:3gpp:video-orientation, config: null}, {value: 3, direction: null, uri: http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01, config: null}, {value: 12, direction: null, uri: http://www.webrtc.org/experiments/rtp-hdrext/playout-delay, config: null}, {value: 11, direction: null, uri: http://www.webrtc.org/experiments/rtp-hdrext/video-content-type, config: null}, {value: 7, direction: null, uri: http://www.webrtc.org/experiments/rtp-hdrext/video-timing, config: null}, {value: 8, direction: null, uri: http://www.webrtc.org/experiments/rtp-hdrext/color-space, config: null}, {value: 4, direction: null, uri: urn:ietf:params:rtp-hdrext:sdes:mid, config: null}, {value: 5, direction: null, uri: urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id, config: null}, {value: 6, direction: null, uri: urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id, config: null}], direction: sendrecv, msid: - 44eb3510-a237-4884-990f-05adde971299, rtcpMux: rtcp-mux, rtcpRsize: rtcp-rsize, rtcpFb: [{payload: 96, type: goog-remb, subtype: null}, {payload: 96, type: transport-cc, subtype: null}, {payload: 96, type: ccm, subtype: fir}, {payload: 96, type: nack, subtype: null}, {payload: 96, type: nack, subtype: pli}, {payload: 98, type: goog-remb, subtype: null}, {payload: 98, type: transport-cc, subtype: null}, {payload: 98, type: ccm, subtype: fir}, {payload: 98, type: nack, subtype: null}, {payload: 98, type: nack, subtype: pli}, {payload: 100, type: goog-remb, subtype: null}, {payload: 100, type: transport-cc, subtype: null}, {payload: 100, type: ccm, subtype: fir}, {payload: 100, type: nack, subtype: null}, {payload: 100, type: nack, subtype: pli}, {payload: 102, type: goog-remb, subtype: null}, {payload: 102, type: transport-cc, subtype: null}, {payload: 102, type: ccm, subtype: fir}, {payload: 102, type: nack, subtype: null}, {payload: 102, type: nack, subtype: pli}, {payload: 127, type: goog-remb, subtype: null}, {payload: 127, type: transport-cc, subtype: null}, {payload: 127, type: ccm, subtype: fir}, {payload: 127, type: nack, subtype: null}, {payload: 127, type: nack, subtype: pli}, {payload: 125, type: goog-remb, subtype: null}, {payload: 125, type: transport-cc, subtype: null}, {payload: 125, type: ccm, subtype: fir}, {payload: 125, type: nack, subtype: null}, {payload: 125, type: nack, subtype: pli}, {payload: 108, type: goog-remb, subtype: null}, {payload: 108, type: transport-cc, subtype: null}, {payload: 108, type: ccm, subtype: fir}, {payload: 108, type: nack, subtype: null}, {payload: 108, type: nack, subtype: pli}, {payload: 35, type: goog-remb, subtype: null}, {payload: 35, type: transport-cc, subtype: null}, {payload: 35, type: ccm, subtype: fir}, {payload: 35, type: nack, subtype: null}, {payload: 35, type: nack, subtype: pli}, {payload: 124, type: goog-remb, subtype: null}, {payload: 124, type: transport-cc, subtype: null}, {payload: 124, type: ccm, subtype: fir}, {payload: 124, type: nack, subtype: null}, {payload: 124, type: nack, subtype: pli}, {payload: 123, type: goog-remb, subtype: null}, {payload: 123, type: transport-cc, subtype: null}, {payload: 123, type: ccm, subtype: fir}, {payload: 123, type: nack, subtype: null}, {payload: 123, type: nack, subtype: pli}], ssrcGroups: [{semantics: FID, ssrcs: 173842415 11685779}], ssrcs: [{id: 173842415, attribute: cname, value: 2vCenoo+cznp2Rdl}, {id: 173842415, attribute: msid, value: - 44eb3510-a237-4884-990f-05adde971299}, {id: 173842415, attribute: mslabel, value: -}, {id: 173842415, attribute: label, value: 44eb3510-a237-4884-990f-05adde971299}, {id: 11685779, attribute: cname, value: 2vCenoo+cznp2Rdl}, {id: 11685779, attribute: msid, value: - 44eb3510-a237-4884-990f-05adde971299}, {id: 11685779, attribute: mslabel, value: -}, {id: 11685779, attribute: label, value: 44eb3510-a237-4884-990f-05adde971299}]}]} mediasoup-client:Device load() | got native RTP capabilities:Instance of 'RtpCapabilities' generateProfileLevelIdForAnswer() | result: [profile:1, level:31 mediasoup-client:Device load() | got extended RTP capabilities:Instance of 'ExtendedRtpCapabilities' mediasoup-client:Device load() | got receiving RTP capabilities:Instance of 'RtpCapabilities' mediasoup-client:Browser getNativeSctpCapabilities() mediasoup-client:Device load() | got native SCTP capabilities:Instance of 'SctpCapabilities' mediasoup-client:Device load() successed mediasoup-client:Browser close() _producetrue [Peer] DEBUG: request() [method:createWebRtcTransport, id: 5994437] mediasoup-client:Device createSendTransport() mediasoup-client:Transport constructor() [id:a651c9da-bb61-48d3-b29a-6dcd4bd3531c, direction:send] mediasoup-client:Browser run() [Peer] DEBUG: request() [method:createWebRtcTransport, id: 9408153] Error: Expected a value of type 'Map<String, dynamic>?', but got one of type 'LinkedMap<dynamic, dynamic>' at Object.throw_ [as throw] (http://localhost:49971/dart_sdk.js:5334:11) at Object.castError (http://localhost:49971/dart_sdk.js:5305:15) at Object.cast [as as] (http://localhost:49971/dart_sdk.js:5621:17) at dart.NullableType.new.as (http://localhost:49971/dart_sdk.js:7182:60) at Browser.Browser.new.run (http://localhost:49971/packages/mediasoup_client_flutter/src/handlers/sdp/PlanBUtils.dart.lib.js:4816:40) at run.next (<anonymous>) at runBody (http://localhost:49971/dart_sdk.js:39052:34) at Object._async [as async] (http://localhost:49971/dart_sdk.js:39083:7) at Browser.Browser.new.run (http://localhost:49971/packages/mediasoup_client_flutter/src/handlers/sdp/PlanBUtils.dart.lib.js:4794:20) at new Transport.Transport.new (http://localhost:49971/packages/mediasoup_client_flutter/src/handlers/sdp/PlanBUtils.dart.lib.js:6931:20) at Device.Device.new.[_createTransport] (http://localhost:49971/packages/mediasoup_client_flutter/src/Device.dart.lib.js:159:23) at Device.Device.new.createSendTransport (http://localhost:49971/packages/mediasoup_client_flutter/src/Device.dart.lib.js:180:36) at Device.Device.new.createSendTransportFromMap (http://localhost:49971/packages/mediasoup_client_flutter/src/Device.dart.lib.js:185:19) at room_client.RoomClient.new._joinRoom (http://localhost:49971/packages/example/room_client.dart.lib.js:194:59) at _joinRoom.next (<anonymous>) at http://localhost:49971/dart_sdk.js:39032:33 at _RootZone.runUnary (http://localhost:49971/dart_sdk.js:38889:58) at _FutureListener.thenAwait.handleValue (http://localhost:49971/dart_sdk.js:33875:29) at handleValueCallback (http://localhost:49971/dart_sdk.js:34435:49) at Function._propagateToListeners (http://localhost:49971/dart_sdk.js:34473:17) at _Future.new.[_completeWithValue] (http://localhost:49971/dart_sdk.js:34315:23) at async._AsyncCallbackEntry.new.callback (http://localhost:49971/dart_sdk.js:34338:35) at Object._microtaskLoop (http://localhost:49971/dart_sdk.js:39176:13) at _startMicrotaskLoop (http://localhost:49971/dart_sdk.js:39182:13) at http://localhost:49971/dart_sdk.js:34689:9 mediasoup-client:Device createRecvTransport() mediasoup-client:Transport constructor() [id:d1f2a362-8fc1-471e-8740-25ff9ec5e427, direction:recv] mediasoup-client:Browser run() [Peer] DEBUG: request() [method:join, id: 793603] newConsumer request failed: Expected a value of type 'String', but got one of type 'int' newConsumer request failed: Expected a value of type 'String', but got one of type 'int' Error: Expected a value of type 'String', but got one of type 'int' at Object.throw_ [as throw] (http://localhost:49971/dart_sdk.js:5334:11) at room_client.RoomClient.new.<anonymous> (http://localhost:49971/packages/example/room_client.dart.lib.js:288:27) at Generator.next (<anonymous>) at runBody (http://localhost:49971/dart_sdk.js:39052:34) at Object._async [as async] (http://localhost:49971/dart_sdk.js:39083:7) at web_socket.WebSocket.new.<anonymous> (http://localhost:49971/packages/example/room_client.dart.lib.js:274:79) at http://localhost:49971/packages/example/web_socket.dart.lib.js:130:19 at Object._checkAndCall (http://localhost:49971/dart_sdk.js:5544:16) at Object.dcall (http://localhost:49971/dart_sdk.js:5549:17) at peer.Peer.new.callback (http://localhost:49971/packages/events2/src/event_emitter.dart.lib.js:99:18) at http://localhost:49971/packages/events2/src/event_emitter.dart.lib.js:186:14 at Array.[dartx.forEach] (http://localhost:49971/dart_sdk.js:15666:11) at peer.Peer.new.emit (http://localhost:49971/packages/events2/src/event_emitter.dart.lib.js:184:50) at peer.Peer.new.[_handleRequest] (http://localhost:49971/packages/protoo_client/src/peer.dart.lib.js:164:14) at http://localhost:49971/packages/protoo_client/src/peer.dart.lib.js:154:31 at Object._checkAndCall (http://localhost:49971/dart_sdk.js:5544:16) at Object.dcall (http://localhost:49971/dart_sdk.js:5549:17) at WebTransport.Transport.new.callback (http://localhost:49971/packages/events2/src/event_emitter.dart.lib.js:89:18) at http://localhost:49971/packages/events2/src/event_emitter.dart.lib.js:186:14 at Array.[dartx.forEach] (http://localhost:49971/dart_sdk.js:15666:11) at WebTransport.Transport.new.emit (http://localhost:49971/packages/events2/src/event_emitter.dart.lib.js:184:50) at WebTransport.Transport.new.safeEmit (http://localhost:49971/packages/protoo_client/src/EnhancedEventEmitter.dart.lib.js:31:14) at http://localhost:49971/packages/protoo_client/src/transports/WebTransport.dart.lib.js:89:14 at Object._checkAndCall (http://localhost:49971/dart_sdk.js:5544:16) at Object.dcall (http://localhost:49971/dart_sdk.js:5549:17) at WebSocket.<anonymous> (http://localhost:49971/dart_sdk.js:105416:21) Error: Expected a value of type 'String', but got one of type 'int' at Object.throw_ [as throw] (http://localhost:49971/dart_sdk.js:5334:11) at room_client.RoomClient.new.<anonymous> (http://localhost:49971/packages/example/room_client.dart.lib.js:305:27) at Generator.next (<anonymous>) at runBody (http://localhost:49971/dart_sdk.js:39052:34) at Object._async [as async] (http://localhost:49971/dart_sdk.js:39083:7) at web_socket.WebSocket.new.<anonymous> (http://localhost:49971/packages/example/room_client.dart.lib.js:274:79) at http://localhost:49971/packages/example/web_socket.dart.lib.js:130:19 at Object._checkAndCall (http://localhost:49971/dart_sdk.js:5544:16) at Object.dcall (http://localhost:49971/dart_sdk.js:5549:17) at peer.Peer.new.callback (http://localhost:49971/packages/events2/src/event_emitter.dart.lib.js:99:18) at http://localhost:49971/packages/events2/src/event_emitter.dart.lib.js:186:14 at Array.[dartx.forEach] (http://localhost:49971/dart_sdk.js:15666:11) at peer.Peer.new.emit (http://localhost:49971/packages/events2/src/event_emitter.dart.lib.js:184:50) at peer.Peer.new.[_handleRequest] (http://localhost:49971/packages/protoo_client/src/peer.dart.lib.js:164:14) at http://localhost:49971/packages/protoo_client/src/peer.dart.lib.js:154:31 at Object._checkAndCall (http://localhost:49971/dart_sdk.js:5544:16) at Object.dcall (http://localhost:49971/dart_sdk.js:5549:17) at WebTransport.Transport.new.callback (http://localhost:49971/packages/events2/src/event_emitter.dart.lib.js:89:18) at http://localhost:49971/packages/events2/src/event_emitter.dart.lib.js:186:14 at Array.[dartx.forEach] (http://localhost:49971/dart_sdk.js:15666:11) at WebTransport.Transport.new.emit (http://localhost:49971/packages/events2/src/event_emitter.dart.lib.js:184:50) at WebTransport.Transport.new.safeEmit (http://localhost:49971/packages/protoo_client/src/EnhancedEventEmitter.dart.lib.js:31:14) at http://localhost:49971/packages/protoo_client/src/transports/WebTransport.dart.lib.js:89:14 at Object._checkAndCall (http://localhost:49971/dart_sdk.js:5544:16) at Object.dcall (http://localhost:49971/dart_sdk.js:5549:17) at WebSocket.<anonymous> (http://localhost:49971/dart_sdk.js:105416:21) mediasoup-client:Transport produce() [track:Track(id: f657b080-7bcd-4c50-a6a3-87cc1fd7931f, kind: audio, label: Default - Microphone (4- USB2.0 MIC) (1908:2310), enabled: true, muted: false) transport.produce() mediasoup-client:Browser send() [kind:audio, tack.id:f657b080-7bcd-4c50-a6a3-87cc1fd7931f Error: NoSuchMethodError: 'errorCallbackFun' Dynamic call of null. Receiver: Instance of 'FlexTaskAdd' Arguments: [Instance of 'IndexError'] at Object.throw_ [as throw] (http://localhost:49971/dart_sdk.js:5334:11) at Object.defaultNoSuchMethod (http://localhost:49971/dart_sdk.js:5779:15) at FlexQueue.FlexTaskAdd.new.noSuchMethod (http://localhost:49971/dart_sdk.js:6879:19) at Object.noSuchMethod (http://localhost:49971/dart_sdk.js:5775:30) at callNSM (http://localhost:49971/dart_sdk.js:5507:19) at Object._checkAndCall (http://localhost:49971/dart_sdk.js:5509:27) at Object.callMethod (http://localhost:49971/dart_sdk.js:5587:17) at Object.dsend (http://localhost:49971/dart_sdk.js:5590:17) at FlexQueue.FlexQueue.new._runTask$ (http://localhost:49971/packages/mediasoup_client_flutter/src/FlexQueue/FlexQueue.dart.lib.js:189:68) at _runTask$.throw (<anonymous>) at http://localhost:49971/dart_sdk.js:39038:38 at _RootZone.runBinary (http://localhost:49971/dart_sdk.js:38894:58) at _FutureListener.thenAwait.handleError (http://localhost:49971/dart_sdk.js:33887:48) at handleError (http://localhost:49971/dart_sdk.js:34451:51) at Function._propagateToListeners (http://localhost:49971/dart_sdk.js:34477:17) at _Future.new.[_completeError] (http://localhost:49971/dart_sdk.js:34323:23) at async._AsyncCallbackEntry.new.callback (http://localhost:49971/dart_sdk.js:34362:31) at Object._microtaskLoop (http://localhost:49971/dart_sdk.js:39176:13) at _startMicrotaskLoop (http://localhost:49971/dart_sdk.js:39182:13) at http://localhost:49971/dart_sdk.js:34689:9 newConsumer request failed: Expected a value of type 'String', but got one of type 'int' Error: Expected a value of type 'String', but got one of type 'int' at Object.throw_ [as throw] (http://localhost:49971/dart_sdk.js:5334:11) at room_client.RoomClient.new.<anonymous> (http://localhost:49971/packages/example/room_client.dart.lib.js:305:27) at Generator.next (<anonymous>) at runBody (http://localhost:49971/dart_sdk.js:39052:34) at Object._async [as async] (http://localhost:49971/dart_sdk.js:39083:7) at web_socket.WebSocket.new.<anonymous> (http://localhost:49971/packages/example/room_client.dart.lib.js:274:79) at http://localhost:49971/packages/example/web_socket.dart.lib.js:130:19 at Object._checkAndCall (http://localhost:49971/dart_sdk.js:5544:16) at Object.dcall (http://localhost:49971/dart_sdk.js:5549:17) at peer.Peer.new.callback (http://localhost:49971/packages/events2/src/event_emitter.dart.lib.js:99:18) at http://localhost:49971/packages/events2/src/event_emitter.dart.lib.js:186:14 at Array.[dartx.forEach] (http://localhost:49971/dart_sdk.js:15666:11) at peer.Peer.new.emit (http://localhost:49971/packages/events2/src/event_emitter.dart.lib.js:184:50) at peer.Peer.new.[_handleRequest] (http://localhost:49971/packages/protoo_client/src/peer.dart.lib.js:164:14) at http://localhost:49971/packages/protoo_client/src/peer.dart.lib.js:154:31 at Object._checkAndCall (http://localhost:49971/dart_sdk.js:5544:16) at Object.dcall (http://localhost:49971/dart_sdk.js:5549:17) at WebTransport.Transport.new.callback (http://localhost:49971/packages/events2/src/event_emitter.dart.lib.js:89:18) at http://localhost:49971/packages/events2/src/event_emitter.dart.lib.js:186:14 at Array.[dartx.forEach] (http://localhost:49971/dart_sdk.js:15666:11) at WebTransport.Transport.new.emit (http://localhost:49971/packages/events2/src/event_emitter.dart.lib.js:184:50) at WebTransport.Transport.new.safeEmit (http://localhost:49971/packages/protoo_client/src/EnhancedEventEmitter.dart.lib.js:31:14) at http://localhost:49971/packages/protoo_client/src/transports/WebTransport.dart.lib.js:89:14 at Object._checkAndCall (http://localhost:49971/dart_sdk.js:5544:16) at Object.dcall (http://localhost:49971/dart_sdk.js:5549:17) at WebSocket.<anonymous> (http://localhost:49971/dart_sdk.js:105416:21)
I am testing it with demo mediasoup server. It connected successfully but no sound and video :
image_2021_05_17T09_09_35_269Z

Flutter screen :
image_2021_05_17T09_09_22_760Z

Example not working properly on web

I tried the example and it Works fine on android. In web I can see the connected users streams but can't produce video or audio. When I join a room the console shows:
InvalidAccessError: Failed to execute 'addTrack' on 'RTCPeerConnection': A sender already exists for the track.

[Logger::WebTransport] DEBUG: constructor() [url:wss://v3demo.mediasoup.org:4443/?roomId=ikogsiaz&peerId=nIKHVQdX, options:null]
[Peer] DEBUG: constructor()
[Logger::WebTransport] DEBUG: onOpen
[Peer] DEBUG: emit "open"
[Peer] DEBUG: request() [method:getRouterRtpCapabilities, id: 1111734]
{codecs: [{kind: audio, mimeType: audio/opus, clockRate: 48000, channels: 2, rtcpFeedback: [{type: transport-cc, parameter: }], parameters: {useinbandfec: 1, stereo: 1}, preferredPayloadType: 100}, {kind: video, mimeType: video/VP8, clockRate: 90000, rtcpFeedback: [{type: nack, parameter: }, {type: nack, parameter: pli}, {type: ccm, parameter: fir}, {type: goog-remb, parameter: }, {type: transport-cc, parameter: }], parameters: {x-google-start-bitrate: 1500}, preferredPayloadType: 101}, {kind: video, mimeType: video/rtx, preferredPayloadType: 102, clockRate: 90000, parameters: {apt: 101}, rtcpFeedback: []}, {kind: video, mimeType: video/H264, clockRate: 90000, parameters: {packetization-mode: 1, level-asymmetry-allowed: 1, profile-level-id: 42e032}, rtcpFeedback: [{type: nack, parameter: }, {type: nack, parameter: pli}, {type: ccm, parameter: fir}, {type: goog-remb, parameter: }, {type: transport-cc, parameter: }], preferredPayloadType: 103}, {kind: video, mimeType: video/rtx, preferredPayloadType: 104, clockRate: 90000, parameters: {apt: 103}, rtcpFeedback: []}, {kind: video, mimeType: video/VP9, clockRate: 90000, rtcpFeedback: [{type: nack, parameter: }, {type: nack, parameter: pli}, {type: ccm, parameter: fir}, {type: goog-remb, parameter: }, {type: transport-cc, parameter: }], parameters: {x-google-start-bitrate: 1500}, preferredPayloadType: 105}, {kind: video, mimeType: video/rtx, preferredPayloadType: 106, clockRate: 90000, parameters: {apt: 105}, rtcpFeedback: []}], headerExtensions: [{kind: audio, uri: urn:ietf:params:rtp-hdrext:sdes:mid, preferredId: 1, preferredEncrypt: false, direction: sendrecv}, {kind: video, uri: urn:ietf:params:rtp-hdrext:sdes:mid, preferredId: 1, preferredEncrypt: false, direction: sendrecv}, {kind: video, uri: urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id, preferredId: 2, preferredEncrypt: false, direction: recvonly}, {kind: video, uri: urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id, preferredId: 3, preferredEncrypt: false, direction: recvonly}, {kind: audio, uri: http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time, preferredId: 4, preferredEncrypt: false, direction: sendrecv}, {kind: video, uri: http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time, preferredId: 4, preferredEncrypt: false, direction: sendrecv}, {kind: audio, uri: http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01, preferredId: 5, preferredEncrypt: false, direction: recvonly}, {kind: video, uri: http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01, preferredId: 5, preferredEncrypt: false, direction: sendrecv}, {kind: video, uri: http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07, preferredId: 6, preferredEncrypt: false, direction: sendrecv}, {kind: video, uri: urn:ietf:params:rtp-hdrext:framemarking, preferredId: 7, preferredEncrypt: false, direction: sendrecv}, {kind: audio, uri: urn:ietf:params:rtp-hdrext:ssrc-audio-level, preferredId: 10, preferredEncrypt: false, direction: sendrecv}, {kind: video, uri: urn:3gpp:video-orientation, preferredId: 11, preferredEncrypt: false, direction: sendrecv}, {kind: video, uri: urn:ietf:params:rtp-hdrext:toffset, preferredId: 12, preferredEncrypt: false, direction: sendrecv}]}
mediasoup-client:Device load() [routerRtpCapabilities:Instance of 'RtpCapabilities']
mediasoup-client:Browser getNativeRtpCapabilities()
parsed: {version: 0, origin: {username: -, sessionId: 4496350646539198500, sessionVersion: 2, netType: IN, ipVer: 4, address: 127.0.0.1}, name: -, timing: {start: 0, stop: 0}, groups: [{type: BUNDLE, mids: 0 1}], extmapAllowMixed: [{extmap-allow-mixed: extmap-allow-mixed}], msidSemantic: {semantic: WMS, token: }, media: [{rtp: [{payload: 111, codec: opus, rate: 48000, encoding: 2}, {payload: 103, codec: ISAC, rate: 16000, encoding: null}, {payload: 104, codec: ISAC, rate: 32000, encoding: null}, {payload: 9, codec: G722, rate: 8000, encoding: null}, {payload: 0, codec: PCMU, rate: 8000, encoding: null}, {payload: 8, codec: PCMA, rate: 8000, encoding: null}, {payload: 106, codec: CN, rate: 32000, encoding: null}, {payload: 105, codec: CN, rate: 16000, encoding: null}, {payload: 13, codec: CN, rate: 8000, encoding: null}, {payload: 110, codec: telephone-event, rate: 48000, encoding: null}, {payload: 112, codec: telephone-event, rate: 32000, encoding: null}, {payload: 113, codec: telephone-event, rate: 16000, encoding: null}, {payload: 126, codec: telephone-event, rate: 8000, encoding: null}], fmtp: [{payload: 111, config: minptime=10;useinbandfec=1}], type: audio, port: 9, protocol: UDP/TLS/RTP/SAVPF, payloads: 111 103 104 9 0 8 106 105 13 110 112 113 126, connection: {version: 4, ip: 0.0.0.0}, rtcp: {port: 9, netType: IN, ipVer: 4, address: 0.0.0.0}, iceUfrag: 8Wwe, icePwd: 3pXMpoVw04FH8u6ABnEvGmkk, iceOptions: trickle, fingerprint: {type: sha-256, hash: 16:FF:B8:95:DF:47:16:1C:D3:E1:C2:AE:63:7F:EF:D5:48:CB:01:EE:0A:E6:9F:FA:59:8E:F9:DB:1F:C9:F9:6A}, setup: actpass, mid: 0, ext: [{value: 1, direction: null, uri: urn:ietf:params:rtp-hdrext:ssrc-audio-level, config: null}, {value: 2, direction: null, uri: http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time, config: null}, {value: 3, direction: null, uri: http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01, config: null}, {value: 4, direction: null, uri: urn:ietf:params:rtp-hdrext:sdes:mid, config: null}, {value: 5, direction: null, uri: urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id, config: null}, {value: 6, direction: null, uri: urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id, config: null}], direction: sendrecv, msid: - dcd479bf-0013-47d6-8235-c3fe487ae36b, rtcpMux: rtcp-mux, rtcpFb: [{payload: 111, type: transport-cc, subtype: null}], ssrcs: [{id: 169880542, attribute: cname, value: P7ucPSJoLAkEIeXB}, {id: 169880542, attribute: msid, value: - dcd479bf-0013-47d6-8235-c3fe487ae36b}, {id: 169880542, attribute: mslabel, value: -}, {id: 169880542, attribute: label, value: dcd479bf-0013-47d6-8235-c3fe487ae36b}]}, {rtp: [{payload: 96, codec: VP8, rate: 90000, encoding: null}, {payload: 97, codec: rtx, rate: 90000, encoding: null}, {payload: 98, codec: VP9, rate: 90000, encoding: null}, {payload: 99, codec: rtx, rate: 90000, encoding: null}, {payload: 100, codec: VP9, rate: 90000, encoding: null}, {payload: 101, codec: rtx, rate: 90000, encoding: null}, {payload: 102, codec: H264, rate: 90000, encoding: null}, {payload: 121, codec: rtx, rate: 90000, encoding: null}, {payload: 127, codec: H264, rate: 90000, encoding: null}, {payload: 120, codec: rtx, rate: 90000, encoding: null}, {payload: 125, codec: H264, rate: 90000, encoding: null}, {payload: 107, codec: rtx, rate: 90000, encoding: null}, {payload: 108, codec: H264, rate: 90000, encoding: null}, {payload: 109, codec: rtx, rate: 90000, encoding: null}, {payload: 35, codec: AV1X, rate: 90000, encoding: null}, {payload: 36, codec: rtx, rate: 90000, encoding: null}, {payload: 124, codec: H264, rate: 90000, encoding: null}, {payload: 119, codec: rtx, rate: 90000, encoding: null}, {payload: 123, codec: H264, rate: 90000, encoding: null}, {payload: 118, codec: rtx, rate: 90000, encoding: null}, {payload: 114, codec: red, rate: 90000, encoding: null}, {payload: 115, codec: rtx, rate: 90000, encoding: null}, {payload: 116, codec: ulpfec, rate: 90000, encoding: null}], fmtp: [{payload: 97, config: apt=96}, {payload: 98, config: profile-id=0}, {payload: 99, config: apt=98}, {payload: 100, config: profile-id=2}, {payload: 101, config: apt=100}, {payload: 102, config: level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f}, {payload: 121, config: apt=102}, {payload: 127, config: level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f}, {payload: 120, config: apt=127}, {payload: 125, config: level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f}, {payload: 107, config: apt=125}, {payload: 108, config: level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f}, {payload: 109, config: apt=108}, {payload: 36, config: apt=35}, {payload: 124, config: level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=4d001f}, {payload: 119, config: apt=124}, {payload: 123, config: level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=64001f}, {payload: 118, config: apt=123}, {payload: 115, config: apt=114}], type: video, port: 9, protocol: UDP/TLS/RTP/SAVPF, payloads: 96 97 98 99 100 101 102 121 127 120 125 107 108 109 35 36 124 119 123 118 114 115 116, connection: {version: 4, ip: 0.0.0.0}, rtcp: {port: 9, netType: IN, ipVer: 4, address: 0.0.0.0}, iceUfrag: 8Wwe, icePwd: 3pXMpoVw04FH8u6ABnEvGmkk, iceOptions: trickle, fingerprint: {type: sha-256, hash: 16:FF:B8:95:DF:47:16:1C:D3:E1:C2:AE:63:7F:EF:D5:48:CB:01:EE:0A:E6:9F:FA:59:8E:F9:DB:1F:C9:F9:6A}, setup: actpass, mid: 1, ext: [{value: 14, direction: null, uri: urn:ietf:params:rtp-hdrext:toffset, config: null}, {value: 2, direction: null, uri: http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time, config: null}, {value: 13, direction: null, uri: urn:3gpp:video-orientation, config: null}, {value: 3, direction: null, uri: http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01, config: null}, {value: 12, direction: null, uri: http://www.webrtc.org/experiments/rtp-hdrext/playout-delay, config: null}, {value: 11, direction: null, uri: http://www.webrtc.org/experiments/rtp-hdrext/video-content-type, config: null}, {value: 7, direction: null, uri: http://www.webrtc.org/experiments/rtp-hdrext/video-timing, config: null}, {value: 8, direction: null, uri: http://www.webrtc.org/experiments/rtp-hdrext/color-space, config: null}, {value: 4, direction: null, uri: urn:ietf:params:rtp-hdrext:sdes:mid, config: null}, {value: 5, direction: null, uri: urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id, config: null}, {value: 6, direction: null, uri: urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id, config: null}], direction: sendrecv, msid: - bb36a3c7-c326-47dc-8575-3e14b0bbf904, rtcpMux: rtcp-mux, rtcpRsize: rtcp-rsize, rtcpFb: [{payload: 96, type: goog-remb, subtype: null}, {payload: 96, type: transport-cc, subtype: null}, {payload: 96, type: ccm, subtype: fir}, {payload: 96, type: nack, subtype: null}, {payload: 96, type: nack, subtype: pli}, {payload: 98, type: goog-remb, subtype: null}, {payload: 98, type: transport-cc, subtype: null}, {payload: 98, type: ccm, subtype: fir}, {payload: 98, type: nack, subtype: null}, {payload: 98, type: nack, subtype: pli}, {payload: 100, type: goog-remb, subtype: null}, {payload: 100, type: transport-cc, subtype: null}, {payload: 100, type: ccm, subtype: fir}, {payload: 100, type: nack, subtype: null}, {payload: 100, type: nack, subtype: pli}, {payload: 102, type: goog-remb, subtype: null}, {payload: 102, type: transport-cc, subtype: null}, {payload: 102, type: ccm, subtype: fir}, {payload: 102, type: nack, subtype: null}, {payload: 102, type: nack, subtype: pli}, {payload: 127, type: goog-remb, subtype: null}, {payload: 127, type: transport-cc, subtype: null}, {payload: 127, type: ccm, subtype: fir}, {payload: 127, type: nack, subtype: null}, {payload: 127, type: nack, subtype: pli}, {payload: 125, type: goog-remb, subtype: null}, {payload: 125, type: transport-cc, subtype: null}, {payload: 125, type: ccm, subtype: fir}, {payload: 125, type: nack, subtype: null}, {payload: 125, type: nack, subtype: pli}, {payload: 108, type: goog-remb, subtype: null}, {payload: 108, type: transport-cc, subtype: null}, {payload: 108, type: ccm, subtype: fir}, {payload: 108, type: nack, subtype: null}, {payload: 108, type: nack, subtype: pli}, {payload: 35, type: goog-remb, subtype: null}, {payload: 35, type: transport-cc, subtype: null}, {payload: 35, type: ccm, subtype: fir}, {payload: 35, type: nack, subtype: null}, {payload: 35, type: nack, subtype: pli}, {payload: 124, type: goog-remb, subtype: null}, {payload: 124, type: transport-cc, subtype: null}, {payload: 124, type: ccm, subtype: fir}, {payload: 124, type: nack, subtype: null}, {payload: 124, type: nack, subtype: pli}, {payload: 123, type: goog-remb, subtype: null}, {payload: 123, type: transport-cc, subtype: null}, {payload: 123, type: ccm, subtype: fir}, {payload: 123, type: nack, subtype: null}, {payload: 123, type: nack, subtype: pli}], ssrcGroups: [{semantics: FID, ssrcs: 985860932 3606149658}], ssrcs: [{id: 985860932, attribute: cname, value: P7ucPSJoLAkEIeXB}, {id: 985860932, attribute: msid, value: - bb36a3c7-c326-47dc-8575-3e14b0bbf904}, {id: 985860932, attribute: mslabel, value: -}, {id: 985860932, attribute: label, value: bb36a3c7-c326-47dc-8575-3e14b0bbf904}, {id: 3606149658, attribute: cname, value: P7ucPSJoLAkEIeXB}, {id: 3606149658, attribute: msid, value: - bb36a3c7-c326-47dc-8575-3e14b0bbf904}, {id: 3606149658, attribute: mslabel, value: -}, {id: 3606149658, attribute: label, value: bb36a3c7-c326-47dc-8575-3e14b0bbf904}]}]}
mediasoup-client:Device load() | got native RTP capabilities:Instance of 'RtpCapabilities'
generateProfileLevelIdForAnswer() | result: [profile:1, level:31
mediasoup-client:Device load() | got extended RTP capabilities:Instance of 'ExtendedRtpCapabilities'
mediasoup-client:Device load() | got receiving RTP capabilities:Instance of 'RtpCapabilities'
mediasoup-client:Browser getNativeSctpCapabilities()
mediasoup-client:Device load() | got native SCTP capabilities:Instance of 'SctpCapabilities'
mediasoup-client:Device load() successed
mediasoup-client:Browser close()
[Peer] DEBUG: request() [method:createWebRtcTransport, id: 3438750]
mediasoup-client:Device createSendTransport()
mediasoup-client:Transport constructor() [id:ddd1ca47-a15b-4edb-955d-c3285ff921bf, direction:send]
mediasoup-client:Browser run()
[Peer] DEBUG: request() [method:createWebRtcTransport, id: 1440835]
mediasoup-client:Device createRecvTransport()
mediasoup-client:Transport constructor() [id:9654281b-cf5e-4043-8e50-657553ba2a07, direction:recv]
mediasoup-client:Browser run()
[Peer] DEBUG: request() [method:join, id: 5993620]
mediasoup-client:Transport produce() [track:Track(id: 07f54d07-48d8-4b75-8a57-db63ddad03fb, kind: audio, label: Default - Microphone Array (Intel® Smart Sound Technology (Intel® SST)), enabled: true, muted: false)
mediasoup-client:Browser send() [kind:audio, tack.id:07f54d07-48d8-4b75-8a57-db63ddad03fb
InvalidAccessError: Failed to execute 'addTrack' on 'RTCPeerConnection': A sender already exists for the track.
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/html/dart2js/html_dart2js.dart 26949:48                 addTrack]
packages/flutter_webrtc/src/web/rtc_peerconnection_impl.dart 330:24                                               addTrack
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 84:54   runBody
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 123:5   _async
packages/flutter_webrtc/src/web/rtc_peerconnection_impl.dart 326:32                                               addTrack
packages/mediasoup_client_flutter/src/handlers/browser.dart 525:11                                                send
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 45:50   <fn>
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/zone.dart 1613:54                                 runUnary
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 155:18                           handleValue
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 707:44                           handleValueCallback
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 736:13                           _propagateToListeners
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 542:5                            [_completeWithValue]
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 580:7                            callback
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/schedule_microtask.dart 40:11                     _microtaskLoop
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/schedule_microtask.dart 49:5                      _startMicrotaskLoop
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 166:15  <fn>
mediasoup-client:Transport produce() [track:Track(id: c2c5a9f1-76f8-4c31-a29d-552391078dd3, kind: video, label: HP Wide Vision HD Camera (04ca:707f), enabled: true, muted: false)
mediasoup-client:Browser send() [kind:video, tack.id:c2c5a9f1-76f8-4c31-a29d-552391078dd3
InvalidAccessError: Failed to execute 'addTrack' on 'RTCPeerConnection': A sender already exists for the track.
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/html/dart2js/html_dart2js.dart 26949:48                 addTrack]
packages/flutter_webrtc/src/web/rtc_peerconnection_impl.dart 330:24                                               addTrack
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 84:54   runBody
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 123:5   _async
packages/flutter_webrtc/src/web/rtc_peerconnection_impl.dart 326:32                                               addTrack
packages/mediasoup_client_flutter/src/handlers/browser.dart 525:11                                                send
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 45:50   <fn>
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/zone.dart 1613:54                                 runUnary
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 155:18                           handleValue
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 707:44                           handleValueCallback
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 736:13                           _propagateToListeners
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 542:5                            [_completeWithValue]
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 580:7                            callback
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/schedule_microtask.dart 40:11                     _microtaskLoop
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/schedule_microtask.dart 49:5                      _startMicrotaskLoop
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 166:15  <fn>

How do we switch video/audio streams?

I'm disabling and re-enabling the stream

Calling producer close, then converting the transport to producer again with a new stream.

The other device seems to get the original stream, but when switching it becomes a grey screen.

I have also tried re-initializing the WebRTC render and consumers, no luck.

Can't seem to find it in the example (Provider would be better than Bloc 🙈)

Future<void> enableWebcam(BuildContext context) async {
  try {
    if (kDebugMode) {
      print("!--- enableWebcam");
    }

    RtpCodecCapability? codec;
    if (isWeb) {
      codec = device!.rtpCapabilities.codecs.where((element) => element.mimeType.contains("VP9")).toList()[0];
    } else {
      codec = device!.rtpCapabilities.codecs.where((element) => element.mimeType.contains("VP8")).toList()[0];
    }

    if (videoStream != null && sendTransport != null) {
      final self = rtcPeerProviderRead(context).selfPeer;
      await closeProducer(
        context,
        producerId: self.connections.producer!.id,
      );
    }

    videoStream = await createVideoStream(context);
    final track = videoStream!.getVideoTracks().first;

    // List what the device supports
    sendTransport!.produce(
      track: track,
      codecOptions: ProducerCodecOptions(
        videoGoogleStartBitrate: 1000,
      ),
      encodings: kIsWeb
          ? [
              RtpEncodingParameters(scalabilityMode: 'S3T3_KEY', scaleResolutionDownBy: 1.0),
            ]
          : [],
      stream: videoStream!,
      appData: {
        'source': 'webcam',
        'transportId': sendTransport!.id,
      },
      source: 'webcam',
      codec: codec,
    );
  } catch (e) {
    if (kDebugMode) {
      print("!--- Event: Failed to enable webcam");
      print(e);
    }
  }
}

Consume through socket.io

hi @Blancduman,

Thank you for mediasoup_client_flutter implementation. I have implemented the same but with socket.io rather than protoo.
I am able to produce video on the server but unable to consume stream. I am able to get consumer object and passed them through onConsumer(consumer) to renderer RTCVideoView. Can you please explain what are you doing on accept({}) that plays that video in RTCVideoView?

thank you

RTCPeerConnection.getRemoteStreams deprecated and not work in safari > 11

Hello, @Blancduman!

When I use web version of my app in safari browser and connect from other device, safari inspector throws an error:
NoSuchMethodError: method not found: 'getRemoteStreams' (s.getRemoteStreams is not a function. (In 's.getRemoteStreams()', 's.getRemoteStreams' is undefined)) a8f — main.dart.js:26852:82

This is most likely due to

final MediaStream? stream = _pc!
.getRemoteStreams()
.firstWhereOrNull((e) => e?.id == options.rtpParameters.rtcp!.cname);

WebRTC api notes that is deprecated method.

Any ideas how to get the stream in another way? I'm trying to use WebRTC createLocalMediaStream, but have no sound from peers

not working in IOS

Hello, I have two devices, �first is an android Samsung note 9, seccond is an iPhone 7 plus.
mediasoup-client-flutter works very well in android but it can't access to use camera (both front and back) for local stream in iPhone 7 plus.

iPhone 7+ - IOS 14.3

flutter doctor

[✓] Flutter (Channel stable, 2.5.2, on Mac OS X 10.15.7 19H15 darwin-x64, locale en-VN)
[!] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    ✗ cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[✓] Android Studio (version 4.1)
[✓] Android Studio (version 4.1)
[✓] IntelliJ IDEA Ultimate Edition (version 2021.2.1)
[✓] VS Code (version 1.61.2)
[✓] Connected device (2 available)

hope you can help me soon ✌️

Where can i get the file 'package:my_project/my_signaling.dart' file?

I am a beginner in dart programming language & I am struggling to understand what the code should look like.
Can someone help me to locate the 'package:my_project/my_signaling.dart' file and also can someone let me know the definition of the below request method?
final Map<String, dynamic> routerRtpCapabilities = await mySignaling.request('getRouterCapabilities');

Why does the process increase after each call?

flutter_e 2737 u0_a58 159u 0000 0,9 0t0 7172 anon_inode:[eventfd]
flutter_e 2737 u0_a58 160u 0000 0,9 0t0 7172 anon_inode:[eventpoll]
flutter_e 2737 u0_a58 161u 0000 0,9 0t0 7172 anon_inode:[eventfd]
flutter_e 2737 u0_a58 162u 0000 0,9 0t0 7172 anon_inode:[eventpoll]
flutter_e 2737 u0_a58 163u 0000 0,9 0t0 7172 anon_inode:[eventfd]
flutter_e 2737 u0_a58 164u 0000 0,9 0t0 7172 anon_inode:[eventpoll]
flutter_e 2737 u0_a58 165u 0000 0,9 0t0 7172 anon_inode:[eventfd]
flutter_e 2737 u0_a58 166u 0000 0,9 0t0 7172 anon_inode:[eventpoll]
flutter_e 2737 u0_a58 167u 0000 0,9 0t0 7172 anon_inode:[eventfd]
flutter_e 2737 u0_a58 168u 0000 0,9 0t0 7172 anon_inode:[eventpoll]
flutter_e 2737 u0_a58 169u 0000 0,9 0t0 7172 anon_inode:[eventfd]
flutter_e 2737 u0_a58 170u 0000 0,9 0t0 7172 anon_inode:[eventpoll]
flutter_e 2737 u0_a58 181r 0000 0,9 0t0 7172 anon_inode:gralloc_extra
flutter_e 2737 u0_a58 182u 0000 0,9 0t0 7172 anon_inode:dmabuf
flutter_e 2737 u0_a58 183r 0000 0,9 0t0 7172 anon_inode:gralloc_extra
flutter_e 2737 u0_a58 184u 0000 0,9 0t0 7172 anon_inode:dmabuf
flutter_e 2737 u0_a58 187r 0000 0,9 0t0 7172 anon_inode:gralloc_extra
flutter_e 2737 u0_a58 188u 0000 0,9 0t0 7172 anon_inode:dmabuf
flutter_e 2737 u0_a58 194r 0000 0,9 0t0 7172 anon_inode:gralloc_extra
flutter_e 2737 u0_a58 195u 0000 0,9 0t0 7172 anon_inode:dmabuf

have any suggestions?thanks for help!

SessionDescription is NULL

i’m getting this error when set sdp. please help me (Sorry my english not good).Thanks!

    o=mediasoup-client 10000 1 IN IP4 0.0.0.0
    s=-
    t=0 0
    a=ice-lite
    a=fingerprint:sha-512 65:F0:4D:B4:75:39:14:0A:B7:C8:EE:38:2B:81:1D:CA:91:3A:22:6F:3A:57:1B:57:A3:D5:07:41:8C:01:B6:49:16:75:4E:B7:66:DF:5F:E8:0A:EF:94:37:2E:9C:1C:10:A4:1C:91:98:26:C5:28:D6:3A:F1:A2:81:68:1A:22:0B
    a=msid-semantic: WMS *
    a=group:BUNDLE 0
    m=audio 7 UDP/TLS/RTP/SAVPF 111
    c=IN IP4 127.0.0.1
    a=rtpmap:111 opus/48000/2
    a=fmtp:111 stereo=1;useinbandfec=0;usedtx=1
    a=rtcp-fb:111 transport-cc 
    a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
    a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
    a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
    a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
    a=setup:active
    a=mid:0
    a=recvonly
    a=ice-ufrag:eoqgj4l291hgy9cm
    a=ice-pwd:3x350xan2amdjelboage5arw7fb6kj2w
    a=candidate:tcpcandidate 1 udp 1076302079 103.170.246.155 50566 typ host```
Log Error: peerConnectionSetRemoteDescription(): WEBRTC_SET_REMOTE_DESCRIPTION_ERROR: SessionDescription is NULL.

Click to close the camera to report an error

I/flutter (26134): mediasoup-client:Native stopSending() | calling pc.setLocalDescription() [offer:{sdp: v=0
I/flutter (26134): o=- 1197244669679924626 3 IN IP4 127.0.0.1
I/flutter (26134): s=-
I/flutter (26134): t=0 0
I/flutter (26134): a=group:BUNDLE video audio
I/flutter (26134): a=extmap-allow-mixed
I/flutter (26134): a=msid-semantic: WMS
I/flutter (26134): m=video 58834 UDP/TLS/RTP/SAVPF 96 97 98 99 35 36 100 101 127 124 125 37
I/flutter (26134): c=IN IP4 172.20.10.14
I/flutter (26134): a=rtcp:9 IN IP4 0.0.0.0
I/flutter (26134): a=candidate:733706150 1 udp 2122262783 240e:47d:3ad0:374:bdfc:c678:b39d:bdfc 36784 typ host generation 0 network-id 4 network-cost 10
I/flutter (26134): a=candidate:4281956785 1 udp 2122194687 172.20.10.14 58834 typ host generation 0 network-id 3 network-cost 10
I/flutter (26134): a=candidate:559267639 1 udp 2122136831 ::1 49018 typ host generation 0 network-id 2
I/flutter (26134): a=candidate:1510613869 1 udp 2122063615 127.0.0.1 33800 typ host generation 0 network-id 1
I/flutter (26134): a=candidate:1876313031 1 tcp 1518157055 ::1 51291 typ host tcptype passive generation 0 network-id 2
I/flutter (26134): a=candidate:344579997 1 tcp 1518083839 127.0.0.1 48383 typ host tcptype passive generation 0 network-id 1
I/flutter (26134): a=ice-ufrag:K1hw
I/flutter (26134): a=ice-pwd:qUrLqlVCo3WRxmjOXYEEOU
I/flutter (26134): mediasoup-client:Native stopSending() | calling pc.setRemoteDescription() [answer:[{sdp: v=0
I/flutter (26134): o=mediasoup-client 10000 2 IN IP4 0.0.0.0
I/flutter (26134): s=-
I/flutter (26134): t=0 0
I/flutter (26134): a=ice-lite
I/flutter (26134): a=fingerprint:sha-384 99:5D:AE:54:3E:DD:20:10:EF:E2:B7:35:02:F1:E3:C5:A3:B5:0B:8A:C9:AA:73:3B:06:D5:A6:3F:56:92:A0:D1:2A:2D:BF:DF:F6:35:D6:6F:41:52:2A:46:8F:A9:97:DA
I/flutter (26134): a=msid-semantic: WMS *
I/flutter (26134): a=group:BUNDLE video
I/flutter (26134): m=video 7 UDP/TLS/RTP/SAVPF 96 97
I/flutter (26134): c=IN IP4 127.0.0.1
I/flutter (26134): a=rtpmap:96 VP8/90000
I/flutter (26134): a=rtpmap:97 rtx/90000
I/flutter (26134): a=fmtp:96 x-google-start-bitrate=1000
I/flutter (26134): a=fmtp:97 apt=96
I/flutter (26134): a=rtcp-fb:96 transport-cc
I/flutter (26134): a=rtcp-fb:96 ccm fir
I/flutter (26134): a=rtcp-fb:96 nack
I/flutter (26134): a=rtcp-fb:96 nack pli
I/flutter (26134): a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
I/flutter (26134): a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
I/flutter (26134): a=extmap:14 urn:ietf:params:rtp-hdrext:toffset
I/flutter (26134): a=setup:active
I/flutter (26134): a=mid:video
I/flutter (26134): a=recvonly
I/flutter (26134): a=ice-ufrag:w3m8hv57av8tww47
I/flutter (26134): a=ice-pwd:psj9ycq07o921950uh4e313d4hazqm61
I/flutter (26134): a=candidate:udpcandidate 1 udp 1076558079 183.62.214.248 10395 typ host
I/flutter (26134): a=rtc
D/FlutterWebRTCPlugin(26134): peerConnectionSetRemoteDescription(): WEBRTC_SET_REMOTE_DESCRIPTION_ERROR: Failed to set remote answer sdp: The order of m-lines in answer doesn't match order in offer. Rejecting answer.
D/FlutterWebRTCPlugin(26134): peerConnectionSetRemoteDescription(): WEBRTC_SET_REMOTE_DESCRIPTION_ERROR: Failed to set remote answer sdp: The order of m-lines in answer doesn't match order in offer. Rejecting answer.
I/flutter (26134): Unable to RTCPeerConnection::setRemoteDescription: peerConnectionSetRemoteDescription(): WEBRTC_SET_REMOTE_DESCRIPTION_ERROR: Failed to set remote answer sdp: The order of m-lines in answer doesn't match order in offer. Rejecting answer.
I/flutter (26134): #0 RTCPeerConnectionNative.setRemoteDescription (package:flutter_webrtc/src/native/rtc_peerconnection_impl.dart:329:7)
I/flutter (26134):
I/flutter (26134): #1 Handler.stopSending (package:mediasoup_client_flutter/src/handlers/native.dart:734:5)
I/flutter (26134):
I/flutter (26134): #2 FlexQueue._runTask (package:mediasoup_client_flutter/src/FlexQueue/flex_queue.dart:85:28)
I/flutter (26134):
I/flutter (26134): mediasoup-client:WARN:Transport producer.close() failed:Unable to RTCPeerConnection::setRemoteDescription: peerConnectionSetRemoteDescription(): WEBRTC_SET_REMOTE_DESCRIPTION_ERROR: Failed to set remote answer sdp: The order of m-lines in answer doesn't match order in offer. Rejecting answer.
I/HwCameraUtil(26134): hide aux camera for app: com.example.conference_demo
I/org.webrtc.Logging(26134): Camera2Session: Stop done
I/org.webrtc.Logging(26134): Camera2Session: Camera device closed.
D/FlutterWebRTCPlugin(26134): CameraEventsHandler.onFirstFrameAvailable
I/CameraDevice-JV-1(26134): Camera now idle

I don't know why this error happened when I clicked to close the camera

void enableWebCam() async {
if (_device.canProduce(RTCRtpMediaType.RTCRtpMediaTypeVideo) == false) {
return;
}
if (_webcamProducer != null) {
return;
}
MediaStream videoStream;
try {
const videoVPVersion = 8;
RtpCodecCapability codec = _device.rtpCapabilities.codecs.firstWhere(
(RtpCodecCapability c) =>
c.mimeType.toLowerCase() == 'video/vp$videoVPVersion',
orElse: () => throw 'desired vp$videoVPVersion codec is not support',
);

  videoStream = await createVideoStream();
  _producerTranport.produce(
    track: videoStream.getVideoTracks().first,
    codecOptions: ProducerCodecOptions(
      videoGoogleStartBitrate: 1000,
    ),
    encodings: [
      RtpEncodingParameters(
          rid: 'r0', scalabilityMode: 'S1T3', maxBitrate: 100000),
      RtpEncodingParameters(
          rid: 'r1', scalabilityMode: 'S1T3', maxBitrate: 300000),
      RtpEncodingParameters(
          rid: 'r2', scalabilityMode: 'S1T3', maxBitrate: 900000)
    ],
    stream: videoStream,
    appData: {
      'source': 'webcam',
    },
    source: 'webcam',
    codec: codec,
  );
  // ignore: empty_catches
} catch (e) {
  if (videoStream != null) {
    await videoStream.dispose();
  }
} finally {
  if (confenceVideoCallback != null) {
    confenceVideoCallback(stream: videoStream);
  }
}

}

void disableWebcam({bool front = true}) async {
if (_webcamProducer == null) {
return;
}
_webcamProducer.close();

try {
  socketSendRequest('producerClosed', {
    'producer_id': _webcamProducer.id,
  });
} catch (e) {
  _webcamProducer = null;
} finally {
  _webcamProducer = null;
  if (confenceVideoCallback != null) {
    confenceVideoCallback();
  }
}

}

Future createVideoStream() async {
var devices = await AvDeviceUtils.getDevice();
Map<String, dynamic> mediaConstraints = <String, dynamic>{
'audio': false,
'video': {
'width': {
'min': 640,
'ideal': 1920,
},
'height': {'min': 400, 'ideal': 1080},
'sourceId': devices.first.deviceId,
},
};

MediaStream stream =
    await navigator.mediaDevices.getUserMedia(mediaConstraints);

return stream;

}

please help me,thanks

flutter-webrtc / flutter-mediasoup-client

Hi Blancduman,

I also noticed that the flutter-mediasoup-client project was not going anywhere. So i started the porting of the web-client this week. After the initial development i found your repo; and i see you are father ahead than me. So I'm going to fork and continue the port from your repo . Could you detail the missing parts?

Thanks for this!
Best,
Nicolai

Possible simulcast bug

I am trying to call produce() with RtpEncodingParameters (simulcast).
However, this fails during the construction of SdpObject around

SdpObject localSdpObject = SdpObject.fromMap(parse(offer.sdp!));

I traced it and found that at this location, Rid object expects "id" to be an integer.
https://github.com/Blancduman/mediasoup-client-flutter/blob/main/lib/src/handlers/sdp/media_section.dart#L265

However, earlier in the UnifiedPlan's send() function, it forces all rids to have format 'r{number}'.

, which ends up turning this id into a string.

Removing the 'r' from the above code did not fix it (possibly due to other inconsistencies)...but changing the Rid.fromMap() code to parse only the integer index of 'r{number}' seems to have fixed the issue.

Not sure if this is a bug or whether I'm using it wrong.

Thanks in advance.

mediasoup-client:Transport connection state changed to disconnected

Hi, sorry I'm a very beginner with mediasoup. Currently, I'm trying to develop a video call app with mediasoup version 3. I followed this tutorial and it works then I want to implement it the same way on flutter I have an issue it says 'mediasoup-client:Transport connection state changed to disconnected' after I called _consumerTransport.consume(..) function.

Note: _consumerTransport.consume(..) in flutter required peerId which in his web tutorial don't have this peerId so I decided to pass a radom string.

is this problem caused by this the peerId or something else?

Please see the log below (flutter ran on chrome).
Thanks

.....
mediasoup-client:Transport connection state changed to connecting
mediasoup-client:Browser receive() | calling pc.setLocalDescription() [answer:{sdp: v=0
o=- 2570049599350349300 3 IN IP4 127.0.0.1
s=-
t=0 0
a=msid-semantic: WMS 
a=group:BUNDLE 0 probator
m=video 62320 UDP/TLS/RTP/SAVPF 101 102
c=IN IP4 192.168.0.136
a=rtpmap:101 VP8/90000
a=rtpmap:102 rtx/90000
a=fmtp:102 apt=101
a=rtcp:9 IN IP4 0.0.0.0
a=rtcp-fb:101 ccm fir
a=rtcp-fb:101 nack 
a=rtcp-fb:101 nack pli
a=setup:active
a=mid:0
a=recvonly
a=ice-ufrag:uZBd
a=ice-pwd:AzY1sGnGvw9+UHZGYQaesJ91
a=fingerprint:sha-256 E3:BD:A8:BC:51:32:C3:1D:0E:77:F9:BF:BE:22:26:6A:E5:33:4B:34:62:47:12:B0:42:ED:4D:2F:88:36:96:5B
a=candidate:499412426 1 udp 2122260223 192.168.0.136 62320 typ host
a=ice-options:trickle
a=rtcp-mux
a=rtcp-rsize
m=video 9 UDP/TLS/RTP/SAVPF 127
c=IN IP4 0.0.0.0
a=rtpmap:127 VP8/90000
a=rtcp:9 IN IP4 0.0.0.0
a=rtcp-fb:127 ccm fir
a=rtcp-fb:127 nack 
a=rtcp-fb:127 nack pli
a=setup:active
a=mid:probator
a=recvonly
a=ice-ufrag:uZBd
a=ice-pwd:AzY1sGnGvw9+UHZGYQaesJ91
a=fingerprint:sha-256 E3:BD:A8:BC:51:32:C3:1D:0E:77:F9:BF:BE:22:26:6A:E5:33:4B:34:62:47:12:B0:42:ED:4D:2F:88:36:96:5B
a=ice-options:trickle
a=rtcp-mux
a=rtcp-rsize
, type: answer}]
mediasoup-client:Transport consume() | Consumer for RTP probation created
mediasoup-client:Transport connection state changed to disconnected

Consider updating the base Flutter WebRTC version

We are a few versions behind the current Flutter WebRTC.

There have been a few fixes, some that we require (like selecting audio outputs)

Would it be possible for you to bump the pubspec up? :-)

Doubt regarding media constraints error.

Hello, in my project that uses this package, I am getting this error of mandatory constraints everytime I run the app on my emulator, and also because of this it never asks for permission for webcam and mic, but the example app in this repo works just fine on the emulator.

image

Vp9 encoding

Hello @Blancduman
even if the codec selected is vp9
RtpCodecCapability? codec = _mediasoupDevice!.rtpCapabilities.codecs
.firstWhere(
(RtpCodecCapability c) => c.mimeType.toLowerCase() == 'video/vp9',

still I am receiving vp8 encoded video on mediasoup demo
output on web:-
audio
id: 7e0be7c6-e7e6-4024-8d07-2b503f03b223
codec: opus
score:10, producerScore:10, producerScores:[10]
video
id: fb3ffb6e-27ea-416d-ae60-0c19fcb139cf
codec: VP8
resolution: 720x1280
priority: 1 [ down ]
score:10, producerScore:10, producerScores:[10]

unable to build : Error The non-abstract class 'RTCVideoRenderer' is missing implementations for these members:

we are getting this error during build for ios and android.

mediasoup_client_flutter: ^0.8.1. this is the latest pub dart verions

: Error: The non-abstract class 'RTCVideoRenderer' is missing implementations for these members:
../…/native/rtc_video_renderer_impl.dart:11
 - VideoRenderer.onFirstFrameRendered
Try to either
 - provide an implementation,
 - inherit an implementation from a superclass or mixin,
 - mark the class as abstract, or
 - provide a 'noSuchMethod' implementation.

class RTCVideoRenderer extends ValueNotifier<RTCVideoValue>
      ^^^^^^^^^^^^^^^^
: Context: 'VideoRenderer.onFirstFrameRendered' is defined here.
../…/src/rtc_video_renderer.dart:51

  Function? onFirstFrameRendered;
            ^^^^^^^^^^^^^^^^^^^^


FAILURE: Build failed with an exception.

restartIce doesn't work on SendTransport after status changed to failed

Once the SendTransport's status changed to failed the transport.restartIce(...) doesn't work anymore. Normally when I try to call .restartIce on a Transport it shows something like the below but after its status has changed to failed for some reason (eg. in my case I cut off the internet) .restartIce will not affect anymore. ReceiveTransport just works fine.

flutter: mediasoup-client:Transport connection state changed to connecting
flutter: mediasoup-client:Transport connection state changed to connected

User video session without sound

After the demo runs, the user video session is silent, and the picture quality is very blurred, and the picture quality is also blurred at the highest level

Bug Report: producer.replaceTrack() doesn't work.

I'm working on a feature where user can switch their camera. To do that I replace a new track for the producer using producer.replaceTrack(newTrack) but it always returns a log that says "replaceTrack() | same track, ignored." even when I pass a completely new track.

I looked into your code inside producer.dart file at line 357 you compare a track parameter to the track parameter itself (see below) which is why the condition is always matched.

  Future<void> replaceTrack(MediaStreamTrack track) async {
   ...
       if (track == track) {
      _logger.debug('replaceTrack() | same track, ignored.');

      return;
    }
  ...
  }

Error - RTCPeerConnection randomly null

Hi,
Please help me. There is an error occurred randomly. It says "Null check operator used on a null value". After I inspected the error file (mediasoup_client_flutter/…/handlers/unified_plan.dart:204) I found that it was RTCPeerConnection has a null value but sometimes it's just working fine.

Screen Shot 2022-06-28 at 4 53 31 PM

Switch Cam

Hello again, I need to switch cam i use replaceTrack() but it doesn’t work.
Any ideas please?

cycleTrack() async {
    final List<MediaDeviceInfo> devices =
        await navigator.mediaDevices.enumerateDevices();
    devices.forEach((element) {
      log('------------\n${element.kind} | ${element.deviceId} | ${element.label}');
    });
    log('------------\n${devices[1].kind} | ${devices[1].deviceId} | ${devices[1].label}');
    Map<String, dynamic> mediaConstraints = {
      'audio': false,
      'video': {
        'mandatory': {
          'minWidth':
              '720', // Provide your own width, height and frame rate here
          'minHeight': '1280',
          'minFrameRate': '30',
        },
        'sourceId': devices[0].deviceId,
      }
    };
    stream = await navigator.mediaDevices.getUserMedia(mediaConstraints);
    // var backVideoTrack = stream.getVideoTracks()[0];
    videoProducer.replaceTrack(stream.getVideoTracks()[0]);
    videoProducer.resume();

    notifyListeners();
  }

example not working

Hello, thank you for your effort and the package .. I tried to run your example but it's not working for me .

Question regarding publishing of package

Hello, will this package be published on pub.dev? Me and my colleagues are using this package for a project which I need to publish soon, so I wanted to know.

Remote video renderer not working when remote peer toggle webcam stream

When remote peer enables webcam for the first time it works but when remote peer turn OFF webcam and turn ON webcam again this error is displayed inside RTCVideoRenderer , but when remote peer again toggles webcam it works fine.

image

image

I am testing on our own mediasoup server, but this error was was there when I ran example code form thiss repository.

testing on android device

Disable logs

I'm trying to create the flow, but it's hard to follow when the library is filling the logs.

Is there an option to disable this?

Screenshot 2022-07-13 at 07 24 25

?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.