toposync-ext-streaming 0.4.1__tar.gz → 0.4.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/PKG-INFO +1 -1
  2. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/pyproject.toml +1 -1
  3. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/api/routes.py +32 -1
  4. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/.gitignore +0 -0
  5. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/LICENSE +0 -0
  6. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/LICENSE.ffmpeg +0 -0
  7. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/LICENSE.mediamtx +0 -0
  8. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/README.md +0 -0
  9. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/__init__.py +0 -0
  10. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/api/__init__.py +0 -0
  11. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/api/models.py +0 -0
  12. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/bin/ffmpeg/LICENSE +0 -0
  13. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/bin/mediamtx/LICENSE +0 -0
  14. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/extension.json +0 -0
  15. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/pipelines/__init__.py +0 -0
  16. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/pipelines/operators.py +0 -0
  17. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/plugin.py +0 -0
  18. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/static/326.js +0 -0
  19. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/static/326.js.LICENSE.txt +0 -0
  20. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/static/4.js +0 -0
  21. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/static/4.js.LICENSE.txt +0 -0
  22. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/static/623.js +0 -0
  23. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/static/623.js.LICENSE.txt +0 -0
  24. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/static/703.js +0 -0
  25. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/static/703.js.LICENSE.txt +0 -0
  26. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/static/main.js +0 -0
  27. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/static/main.js.LICENSE.txt +0 -0
  28. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/static/remoteEntry.js +0 -0
  29. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/__init__.py +0 -0
  30. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/arbitration.py +0 -0
  31. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/camera_ingest.py +0 -0
  32. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/distributed_sync.py +0 -0
  33. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/encoder_state.py +0 -0
  34. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/engine_manager.py +0 -0
  35. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/ffmpeg_binary.py +0 -0
  36. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/go2rtc_binary.py +0 -0
  37. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/go2rtc_config.py +0 -0
  38. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/go2rtc_manager.py +0 -0
  39. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/ingest_auth.py +0 -0
  40. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/ingest_resolver.py +0 -0
  41. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/jsmpeg_manager.py +0 -0
  42. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/mediamtx_api_client.py +0 -0
  43. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/mediamtx_binary.py +0 -0
  44. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/mediamtx_config.py +0 -0
  45. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/mediamtx_processes.py +0 -0
  46. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/placeholder.py +0 -0
  47. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/platform.py +0 -0
  48. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/playback_events.py +0 -0
  49. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/publisher_manager.py +0 -0
  50. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/resize.py +0 -0
  51. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/runtime_state.py +0 -0
  52. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/streaming/writer_bridge.py +0 -0
  53. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/wizard/__init__.py +0 -0
  54. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/src/toposync_ext_streaming/wizard/pipeline_builder.py +0 -0
  55. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/ui/package.json +0 -0
  56. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/ui/src/activate.tsx +0 -0
  57. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/ui/src/api/streamingApi.ts +0 -0
  58. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/ui/src/constants.ts +0 -0
  59. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/ui/src/entry.ts +0 -0
  60. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/ui/src/settings/StreamingSettingsPanel.tsx +0 -0
  61. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/ui/src/settings/SubModal.tsx +0 -0
  62. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/ui/src/settings/WizardCreatePipelineFromTransmission.tsx +0 -0
  63. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/ui/src/translations.ts +0 -0
  64. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/ui/src/types.ts +0 -0
  65. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/ui/tsconfig.json +0 -0
  66. {toposync_ext_streaming-0.4.1 → toposync_ext_streaming-0.4.2}/ui/webpack.config.js +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: toposync-ext-streaming
3
- Version: 0.4.1
3
+ Version: 0.4.2
4
4
  Summary: Toposync first-party extension: streaming settings, API surface, and pipeline sink bootstrap.
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "toposync-ext-streaming"
3
- version = "0.4.1"
3
+ version = "0.4.2"
4
4
  description = "Toposync first-party extension: streaming settings, API surface, and pipeline sink bootstrap."
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -518,6 +518,7 @@ def _hls_proxy_public_base_path(request: Request) -> str:
518
518
 
519
519
  MEDIA_TOKEN_SCOPE = "stream:media:read"
520
520
  LEGACY_HLS_MEDIA_TOKEN_SCOPE = "stream:hls:read"
521
+ MAX_MEDIA_TOKEN_TTL_OVERRIDE_SECONDS = 1800.0
521
522
 
522
523
 
