首页 > 解决方案 > Sending data from Screen over Socket IO?

问题描述

I have been googling around but cannot find a clear answer to this.

I am making a chrome extension which records tabs. The idea is to stream getUserMedia to the backend using Websockets (specifically Socket.io) where the backend writes to a file until a specific condition (a value in the backend) is set.

The problem is, I do not know how I would call the backend with a specific ID and also, how would I correctly write to the file without corrupting it?

标签: node.jswebsocketsocket.iogetusermediaweb-mediarecorder

解决方案


You are sending the output from MediaRecorder, via a websocket, to your back end.

Presumably you do this from within MediaRecorder's ondataavailable handler.

It's quite easy to stuff that data into a websocket:

function ondataavailable ( event ) {
  event.data.arrayBuffer().then ( buf => {socket.emit('media', buf) })
}

In the backend you must concatenate all the data you receive, in the order of reception, to a media file. This media file likely has a video/webm MIME type; if you give it the .webm filename extension most media players will handle it correctly. Notice that the media file will be useless if it doesn't contain all the Blobs in order. The first few Blobs contain metadata needed to make sense of the stream. This is easy to do by appending each received data item to the file.

Server-side you can use the socket.id attribute to make up a file name; that gives you a unique file for each socket connection. Something like this sleazy poorly-performing non-debugged not-production-ready code will do that.

io.on("connection", (socket) => {
  if (!socket.filename) 
     socket.filename = path.join(__dirname, 'media', socket.id + '.webm))

  socket.on('filename', (name) => {
     socket.filename = path.join(__dirname, 'media', name + '.webm))
  })
  socket.on('media', (buf) => {
    fs.appendFile(buf, filename)
  })
})

On the client side you could set the filename with this.

socket.emit('filename', 'myFavoriteScreencast')

推荐阅读