Compare commits

...

2 Commits

Author SHA1 Message Date
d37694e4d3 Refresh local videos on each listing request 2026-06-15 19:44:49 -07:00
0ad0df5612 realtime flag for http urls 2026-06-14 19:07:58 -07:00
2 changed files with 14 additions and 8 deletions

View File

@@ -110,7 +110,7 @@ Frame output:
- Maps `0:v:0`
- Disables audio with `-an`
- Applies `fps=<fps>,scale=w='min(<width>,iw)':h=-2:flags=bicubic:out_range=pc,format=yuvj420p`
- Applies `fps=<fps>,scale=w='min(<width>,iw)':h=-2:flags=bicubic:out_range=pc,format=yuvj420p,realtime`
- Encodes `mjpeg`
- Uses `-pix_fmt yuvj420p`, `-color_range pc`, `-q:v <quality>`
- Outputs `image2pipe` to either `pipe:1` or `pipe:3`

View File

@@ -132,6 +132,8 @@ app.get('/api/favorites', (_request, response) => {
});
app.get('/api/local-videos', async (_request, response) => {
response.set('Cache-Control', 'no-store');
if (!LOCAL_VIDEOS_ROOT) {
response.json({ enabled: false, videos: [] });
return;
@@ -658,10 +660,13 @@ function getLocalVideosRealRoot() {
}
if (!localVideosRealRootPromise) {
localVideosRealRootPromise = fs.realpath(LOCAL_VIDEOS_ROOT).catch((error) => {
localVideosRealRootPromise = null;
throw new Error(`Local videos directory is unavailable: ${error.message}`);
});
localVideosRealRootPromise = fs.realpath(LOCAL_VIDEOS_ROOT)
.catch((error) => {
throw new Error(`Local videos directory is unavailable: ${error.message}`);
})
.finally(() => {
localVideosRealRootPromise = null;
});
}
return localVideosRealRootPromise;
@@ -2798,6 +2803,7 @@ function buildFrameArgs(session, inputUrl, inputOptions) {
}
function buildInputArgs(inputUrl, { seekable = true, startTime = 0 } = {}) {
const isHttpInput = isHttpInputUrl(inputUrl);
const args = [
'-hide_banner',
'-nostdin',
@@ -2806,7 +2812,7 @@ function buildInputArgs(inputUrl, { seekable = true, startTime = 0 } = {}) {
'-nostats',
];
if (seekable) {
if (seekable && isHttpInput) {
args.push('-seekable', startTime > 0 ? '1' : FFMPEG_INPUT_SEEKABLE);
}
@@ -2814,7 +2820,7 @@ function buildInputArgs(inputUrl, { seekable = true, startTime = 0 } = {}) {
args.push('-ss', formatFfmpegSeconds(startTime));
}
if (FFMPEG_HTTP_RECONNECT && isHttpInputUrl(inputUrl)) {
if (FFMPEG_HTTP_RECONNECT && isHttpInput) {
args.push(
'-reconnect',
'1',
@@ -2849,7 +2855,7 @@ function formatFfmpegSeconds(seconds) {
function buildFrameOutputArgs(session, outputUrl) {
const { fps, quality, width } = session.options;
const videoFilter = `fps=${fps},scale=w='min(${width},iw)':h=-2:flags=bicubic:out_range=pc,format=yuvj420p`;
const videoFilter = `fps=${fps},scale=w='min(${width},iw)':h=-2:flags=bicubic:out_range=pc,format=yuvj420p,realtime`;
return [
'-an',