523
524
  def _hls_proxy_url(
@@ -651,9 +652,18 @@ def _issue_media_token(
651
652
  output: TransmissionOutput,
652
653
  engine_path: str,
653
654
  transport: Literal["hls", "mse", "jsmpeg"],
655
+ ttl_seconds: float | None = None,
654
656
  ) -> tuple[str, float, float]:
655
657
  now = time.time()
656
- ttl_s = max(30.0, float(settings.engine.media_auth.token_ttl_seconds))
658
+ configured_ttl_s = max(30.0, float(settings.engine.media_auth.token_ttl_seconds))
659
+ if ttl_seconds is not None:
660
+ requested_ttl_s = max(
661
+ 30.0,
662
+ min(float(ttl_seconds), MAX_MEDIA_TOKEN_TTL_OVERRIDE_SECONDS),
663
+ )
664
+ ttl_s = max(configured_ttl_s, requested_ttl_s)
665
+ else:
666
+ ttl_s = configured_ttl_s
657
667
  renew_margin_s = max(1.0, float(settings.engine.media_auth.renew_margin_seconds))
658
668
  expires_at = now + ttl_s
659
669
  renew_after = max(now, expires_at - min(renew_margin_s, ttl_s - 1.0))
@@ -680,6 +690,7 @@ def _issue_hls_media_token(
680
690
  transmission: Transmission,
681
691
  output: TransmissionOutput,
682
692
  engine_path: str,
693
+ ttl_seconds: float | None = None,
683
694
  ) -> tuple[str, float, float]:
684
695
  return _issue_media_token(
685
696
  config_store=config_store,
@@ -688,6 +699,7 @@ def _issue_hls_media_token(
688
699
  output=output,
689
700
  engine_path=engine_path,
690
701
  transport="hls",
702
+ ttl_seconds=ttl_seconds,
691
703
  )
692
704
 
693
705
 
@@ -1535,6 +1547,7 @@ async def _resolve_local_transmission_urls(
1535
1547
  transmission: Transmission,
1536
1548
  output_id: str | None = None,
1537
1549
  quality_profile_id: str | None = None,
1550
+ media_token_ttl_seconds: float | None = None,
1538
1551
  ) -> TransmissionUrlsResponse:
1539
1552
  bridge = _writer_bridge(request)
1540
1553
  prime_demand = getattr(bridge, "prime_transmission_demand", None)
@@ -1672,6 +1685,7 @@ async def _resolve_local_transmission_urls(
1672
1685
  transmission=transmission,
1673
1686
  output=output,
1674
1687
  engine_path=engine_path,
1688
+ ttl_seconds=media_token_ttl_seconds,
1675
1689
  )
1676
1690
  url = _hls_proxy_url(request, engine_path, media_token=media_token) or ""
1677
1691
  media_auth_type = "signed_url"
@@ -1701,6 +1715,7 @@ async def _resolve_local_transmission_urls(
1701
1715
  output=output,
1702
1716
  engine_path=engine_path,
1703
1717
  transport="mse",
1718
+ ttl_seconds=media_token_ttl_seconds,
1704
1719
  )
1705
1720
  outputs.append(
1706
1721
  TransmissionOutputUrl(
@@ -1724,6 +1739,7 @@ async def _resolve_local_transmission_urls(
1724
1739
  output=output,
1725
1740
  engine_path=engine_path,
1726
1741
  transport="jsmpeg",
1742
+ ttl_seconds=media_token_ttl_seconds,
1727
1743
  )
1728
1744
  outputs.append(
1729
1745
  TransmissionOutputUrl(
@@ -1776,6 +1792,7 @@ async def _resolve_local_transmission_urls(
1776
1792
  output=output,
1777
1793
  engine_path=engine_path,
1778
1794
  transport="mse",
1795
+ ttl_seconds=media_token_ttl_seconds,
1779
1796
  )
1780
1797
  outputs.append(
1781
1798
  TransmissionOutputUrl(
@@ -1799,6 +1816,7 @@ async def _resolve_local_transmission_urls(
1799
1816
  output=output,
1800
1817
  engine_path=engine_path,
1801
1818
  transport="jsmpeg",
1819
+ ttl_seconds=media_token_ttl_seconds,
1802
1820
  )
1803
1821
  outputs.append(
1804
1822
  TransmissionOutputUrl(
@@ -1846,6 +1864,7 @@ async def _resolve_remote_transmission_urls(
1846
1864
  transmission: Transmission,
1847
1865
  output_id: str | None = None,
1848
1866
  quality_profile_id: str | None = None,
1867
+ media_token_ttl_seconds: float | None = None,
1849
1868
  ) -> TransmissionUrlsResponse:
1850
1869
  servers_by_id = await _processing_servers_by_id(config_store)
1851
1870
  host_server_id = normalize_server_id(transmission.host_server_id, fallback="local")
@@ -1872,6 +1891,7 @@ async def _resolve_remote_transmission_urls(
1872
1891
  for key, value in {
1873
1892
  "output_id": str(output_id or "").strip(),
1874
1893
  "quality_profile_id": str(quality_profile_id or "").strip(),
1894
+ "media_token_ttl_seconds": str(media_token_ttl_seconds or "").strip(),
1875
1895
  }.items()
1876
1896
  if value
1877
1897
  }
@@ -6285,6 +6305,7 @@ def create_streaming_router() -> APIRouter:
6285
6305
  live_view_id: str,
6286
6306
  context: StreamingCameraLiveContext = "thumbnail",
6287
6307
  variant_id: str | None = None,
6308
+ media_token_ttl_seconds: float | None = None,
6288
6309
  ) -> CameraLiveViewPlaybackResponse:
6289
6310
  _require_auth(request, action="core:settings:read")
6290
6311
  config_store = _config_store(request)
@@ -6338,12 +6359,14 @@ def create_streaming_router() -> APIRouter:
6338
6359
  settings=settings,
6339
6360
  transmission=transmission,
6340
6361
  quality_profile_id=variant.quality_profile_id,
6362
+ media_token_ttl_seconds=media_token_ttl_seconds,
6341
6363
  )
6342
6364
  else:
6343
6365
  urls = await _resolve_remote_transmission_urls(
6344
6366
  config_store=config_store,
6345
6367
  transmission=transmission,
6346
6368
  quality_profile_id=variant.quality_profile_id,
6369
+ media_token_ttl_seconds=media_token_ttl_seconds,
6347
6370
  )
6348
6371
 
6349
6372
  selected_output = _select_live_playback_output(urls=urls, variant=variant)
@@ -7435,6 +7458,7 @@ def create_streaming_router() -> APIRouter:
7435
7458
  transmission_id: str,
7436
7459
  output_id: str | None = None,
7437
7460
  quality_profile_id: str | None = None,
7461
+ media_token_ttl_seconds: float | None = None,
7438
7462
  ) -> TransmissionUrlsResponse:
7439
7463
  _require_auth(request, action="core:settings:read")
7440
7464
  config_store = _config_store(request)
@@ -7456,12 +7480,14 @@ def create_streaming_router() -> APIRouter:
7456
7480
  transmission=transmission,
7457
7481
  output_id=output_id,
7458
7482
  quality_profile_id=quality_profile_id,
7483
+ media_token_ttl_seconds=media_token_ttl_seconds,
7459
7484
  )
7460
7485
  return await _resolve_remote_transmission_urls(
7461
7486
  config_store=config_store,
7462
7487
  transmission=transmission,
7463
7488
  output_id=output_id,
7464
7489
  quality_profile_id=quality_profile_id,
7490
+ media_token_ttl_seconds=media_token_ttl_seconds,
7465
7491
  )
7466
7492
 
7467
7493
  @router.get(
@@ -7476,6 +7502,7 @@ def create_streaming_router() -> APIRouter:
7476
7502
  quality_profile_id: str | None = None,
7477
7503
  context: StreamingCameraLiveContext | None = None,
7478
7504
  low_latency: bool = False,
7505
+ media_token_ttl_seconds: float | None = None,
7479
7506
  ) -> StreamingPlaybackPlanResponse:
7480
7507
  _require_auth(request, action="core:settings:read")
7481
7508
  config_store = _config_store(request)
@@ -7493,6 +7520,7 @@ def create_streaming_router() -> APIRouter:
7493
7520
  transmission=transmission,
7494
7521
  output_id=output_id,
7495
7522
  quality_profile_id=quality_profile_id,
7523
+ media_token_ttl_seconds=media_token_ttl_seconds,
7496
7524
  )
7497
7525
  runtime_health: StreamingRuntimeTransmissionHealth | None = None
7498
7526
  try:
@@ -7509,6 +7537,7 @@ def create_streaming_router() -> APIRouter:
7509
7537
  transmission=transmission,
7510
7538
  output_id=output_id,
7511
7539
  quality_profile_id=quality_profile_id,
7540
+ media_token_ttl_seconds=media_token_ttl_seconds,
7512
7541
  )
7513
7542
  runtime_health = None
7514
7543
 
@@ -7688,6 +7717,7 @@ def create_streaming_router() -> APIRouter:
7688
7717
  transmission_id: str,
7689
7718
  output_id: str | None = None,
7690
7719
  quality_profile_id: str | None = None,
7720
+ media_token_ttl_seconds: float | None = None,
7691
7721
  ) -> TransmissionUrlsResponse:
7692
7722
  _require_auth(request, action="core:settings:read")
7693
7723
  config_store = _config_store(request)
@@ -7716,6 +7746,7 @@ def create_streaming_router() -> APIRouter:
7716
7746
  transmission=transmission,
7717
7747
  output_id=output_id,
7718
7748
  quality_profile_id=quality_profile_id,
7749
+ media_token_ttl_seconds=media_token_ttl_seconds,
7719
7750
  )
7720
7751
 
7721
7752
  @router.get("/distributed/settings/{server_id}", response_model=StreamingExtensionSettings)