Fix YouTube relay instabile e timer LIVE a zero in app
ffmpeg: probesize/analyzeduration su _air, restart più rapido e avvio relay al go_live. App: sincronizza started_at dal server e fallback al passaggio live. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -17,7 +17,9 @@ module Mediamtx
|
||||
# RTMP ancora connesso in pausa: non forzare live/reconnect.
|
||||
elsif @session.may_go_live?
|
||||
@session.go_live!
|
||||
Streams::Overlay::Refresh.call(@session.reload)
|
||||
@session.reload
|
||||
Streams::Overlay::Refresh.call(@session)
|
||||
Streams::YoutubeRelay.ensure_publishing!(@session) if @session.platform == "youtube"
|
||||
elsif @session.reconnecting? && @session.may_reconnect?
|
||||
@session.reconnect!
|
||||
cancel_timeout
|
||||
|
||||
@@ -56,10 +56,13 @@ module Streams
|
||||
return if session.stream_key.blank?
|
||||
return unless Streams::OverlayRelay.running?(session.id)
|
||||
|
||||
pid = pid_for(session.id)
|
||||
clear_pid(session.id) if pid.present? && !process_alive?(pid.to_i)
|
||||
|
||||
return if running?(session.id)
|
||||
|
||||
last_restart = redis.get(restart_debounce_key(session.id)).to_i
|
||||
return if last_restart.positive? && (Time.now.to_i - last_restart) < 20
|
||||
return if last_restart.positive? && (Time.now.to_i - last_restart) < 5
|
||||
|
||||
start(session)
|
||||
redis.set(restart_debounce_key(session.id), Time.now.to_i, ex: 300)
|
||||
@@ -75,6 +78,7 @@ module Streams
|
||||
[
|
||||
"ffmpeg", "-nostdin", "-hide_banner", "-loglevel", "warning",
|
||||
"-fflags", "+genpts+discardcorrupt", "-use_wallclock_as_timestamps", "1",
|
||||
"-analyzeduration", "10000000", "-probesize", "10000000",
|
||||
"-rw_timeout", "15000000",
|
||||
"-i", intake,
|
||||
"-f", "lavfi", "-i", "anullsrc=channel_layout=mono:sample_rate=48000",
|
||||
|
||||
@@ -41,6 +41,7 @@ class _CameraScreenState extends ConsumerState<CameraScreen> {
|
||||
static const _previewKey = ValueKey<String>('camera_streaming_preview');
|
||||
|
||||
Timer? _elapsedTimer;
|
||||
Timer? _sessionSyncTimer;
|
||||
Timer? _telemetryTimer;
|
||||
Timer? _statsTimer;
|
||||
Timer? _scorePullTimer;
|
||||
@@ -75,6 +76,9 @@ class _CameraScreenState extends ConsumerState<CameraScreen> {
|
||||
);
|
||||
}
|
||||
});
|
||||
_sessionSyncTimer = Timer.periodic(const Duration(seconds: 15), (_) {
|
||||
unawaited(_syncSessionStartedAt());
|
||||
});
|
||||
_telemetryTimer = Timer.periodic(const Duration(seconds: 10), (_) => _sendTelemetry());
|
||||
_statsTimer = Timer.periodic(const Duration(seconds: 30), (_) => _fetchStats());
|
||||
_scorePullTimer = Timer.periodic(const Duration(seconds: 2), (_) {
|
||||
@@ -263,6 +267,20 @@ class _CameraScreenState extends ConsumerState<CameraScreen> {
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
/// Il server imposta `started_at` solo al primo go_live; sincronizza per il timer LIVE.
|
||||
Future<void> _syncSessionStartedAt() async {
|
||||
final current = ref.read(sessionProvider).session;
|
||||
if (current == null || current.startedAt != null || !current.isLive) return;
|
||||
try {
|
||||
final fresh = await ref.read(apiClientProvider).fetchSession(widget.sessionId);
|
||||
if (!mounted || fresh.startedAt == null) return;
|
||||
ref.read(sessionProvider.notifier).setSession(
|
||||
fresh,
|
||||
match: ref.read(sessionProvider).match,
|
||||
);
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
Future<void> _lockOrientations() async {
|
||||
await SystemChrome.setPreferredOrientations([
|
||||
DeviceOrientation.landscapeLeft,
|
||||
@@ -497,6 +515,7 @@ class _CameraScreenState extends ConsumerState<CameraScreen> {
|
||||
@override
|
||||
void dispose() {
|
||||
_elapsedTimer?.cancel();
|
||||
_sessionSyncTimer?.cancel();
|
||||
_telemetryTimer?.cancel();
|
||||
_statsTimer?.cancel();
|
||||
_scorePullTimer?.cancel();
|
||||
|
||||
@@ -111,6 +111,8 @@ class SessionNotifier extends StateNotifier<SessionState> {
|
||||
state = state.copyWith(cameraDevice: device);
|
||||
return;
|
||||
}
|
||||
final startedAt = s.startedAt ??
|
||||
((incoming == 'live' || incoming == 'reconnecting') ? DateTime.now() : null);
|
||||
state = state.copyWith(
|
||||
session: StreamSession(
|
||||
id: s.id,
|
||||
@@ -127,7 +129,7 @@ class SessionNotifier extends StateNotifier<SessionState> {
|
||||
privacyStatus: s.privacyStatus,
|
||||
qualityPreset: s.qualityPreset,
|
||||
targetBitrate: s.targetBitrate,
|
||||
startedAt: s.startedAt,
|
||||
startedAt: startedAt,
|
||||
disconnectionCount: s.disconnectionCount,
|
||||
score: s.score,
|
||||
devices: s.devices,
|
||||
|
||||
Reference in New Issue
Block a user