# Aiortc python server connected to ract-native-webrtc

**URL:** https://react-native-webrtc.discourse.group/t/aiortc-python-server-connected-to-ract-native-webrtc/1742
**Category:** General040642add70aa006ef56b5af5b5acae3
**Created:** [April 15, 2023, 8:54am UTC](https://react-native-webrtc.discourse.group/t/aiortc-python-server-connected-to-ract-native-webrtc/1742 "2023-04-15T08:54:11Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![eliabruni](https://avatars.discourse-cdn.com/v4/letter/e/9de053/32.png) [@eliabruni](https://react-native-webrtc.discourse.group/u/eliabruni)
#### Post date: [April 15, 2023, 8:54am UTC](https://react-native-webrtc.discourse.group/t/aiortc-python-server-connected-to-ract-native-webrtc/1742/1 "2023-04-15T08:54:11Z")

</div>

Hi!

I am trying to create an aiortc-based server to send a video stream to a react-native-webrtc client.

Here is my simple server:

```auto
import asyncio
import os
import json
from aiohttp import web
from aiortc import MediaStreamTrack, RTCPeerConnection, RTCSessionDescription
from av import VideoFrame
import cv2
import glob

ROOT = os.path.dirname( __file__ )
pcs = set()

image_files = sorted(glob.glob("./sample-video-frames/*.jpg")) # Change to the path to your images
current_image_index = 0

def get_next_image():
    global current_image_index
    img = cv2.imread(image_files[current_image_index])
    current_image_index = (current_image_index + 1) % len(image_files)
    return img

class ImageVideoTrack(MediaStreamTrack):
    kind = "video"

    def __init__ (self):
        super(). __init__ ()

    async def recv(self):
        img = get_next_image()

        new_frame = VideoFrame.from_ndarray(img, format="bgr24")
        new_frame.pts = 0
        new_frame.time_base = 0

        await asyncio.sleep(1/30) # Set the desired frame rate (e.g., 30 FPS)
        return new_frame

async def index(request):
    content = open(os.path.join(ROOT, "index.html"), "r").read()
    return web.Response(content_type="text/html", text=content)

async def offer(request):
    params = await request.json()
    offer = RTCSessionDescription(sdp=params["sdp"], type=params["type"])

    pc = RTCPeerConnection()
    pcs.add(pc)

    @pc.on("connectionstatechange")
    async def on_connectionstatechange():
        print("Connection state change:", pc.connectionState)
        if pc.connectionState == "failed":
            await pc.close()
            pcs.discard(pc)

    @pc.on("track")
    def on_track(track):
        print("Track received:", track.kind)
        if track.kind == "video":
            local_video = ImageVideoTrack()
            pc.addTrack(local_video)

            async def send_frames():
                while pc.connectionState == "connected":
                    local_video.on_frame()
                    await asyncio.sleep(0.01) # Set the desired frame rate (e.g., 100 FPS)

            asyncio.ensure_future(send_frames())

    print("Setting remote description")
    await pc.setRemoteDescription(offer)
    print("Creating answer")
    answer = await pc.createAnswer()

    # Modify the SDP to change "a=inactive" to "a=sendonly"
    sdp_lines = answer.sdp.split('\n')
    modified_sdp_lines = [line if "a=inactive" not in line else "a=sendonly" for line in sdp_lines]
    modified_sdp = '\n'.join(modified_sdp_lines)

    # Set the local description with the modified SDP
    print("Setting local description")
    await pc.setLocalDescription(RTCSessionDescription(sdp=modified_sdp, type=answer.type))

    print("Answer created and local description set")
    return web.Response(
        content_type="application/json",
        text=json.dumps(
            {"sdp": pc.localDescription.sdp, "type": pc.localDescription.type}
        ),
    )

async def on_shutdown(app):
    print("Shutting down")
    coros = [pc.close() for pc in pcs]
    await asyncio.gather(*coros)
    pcs.clear()

if __name__ == " __main__":
    app = web.Application()
    app.on_shutdown.append(on_shutdown)
    app.router.add_get("/", index)
    app.router.add_post("/offer", offer)
    web.run_app(app, access_log=None, host="192.168.122.1", port=8080)

```

And here the client:

```auto
import React, { useEffect, useState } from 'react';
import { View } from 'react-native';
import {
  RTCPeerConnection,
  RTCSessionDescription,
  mediaDevices,
} from 'react-native-webrtc';
import InCallManager from 'react-native-incall-manager';
import { RTCView } from 'react-native-webrtc';

const App = () => {
  const [remoteStream, setRemoteStream] = useState(null);

  useEffect(() => {
    async function startStreaming() {
      const pc = new RTCPeerConnection({
        iceServers: [{ urls: 'stun:stun.l.google.com:19302' }],
      });

      pc.ontrack = (event) => {
        console.log('Received remote stream:', event.streams[0]);
        setRemoteStream(event.streams[0]);
      };

      pc.onicecandidate = async (event) => {
        if (event.candidate) {
          console.log('Sending ICE candidate:', event.candidate.substr(0, 50));
          const response = await fetch('http://192.168.122.1:8080/candidate', {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({
              candidate: event.candidate,
            }),
          });
        } else {
          console.log('All ICE candidates sent');
        }
      };

      const offer = await pc.createOffer({ offerToReceiveVideo: true });
      console.log('Offer created:', offer.sdp.substr(0, 50));
      await pc.setLocalDescription(offer);
      console.log('Local description set:', pc.localDescription.sdp.substr(0, 50));

      const response = await fetch('http://192.168.122.1:8080/offer', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          sdp: pc.localDescription.sdp,
          type: pc.localDescription.type,
        }),
      });

      const responseData = await response.json();
      const answer = new RTCSessionDescription(responseData);
      console.log('Answer received:', answer.sdp.substr(0, 50));
      await pc.setRemoteDescription(answer);
      console.log('Remote description set:', pc.remoteDescription.sdp.substr(0, 50));

      InCallManager.start({ media: 'video' });
    }

    startStreaming();

    return () => {
      InCallManager.stop();
    };
  }, []);

  return (
    <View style={{ flex: 1, backgroundColor: 'black' }}>
      {remoteStream && (
        <RTCView
          objectFit="cover"
          style={{ flex: 1 }}
          streamURL={remoteStream.toURL()}
        />
      )}
    </View>
  );
};

export default App;

```

Peer connection is successfully established as per logs:

```auto
 LOG Running "WebrtcImageApp" with {"rootTag":11}
 LOG rn-webrtc:pc:DEBUG 0 ctor +0ms
 LOG rn-webrtc:pc:DEBUG 0 createOffer +1ms
 LOG rn-webrtc:pc:DEBUG 0 createOffer OK +14ms
 LOG Offer created: v=0
o=- 8514285042449230946 2 IN IP4 127.0.0.1
s
 LOG rn-webrtc:pc:DEBUG 0 setLocalDescription +2ms
 LOG rn-webrtc:pc:DEBUG 0 setLocalDescription OK +17ms
 LOG Local description set: v=0
o=- 8514285042449230946 2 IN IP4 127.0.0.1
s
 LOG Answer received: v=0
o=- 3890536821 3890536821 IN IP4 0.0.0.0
s=-
 LOG rn-webrtc:pc:DEBUG 0 setRemoteDescription +62ms
 LOG rn-webrtc:pc:DEBUG 0 ontrack +15ms
 LOG All ICE candidates sent

```

However, I keep having the following error:

```auto
 WARN Possible Unhandled Promise Rejection (id: 3):
TypeError: Cannot read property 'receiver' of undefined
TypeError: Cannot read property 'receiver' of undefined

```

It’s likely related to the `ontrack` event, which is triggered when a remote stream is added to the peer connection. However, I cannot understand how to handle it.

Does anyone have experience with aiortc and react-native-webrtc connection?

---

<div class="post-metadata">

### Author: ![guybiton7](https://avatars.discourse-cdn.com/v4/letter/g/22d042/32.png) [@guybiton7](https://react-native-webrtc.discourse.group/u/guybiton7)
#### Post date: [April 19, 2023, 2:16pm UTC](https://react-native-webrtc.discourse.group/t/aiortc-python-server-connected-to-ract-native-webrtc/1742/2 "2023-04-19T14:16:07Z")

</div>

> [@eliabruni](#):
>
> `RTCPeerConnection`

the same issue is happening to me

---

<div class="post-metadata">

### Author: ![8BallBomBom](https://yyz2.discourse-cdn.com/free1/user_avatar/react-native-webrtc.discourse.group/8ballbombom/32/710_2.png) [@8BallBomBom](https://react-native-webrtc.discourse.group/u/8BallBomBom)
#### Post date: [April 29, 2023, 4:47pm UTC](https://react-native-webrtc.discourse.group/t/aiortc-python-server-connected-to-ract-native-webrtc/1742/3 "2023-04-29T16:47:12Z")

</div>

Are you running the absolute latest version of the module? v111.0.0  
Also can you provide logs from logcat as it should include the error stack trace.
