mediadevices
mediadevices copied to clipboard
Crash on resolution change
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.
@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?
- What's your application stack/architecture?
- 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? - How do you use
mediadeviceswith your nodejs stack?
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.
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 ?
@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()
}
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 ?
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.