How can I correctly provide a mock webcam video to Chrome?
After reading the link you provided I noticed that we can also provide an mjpeg.
Depending on what your test requirements - this may be sufficient for you. As a terminal command with ffmpeg installed:
ffmpeg -i oldfile.mp4 newfile.mjpeg
then I tested by running Google Chrome from the terminal using:
google-chrome --use-fake-device-for-media-stream --use-file-for-fake-video-capture=newfile.mjpeg
After navigating to Tracking JS I could see the video being played back.
I hope that works for you!
If someone ever needs to mock a video dynamically, this is what I've used (forked from here)
await page.evaluate(() => { const video = document.createElement("video"); video.setAttribute('id', 'video-mock'); video.setAttribute("src", 'https://woolyss.com/f/spring-vp9-vorbis.webm'); video.setAttribute("crossorigin", "anonymous"); video.setAttribute("controls", ""); video.oncanplay = () => { const stream = video.captureStream(); navigator.mediaDevices.getUserMedia = () => Promise.resolve(stream); }; document.querySelector("body").appendChild(video); });
- the key is to return
Promise.resolve(stream)
oncanplay
is better thanonplay
because it is triggered after the video is playable
This flags are still necessary:
'--use-fake-ui-for-media-stream','--use-fake-device-for-media-stream',
In the end, with this script different camera mocks are possible for every page - especially useful when using browserless!
Mocked/Fake Raw Video (2021)
Use y4m if you want raw frames without Chrome having to run a decoder:
ffmpeg -i original.avi -pix_fmt yuv420p video-for-chrome.y4m
Then, start Chrome:
chrome.exe --user-fake-device-for-media-stream --use-file-for-fake-video-capture=video-for-chrome.y4m
Note: There is no longer any reason to have to modify your y4m file's header. Chrome has since been fixed.
This method uses less CPU, but will take up a good deal of hard drive space for the raw video. Keep your video file short. Chrome will loop it.