-
-
Notifications
You must be signed in to change notification settings - Fork 185
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Transcode server for remote #611
base: main
Are you sure you want to change the base?
Changes from all commits
537e992
44ead95
1c5ab8d
5b3d455
ff6b2f4
0ef96a5
8c3097c
fc0b06f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -38,6 +38,14 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// ================================================================================================= | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// transcode | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const ffmpegPath = require('@ffmpeg-installer/ffmpeg').path.replace('app.asar', 'app.asar.unpacked'); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const spawn = require('child_process').spawn; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const onFinished = require('on-finished'); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// --- | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export function setUpIpcForServer(ipc) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ipc.on('latest-gallery-view', (event, data): void => { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -94,6 +102,38 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// res.end(); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// }); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
app.get('/video', (req, res) => { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const seekTime = req.query.seek || 0; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const file = req.query.file || ''; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// see https://trac.ffmpeg.org/wiki/Encode/H.264#a2.Chooseapreset for more options | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const ffmpeg = spawn(ffmpegPath, [ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
'-ss', seekTime, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
'-i', file, | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
'-f', 'mp4', | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
'-crf', '17', | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
'-preset', 'ultrafast', | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
'-movflags', 'frag_keyframe+empty_moov+faststart', | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
'-frag_duration', '15', | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
'pipe:1' | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
]); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
res.writeHead(200, { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
'Content-Type': 'video/mp4' | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ffmpeg.stdout.pipe(res); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// error logging | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ffmpeg.stderr.setEncoding('utf8'); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ffmpeg.stderr.on('data', (data) => { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
console.log(data); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
onFinished(res, () => { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
console.log('about to kill!'); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ffmpeg.kill(); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+106
to
+133
Check failure Code scanning / CodeQL Missing rate limiting High
This route handler performs
a system command Error loading related location Loading
Copilot Autofix AI 4 months ago To fix the problem, we will introduce rate limiting to the Express application using the
Suggested changeset
2
node/server.ts
package.json
Outside changed files
This fix introduces these dependencies
Copilot is powered by AI and may make mistakes. Always verify output.
Refresh and try again.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Serve the Angular VHA remote control app | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
app.use(express.static(remoteAppPath)); | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can probably remove this - I think it might have a sensible default anyway. We can change it later.
The idea with fragmenting, is that you can seek and stream much easier, without having to download the entire mp4 file before playback can begin. Each fragment contains metadata about the video, rather than all the metadata being store at the end of the file!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can look into finding the best options, but if the code works as is, may as well use that for now!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Cal for looking at this again. I've paused this feature for a while because I had at least two days of trying hard with no success: getting the video to play in Chrome ✅ no problem 👌 but getting Safari on iOS (on my phone) to play anything was a no-go 😓 which is the sole purpose of this feature.
I'll come back to this with renewed energy once I move in to the new house (these few months have been busy).
😅 also I've been working on an image-centric analogous-to-VHA app this past month -- I want to finish it first before returning to this headache![:trollface: :trollface:](https://github.githubassets.com/images/icons/emoji/trollface.png)