fix(01-review): sweep #1 stopRecording nulls mediaStream first to prevent rotation race
This commit is contained in:
@@ -359,16 +359,40 @@ function onUserStoppedSharing(): void {
|
||||
}
|
||||
|
||||
function stopRecording(): void {
|
||||
// Отменяем будущую ротацию, чтобы rotateSegment не дёрнул stop() на
|
||||
// уже остановленном рекордере.
|
||||
// Sweep #1 fix: race between rotateSegment / onSegmentStopped and a
|
||||
// STOP_RECORDING that does NOT null the mediaStream. The previous
|
||||
// implementation cleared the rotation timer and called .stop(), which
|
||||
// triggers onSegmentStopped async; onSegmentStopped then unconditionally
|
||||
// calls startNewSegment() whenever `mediaStream !== null`. Result: after
|
||||
// a manual STOP_RECORDING, a new segment would spawn anyway and the
|
||||
// recorder kept rolling silently. The fix mirrors onUserStoppedSharing:
|
||||
// null the mediaStream FIRST so onSegmentStopped's gate sees the stopped
|
||||
// state, then stop the recorder and release the tracks. This also fixes
|
||||
// the secondary issue of leaked MediaStreamTracks (the picker indicator
|
||||
// would have stayed up until the operator manually clicked "Stop
|
||||
// sharing" in Chrome's UI).
|
||||
if (rotationTimerId !== null) {
|
||||
clearTimeout(rotationTimerId);
|
||||
rotationTimerId = null;
|
||||
}
|
||||
// Capture stream before nulling so we can release its tracks.
|
||||
const streamToStop = mediaStream;
|
||||
mediaStream = null;
|
||||
if (videoRecorder !== null && videoRecorder.state !== 'inactive') {
|
||||
videoRecorder.stop();
|
||||
try {
|
||||
videoRecorder.stop();
|
||||
} catch (err) {
|
||||
logger.warn('stop() during stopRecording failed:', err);
|
||||
}
|
||||
logger.log('Recording stopped manually');
|
||||
}
|
||||
if (streamToStop !== null) {
|
||||
streamToStop.getTracks().forEach((t) => t.stop());
|
||||
}
|
||||
// Note: we do NOT call resetBuffer() here — the operator may want to
|
||||
// STOP and then SAVE the buffered footage. resetBuffer happens on
|
||||
// onUserStoppedSharing (operator dismissed Chrome's sharing indicator)
|
||||
// and at the start of the next startRecording().
|
||||
}
|
||||
|
||||
// ─── Bootstrap: handshake + port lifecycle (D-17, RESEARCH.md Patterns 4 & 5) ──
|
||||
|
||||
Reference in New Issue
Block a user