mediadevices icon indicating copy to clipboard operation
mediadevices copied to clipboard

Crash on resolution change

Open ghost opened this issue 4 years ago • 6 comments

I'm working on linux 18.04 without GUI with X display and the stream works well But once i change the screen resolution with xrandr command the stream crashes and here's the error:

(node:10327) UnhandledPromiseRejectionWarning: Error: write EPIPE
    at afterWriteDispatched (internal/stream_base_commons.js:154:25)
    at writeGeneric (internal/stream_base_commons.js:145:3)
    at Socket._writeGeneric (net.js:786:11)
    at Socket._write (net.js:798:8)
    at doWrite (_stream_writable.js:403:12)
    at writeOrBuffer (_stream_writable.js:387:5)
    at Socket.Writable.write (_stream_writable.js:318:11)
    at Transport.send (/snapshot/playwright-cli/node_modules/playwright/lib/protocol/transport.js:43:25)
    at DispatcherConnection.onmessage (/snapshot/playwright-cli/lib/driver.js:49:61)
    at DispatcherConnection.sendMessageToClient (/snapshot/playwright-cli/node_modules/playwright/lib/dispatchers/dispatcher.js:129:14)
(node:10327) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:10327) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

ghost avatar Jan 29 '21 13:01 ghost

@celestial2 sorry for the delay. I'm not really sure how nodejs is related to mediadevices. Do you mind explaining your use case a little bit more?

  1. What's your application stack/architecture?
  2. So, it seems that you changed your screen resolution on your system. Was the error originated from mediadevices? If so, what was the error message from Go end?
  3. How do you use mediadevices with your nodejs stack?

lherman-cs avatar Feb 09 '21 02:02 lherman-cs

Sorry for late response, i was debugging just to be sure. Ignore the nodeJS, it was issue from other library. I am using Golang with VueJS and on signal from front end i change the resolution in the system.

So i have Xvfb virtual display since my app is in docker and i'm changing the resolution with xrandr commands.

**Display command**
Xvfb -screen 0 1920x1920x24 -ac &

**Resize commands**
# Get the needed resolution info
CVT=$(cvt $w $h)
resolution=$(echo $CVT | cut -d "\"" -f 2)
rest=$(echo $CVT | cut -d "\"" -f 3)

# Create, add and apply the new mode resolution
xrandr --newmode $resolution $rest || true
xrandr --addmode screen $resolution || true 
xrandr --output screen --mode $resolution || true

The app when i change the resolution crashes and returns this:

X Error of failed request:  BadMatch (invalid parameter attributes)
  Major opcode of failed request:  130 (MIT-SHM)
  Minor opcode of failed request:  4 (X_ShmGetImage)
  Serial number of failed request:  26
  Current serial number in output stream:  26

I'm certain that it is from the mediadevices stream because when i am not streaming, executing the command doesn't crash the app.

Interesting thing is that if before the stream starts i add the new resolution and then when its running i change it to the first one it doesn't crash. It is as if the stream takes only the resolutions that are registered when it's created and if the system after the stream creation adds and uses a new resolution it crashes.

I was previously using mediadevices with the navigator in nodeJS app and it didn't have this issue.

ghost avatar Feb 11 '21 13:02 ghost

In addition to my conclusion above i tried to close the track, restart the display and then take it, but there is no option to stop/restart the stream. After i remove the tracks when i try to get displaymedia again it says that the driver is already in use.

Is there a way to restart or re-initiate the stream ?

ghost avatar Feb 12 '21 19:02 ghost

@Chimerax2 what's your OS? Currently, we have 2 backends, X11 driver that interacts directly to X11 server, and kbinani/screenshot. We use the X11 driver directly if it's on Linux.

In addition to my conclusion above i tried to close the track, restart the display and then take it, but there is no option to stop/restart the stream. After i remove the tracks when i try to get displaymedia again it says that the driver is already in use.

You should be able to re-initiate the stream by calling Close on the tracks and call GetUserMedia again, https://pkg.go.dev/github.com/pion/mediadevices#Source.

mediaStream, _ := mediadevices.GetUserMedia(...)
for _, track := range mediaStream.GetTracks() {
  track.Close()
}

lherman-cs avatar Feb 21 '21 20:02 lherman-cs

Sorry for the late response, just got back to the issue.

It doesn't break anymore, but the stream doesn't continue. I try to get the stream tracks and they are there, but the ontrack event on client side doesn't fire and when i check the webrtc-internals tab it shows on the graphs that it is not receiving any frames.

After i close the tracks, i get display media again and then add the tracks to the transceiver. Is there some additional step that i am missing ?

ghost avatar Mar 11 '21 12:03 ghost

Handling the resize with restart of connection was not the best user experience.

I made two repos - mediadevices one and one with novnc nodejs based on x11vnc also. They both use same environment and do resize while connection running but the mediadevices one crashes on resize.

You can take them from here:

  • https://github.com/Chimerax2/mediadevices
  • https://github.com/Chimerax2/novnc-resize

They are both dockerized so environment shouldn't be a problem. If you can please check them and let me know your thoughts whether this can be setup in mediadevices so they don't crash.

ghost avatar Jun 15 '21 08:06 ghost