-
Notifications
You must be signed in to change notification settings - Fork 128
Open
Description
I am trying to create a close-to-realtime streaming implementation. The user should be able to remotely control the browser, so the streaming delay needs to be minimal. I tried different solutions, the most straight forward one is the following, but for some reason the video does not start playing, even though a lot of data has been streamed already.

Here is my (next.js) client code:
import React, { useState, useEffect, useRef } from 'react'
const VideoTestPage = () => {
const videoRef = useRef(null)
return (
<div>
<video
ref={videoRef}
src="/api/browsers/direct-video-test"
controls
autoPlay={true}
style={{ width: '100%', height: 'auto' }}
preload="none"
muted // Ensure autoplay works
></video>
</div>
)
}
export default VideoTestPage
And here the API endpoint code:
import { getStream, launch } from 'puppeteer-stream'
let browsers = {}
const startStreamingBrowser = async (userId, size, url) => {
const { width = 800, height = 600 } = size
let stream = null
try {
let browser = browsers[userId]
let page
if (!browser) {
console.log('start new browser')
browser = await launch({
//executablePath: utils.getExecutablePath(),
executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
defaultViewport: {
width: parseInt(width, 10),
height: parseInt(height, 10)
}
})
console.log('create new page')
page = await browser.newPage()
browser.page = page
browsers[userId] = browser
} else {
page = browser.page
}
console.log('go to url: ', url)
await page.goto(url)
stream = await getStream(page, { audio: true, video: true, frameSize: 200 })
stream.on('close', async () => {
await browser.close()
browsers[userId] = null
})
stream.on('error', async error => {
console.error('Error occurred:', error)
await browser.close()
browsers[userId] = null
})
stream.on('end', async () => {
console.log('Stream end -> closing browser instance')
try {
await browser.close()
} catch (error) {
console.log('Closing browser failed. Maybe browser was closed already manually...')
}
browsers[userId] = null
})
} catch (error) {
console.error('Error occurred:', error)
}
return stream
}
const stopStreamingBrowser = async userId => {
const browser = browsers[userId]
if (browser) {
await browser.close()
browsers[userId] = null
}
}
export default async function handler(req, res) {
console.log('browser endpoint', req.method)
const userId = 'test'
const stream = await startStreamingBrowser(
userId,
{ width: 800, height: 600 },
'https://giphy.com/clips/studiosoriginals-happy-birthday-grandson-Ny5rE4B0R6i1vqOOaj'
)
// Stream headers
res.setHeader('Content-Type', 'video/mp4');
res.setHeader('Transfer-Encoding', 'chunked');
res.setHeader('Connection', 'keep-alive');
stream.pipe(res)
}
export const config = {
api: {
responseLimit: false,
},
}
Any ideas how I could get this working?
Metadata
Metadata
Assignees
Labels
No labels