'Uncaught InvalidStateError: not loaded'

I am new to media soup…I ve read the documentation and tried working with simple demo…I got error on ‘mediaoup-client’ saying ‘Uncaught InvalidStateError: not loaded’. I dont know what I miss…FIrst I get media stream, and then get rtpcapabilities from the server, and then created device, device.load(rtpcapabilities). and then create transport in clients side from the params recived from the server with subscription to on produce and on connect event, and then called transport.produce(track)…Yet I got the following error…did I Miss any thing wrong…Following is my client side code

const { io } = require("socket.io-client");
let socket = io("http://localhost:3000/");
const mediasoupClient = require("mediasoup-client");
socket.on("connect", () => {
  console.log("server is connected with client ", socket.id);
});

let device
let rtpCapabilities
let producerTransport
let consumerTransport
let producer
let consumer
let isProducer = false

let params = {
  // mediasoup params
  
}

const streamSuccess =  (stream) => {
  localVideo.srcObject = stream
  const track = stream.getVideoTracks()[0]
  params = {
    track,
    ...params
  }
  goConnect(true)
}

const getLocalStream = () => {
  navigator.mediaDevices.getUserMedia({
    audio: false,
    video: {
      width: {
        min: 640,
        max: 1920,
      },
      height: {
        min: 400,
        max: 1080,
      }
    }
  })
  .then(streamSuccess)
  .catch(error => {
    console.log(error.message)
  })
}

const goConsume = () => {
  goConnect(false)
}

const goConnect = (producerOrConsumer) => {
  isProducer = producerOrConsumer
  device === undefined ? getRtpCapabilities() : goCreateTransport()
}

const goCreateTransport = () => {
  isProducer ? createSendTransport() : createRecvTransport()
}

const createDevice = async () => {
  try {
    device = new mediasoupClient.Device()

   
    await device.load({
 
      routerRtpCapabilities: rtpCapabilities
    })

    console.log('Device RTP Capabilities', device.rtpCapabilities)

    // once the device loads, create transport
    goCreateTransport()

  } catch (error) {
    console.log(error)
    if (error.name === 'UnsupportedError')
      console.warn('browser not supported')
  }
}

const getRtpCapabilities = () => {

  socket.emit('createRoom', (data) => {
    console.log(`Router RTP Capabilities... ${data.rtpCapabilities}`)

    rtpCapabilities = JSON.parse(data.rtpCapabilities)

    createDevice()
  })
}

const createSendTransport = () => {
  
  socket.emit('createWebRtcTransport', { sender: true }, ({ params }) => {
  
    if (params.error) {
      console.log(params.error)
      return
    }

    console.log(params)

 
    producerTransport = device.createSendTransport(params)

    producerTransport.on('connect', async ({ dtlsParameters }, callback, errback) => {
      try {
        // Signal local DTLS parameters to the server side transport
        // see server's socket.on('transport-connect', ...)
        await socket.emit('transport-connect', {
          dtlsParameters,
        })

        // Tell the transport that parameters were transmitted.
        callback()

      } catch (error) {
        errback(error)
      }
    })

    producerTransport.on('produce', async (parameters, callback, errback) => {
      console.log(parameters)

      try {
     
        await socket.emit('transport-produce', {
          kind: parameters.kind,
          rtpParameters: parameters.rtpParameters,
          appData: parameters.appData,
        }, ({ id }) => {
     
          callback({ id })
        })
      } catch (error) {
        errback(error)
      }
    })

    connectSendTransport()
  })
}

const connectSendTransport = async () => {

  producer = await producerTransport.produce(params)

  producer.on('trackended', () => {
    console.log('track ended')

    // close video track
  })

  producer.on('transportclose', () => {
    console.log('transport ended')

    // close video track
  })
}

const createRecvTransport = async () => {

  await socket.emit('createWebRtcTransport', { sender: false }, ({ params }) => {
e
    if (params.error) {
      console.log(params.error)
      return
    }

    console.log(params)

    
    consumerTransport = device.createRecvTransport(params)

    consumerTransport.on('connect', async ({ dtlsParameters }, callback, errback) => {
      try {
   
        await socket.emit('transport-recv-connect', {
          dtlsParameters,
        })

        callback()
      } catch (error) {
        errback(error)
      }
    })

    connectRecvTransport()
  })
}

const connectRecvTransport = async () => {
  
  await socket.emit('consume', {
    rtpCapabilities: device.rtpCapabilities,
  }, async ({ params }) => {
    if (params.error) {
      console.log('Cannot Consume')
      return
    }

    console.log(params)
  
    consumer = await consumerTransport.consume({
      id: params.id,
      producerId: params.producerId,
      kind: params.kind,
      rtpParameters: params.rtpParameters
    })

    // destructure and retrieve the video track from the producer
    const { track } = consumer

    remoteVideo.srcObject = new MediaStream([track])

    // the server consumer started with media paused
    // so we need to inform the server to resume
    socket.emit('consumer-resume')
  })
}

btnLocalVideo.addEventListener('click', getLocalStream)
btnRecvSendTransport.addEventListener('click', goConsume)

You have async functions on which you have to await. Like createDevice().

thank you for the support…

Actually there is no createDevice() function but a Device() constructor which obviously is synchronous. However device.load() is async and you have to await for it before doing other things with the device instance.

There is one in code snippet provided above and it does call device.load() inside of it

True, sorry.

You should not try to create a transport before the device is loaded. For example, in goConnect, if device is NOT undefined, make sure that it is loaded before calling goCreateTransport().

Thank you for the support