Summary
The automatic-push editor silently couples the connection schedule (scheduletime) to the media playback position (startunix). Saving a new scheduled auto push with an empty playback-start field fills that field with the schedule timestamp. Editing a schedule can also overwrite an explicit playback-start value that the user has not edited.
For a continuous live relay, that absolute playback timestamp persists in the destination URL and is reused on subsequent connections. We encountered failed recovery on an RTMP output with an old scheduled start in its saved target. Please confirm whether the implicit coupling is intentional; if so, its live-reconnect implications and UI behavior need clarification.
Version / scope
- Reproduced at source/UI-handler level on official tag 3.11.2, commit
51b50c59d75e9937b2ce2660bfa97437bd64b6b5.
- The same assignment block is still present in
master/lsp/mist.js as retrieved on 2026-09-07.
- Linux ARM64, Docker; continuous H.264/AAC live input, RTMP platform outputs, approximately 8 Mbps, no relay transcoding.
- No credentials, real ingest URLs, or customer server addresses are included here.
Code path
Automatic-push editor preSave in the tested commit
Within other == "auto":
- New rule: when
scheduletime is set and startunix is empty, the handler writes scheduletime into startunix.
- Existing rule: when the old rule has both fields, changing the schedule while leaving the media-start field unchanged rewrites the latter to the new schedule.
Minimal reproduction
On a disposable instance / local test destination:
- Create an automatic push for a live stream, e.g.
live_test, targeting rtmp://127.0.0.1:19350/live/test.
- Set a connection start schedule to a future time T. Leave playback start /
startunix empty.
- Save and inspect the saved auto-push target through the API/config.
- Observe an added
startunix=T query parameter, despite not requesting historical playback.
- Independently test editing: load a rule with a schedule and an explicit playback start, change only the schedule, save. The untouched playback-start value is overwritten under the condition above.
Steps 1-5 describe the UI reproduction path; our deterministic reproduction executes the actual extracted preSave function, not a full authenticated browser-click test. A minimal handler regression test is below.
For the operational failure path, allow the original start timestamp to become old relative to the live buffer, then reconnect the push. The exact result may depend on stream buffering and output behavior; please investigate that downstream behavior separately rather than treating every reconnect failure as this bug.
Expected
Connection scheduling and requested media position should be independent:
- Empty playback start remains empty for ordinary live output.
- An explicitly supplied playback-start value remains unchanged when only the schedule changes.
- Future schedules still gate when to connect.
- Intentional historical playback through the API remains supported.
If synchronized historical playback is a required feature, an explicit opt-in UI control would avoid silently applying it to normal live relays.
Operational evidence and limits
- A YouTube output disconnected after approximately 25 hours while the original input and other outputs remained healthy. The cause of that initial disconnect is not established; this report is not a claim of a YouTube duration limit.
- During failed recovery, the saved auto-push had an old
scheduletime and matching startunix; connection attempts transmitted an initial small amount of data and then failed to progress.
- Removing both the elapsed schedule and its matching unintended playback-start parameter restored approximately 8 Mbps transmission. A controlled stop of that output subsequently recovered automatically. Because both fields were cleaned, this operational intervention alone does not isolate all downstream causality.
- A local patch removing only the UI assignment block was subsequently built into MistController, leaving input/output binaries unchanged. Existing live rules had already been migrated before deployment.
- Five outputs recovered after a controlled deployment restart and continued advancing bytes/media time at roughly 8 Mbps each. Internal reported output latency settled around tens of milliseconds rather than accumulating. The operator also confirmed smooth actual playback.
- Long-duration post-patch testing is ongoing. This is not evidence that every timestamp discontinuity or network failure is resolved, nor that a native C++ RTMP timestamp bug was fixed.
Suggested change
Remove the automatic assignment/reassignment of startunix from the auto-push editor's preSave handler, preserving explicit user/API requests. Regenerate the embedded/minified UI as part of the build.
Migration and compatibility considerations:
- Previously saved target URLs require separate review; deploying new UI does not rewrite them.
- Do not indiscriminately strip historical parameters from intentional timeshift/recording rules.
- Existing management tabs must reload to stop executing cached old UI.
- Please assess any intended scheduled-recording semantics before adopting the change globally.
Minimal regression test
Run from the repository root with Node.js. This extracts and executes the actual preSave body with mocked form fields. The first case fails on the tested upstream source and all four pass after removing the assignment block.
const fs = require('fs');
const vm = require('vm');
const assert = require('assert');
const src = fs.readFileSync('lsp/mist.js', 'utf8');
const start = src.indexOf(
'preSave: function(){',
src.indexOf('//contains the part that comes after the ?')
);
assert(start > 0);
const bodyStart = src.indexOf('{', start) + 1;
const end = src.indexOf('\n },', bodyStart);
assert(end > bodyStart);
const body = src.slice(bodyStart, end);
for (const s of [
{name: 'new live schedule', date: 200, seek: undefined},
{name: 'explicit history', date: 200, seek: 100},
{name: 'edit schedule, preserve old seek', date: 300, seek: 100, old: 100},
{name: 'no schedule', date: undefined, seek: undefined},
]) {
const fields = {scheduletime: s.date, startunix: s.seek};
const before = {...fields};
const context = {
other: 'auto',
editid: s.old ? 'id' : undefined,
saveas: {params: {startunix: s.seek}, scheduletime: s.old},
$: selector => {
const name = selector.match(/name="(.*?)"/)[1];
return {
getval: () => fields[name],
setval: value => { fields[name] = value; }
};
}
};
vm.runInNewContext('(function(){' + body + '})()', context);
assert.deepStrictEqual(fields, before, s.name);
}
Related report
#290 describes an automatic-push recovery symptom, but its maintainer response identifies recording/resume track mapping and playlist behavior. This report is deliberately scoped to the independent UI scheduling/playback-position mutation; we are not claiming those have the same root cause.
Thank you for maintaining MistServer. Happy to clarify the reproduction and distinguish intended scheduling behavior from the live-relay use case.
Summary
The automatic-push editor silently couples the connection schedule (
scheduletime) to the media playback position (startunix). Saving a new scheduled auto push with an empty playback-start field fills that field with the schedule timestamp. Editing a schedule can also overwrite an explicit playback-start value that the user has not edited.For a continuous live relay, that absolute playback timestamp persists in the destination URL and is reused on subsequent connections. We encountered failed recovery on an RTMP output with an old scheduled start in its saved target. Please confirm whether the implicit coupling is intentional; if so, its live-reconnect implications and UI behavior need clarification.
Version / scope
51b50c59d75e9937b2ce2660bfa97437bd64b6b5.master/lsp/mist.jsas retrieved on 2026-09-07.Code path
Automatic-push editor preSave in the tested commit
Within
other == "auto":scheduletimeis set andstartunixis empty, the handler writesscheduletimeintostartunix.Minimal reproduction
On a disposable instance / local test destination:
live_test, targetingrtmp://127.0.0.1:19350/live/test.startunixempty.startunix=Tquery parameter, despite not requesting historical playback.Steps 1-5 describe the UI reproduction path; our deterministic reproduction executes the actual extracted preSave function, not a full authenticated browser-click test. A minimal handler regression test is below.
For the operational failure path, allow the original start timestamp to become old relative to the live buffer, then reconnect the push. The exact result may depend on stream buffering and output behavior; please investigate that downstream behavior separately rather than treating every reconnect failure as this bug.
Expected
Connection scheduling and requested media position should be independent:
If synchronized historical playback is a required feature, an explicit opt-in UI control would avoid silently applying it to normal live relays.
Operational evidence and limits
scheduletimeand matchingstartunix; connection attempts transmitted an initial small amount of data and then failed to progress.Suggested change
Remove the automatic assignment/reassignment of
startunixfrom the auto-push editor's preSave handler, preserving explicit user/API requests. Regenerate the embedded/minified UI as part of the build.Migration and compatibility considerations:
Minimal regression test
Run from the repository root with Node.js. This extracts and executes the actual preSave body with mocked form fields. The first case fails on the tested upstream source and all four pass after removing the assignment block.
Related report
#290 describes an automatic-push recovery symptom, but its maintainer response identifies recording/resume track mapping and playlist behavior. This report is deliberately scoped to the independent UI scheduling/playback-position mutation; we are not claiming those have the same root cause.
Thank you for maintaining MistServer. Happy to clarify the reproduction and distinguish intended scheduling behavior from the live-relay use case.