sendrecv: try to add a data channel
authorMathieu Duponchelle <mathieu@centricular.com>
Fri, 21 Sep 2018 13:03:43 +0000 (15:03 +0200)
committerMatthew Waters <ystreet@users.noreply.github.com>
Fri, 21 Sep 2018 13:12:16 +0000 (13:12 +0000)
webrtc/sendrecv/gst/webrtc-sendrecv.c
webrtc/sendrecv/js/index.html
webrtc/sendrecv/js/webrtc.js

index 109b14d..321f8d0 100644 (file)
@@ -40,6 +40,7 @@ enum AppState {
 
 static GMainLoop *loop;
 static GstElement *pipe1, *webrtc1;
+static GObject *send_channel, *receive_channel;
 
 static SoupWebsocketConnection *ws_conn = NULL;
 static enum AppState app_state = 0;
@@ -274,6 +275,54 @@ on_negotiation_needed (GstElement * element, gpointer user_data)
 #define RTP_CAPS_OPUS "application/x-rtp,media=audio,encoding-name=OPUS,payload="
 #define RTP_CAPS_VP8 "application/x-rtp,media=video,encoding-name=VP8,payload="
 
+static void
+data_channel_on_error (GObject * dc, gpointer user_data)
+{
+  cleanup_and_quit_loop ("Data channel error", 0);
+}
+
+static void
+data_channel_on_open (GObject * dc, gpointer user_data)
+{
+  GBytes *bytes = g_bytes_new ("data", strlen("data"));
+  g_print ("data channel opened\n");
+  g_signal_emit_by_name (dc, "send-string", "Hi! from GStreamer");
+  g_signal_emit_by_name (dc, "send-data", bytes);
+  g_bytes_unref (bytes);
+}
+
+static void
+data_channel_on_close (GObject * dc, gpointer user_data)
+{
+  cleanup_and_quit_loop ("Data channel closed", 0);
+}
+
+static void
+data_channel_on_message_string (GObject * dc, gchar *str, gpointer user_data)
+{
+  g_print ("Received data channel message: %s\n", str);
+}
+
+static void
+connect_data_channel_signals (GObject * data_channel)
+{
+  g_signal_connect (data_channel, "on-error", G_CALLBACK (data_channel_on_error),
+      NULL);
+  g_signal_connect (data_channel, "on-open", G_CALLBACK (data_channel_on_open),
+      NULL);
+  g_signal_connect (data_channel, "on-close", G_CALLBACK (data_channel_on_close),
+      NULL);
+  g_signal_connect (data_channel, "on-message-string", G_CALLBACK (data_channel_on_message_string),
+      NULL);
+}
+
+static void
+on_data_channel (GstElement * webrtc, GObject * data_channel, gpointer user_data)
+{
+  connect_data_channel_signals (data_channel);
+  receive_channel = data_channel;
+}
+
 static gboolean
 start_pipeline (void)
 {
@@ -306,6 +355,17 @@ start_pipeline (void)
    * added by us too, see on_server_message() */
   g_signal_connect (webrtc1, "on-ice-candidate",
       G_CALLBACK (send_ice_candidate_message), NULL);
+  g_signal_emit_by_name (webrtc1, "create-data-channel", "channel", NULL,
+      &send_channel);
+  if (send_channel) {
+    g_print ("Created data channel\n");
+    connect_data_channel_signals (send_channel);
+  } else {
+    g_print ("Could not create data channel, is usrsctp available?\n");
+  }
+
+  g_signal_connect (webrtc1, "on-data-channel", G_CALLBACK (on_data_channel),
+      NULL);
   /* Incoming streams will be exposed via this signal */
   g_signal_connect (webrtc1, "pad-added", G_CALLBACK (on_incoming_stream),
       pipe1);
index f52cd50..9a95fb7 100644 (file)
@@ -24,6 +24,7 @@
   <body>
     <div><video id="stream" autoplay>Your browser doesn't support video</video></div>
     <div>Status: <span id="status">unknown</span></div>
+    <div><textarea id="text" cols=40 rows=4></textarea></div>
     <div>Our id is <b id="peer-id">unknown</b></div>
     <br/>
     <div>
index b94288f..c13837e 100644 (file)
@@ -20,6 +20,7 @@ var default_constraints = {video: true, audio: true};
 
 var connect_attempts = 0;
 var peer_connection;
+var send_channel;
 var ws_conn;
 // Promise for local stream after constraints are approved by the user
 var local_stream_promise;
@@ -234,6 +235,41 @@ function errorUserMediaHandler() {
     setError("Browser doesn't support getUserMedia!");
 }
 
+const handleDataChannelOpen = (event) =>{
+    console.log("dataChannel.OnOpen", event);
+};
+
+const handleDataChannelMessageReceived = (event) =>{
+    console.log("dataChannel.OnMessage:", event, event.data.type);
+
+    setStatus("Received data channel message");
+    if (typeof event.data === 'string' || event.data instanceof String) {
+        console.log('Incoming string message: ' + event.data);
+        textarea = document.getElementById("text")
+        textarea.value = textarea.value + '\n' + event.data
+    } else {
+        console.log('Incoming data message');
+    }
+    send_channel.send("Hi! (from browser)");
+};
+
+const handleDataChannelError = (error) =>{
+    console.log("dataChannel.OnError:", error);
+};
+
+const handleDataChannelClose = (event) =>{
+    console.log("dataChannel.OnClose", event);
+};
+
+function onDataChannel(event) {
+    setStatus("Data channel created");
+    let receiveChannel = event.channel;
+    receiveChannel.onopen = handleDataChannelOpen;
+    receiveChannel.onmessage = handleDataChannelMessageReceived;
+    receiveChannel.onerror = handleDataChannelError;
+    receiveChannel.onclose = handleDataChannelClose;
+}
+
 function createCall(msg) {
     // Reset connection attempts because we connected successfully
     connect_attempts = 0;
@@ -241,6 +277,12 @@ function createCall(msg) {
     console.log('Creating RTCPeerConnection');
 
     peer_connection = new RTCPeerConnection(rtc_configuration);
+    send_channel = peer_connection.createDataChannel('label', null);
+    send_channel.onopen = handleDataChannelOpen;
+    send_channel.onmessage = handleDataChannelMessageReceived;
+    send_channel.onerror = handleDataChannelError;
+    send_channel.onclose = handleDataChannelClose;
+    peer_connection.ondatachannel = onDataChannel;
     peer_connection.onaddstream = onRemoteStreamAdded;
     /* Send our video/audio to the other peer */
     local_stream_promise = getLocalStream().then((stream) => {