Fix segment deletion and add progress callback
- Remove stream_dir deletion in finally block to prevent IPFS upload failures - Add on_progress callback to StreamInterpreter for real-time progress updates - Task now sends progress updates to Celery state during rendering Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -94,6 +94,10 @@ class StreamInterpreter:
|
||||
# Callback for live streaming (called when IPFS playlist is updated)
|
||||
self.on_playlist_update: callable = None
|
||||
|
||||
# Callback for progress updates (called periodically during rendering)
|
||||
# Signature: on_progress(percent: float, frame_num: int, total_frames: int)
|
||||
self.on_progress: callable = None
|
||||
|
||||
def _resolve_name(self, name: str) -> Optional[Path]:
|
||||
"""Resolve a friendly name to a file path using the naming service."""
|
||||
try:
|
||||
@@ -888,6 +892,7 @@ class StreamInterpreter:
|
||||
try:
|
||||
from .output import PipeOutput, DisplayOutput, FileOutput, HLSOutput, IPFSHLSOutput
|
||||
from .gpu_output import GPUHLSOutput, check_gpu_encode_available
|
||||
from .multi_res_output import MultiResolutionHLSOutput
|
||||
except ImportError:
|
||||
from output import PipeOutput, DisplayOutput, FileOutput, HLSOutput, IPFSHLSOutput
|
||||
try:
|
||||
@@ -895,6 +900,10 @@ class StreamInterpreter:
|
||||
except ImportError:
|
||||
GPUHLSOutput = None
|
||||
check_gpu_encode_available = lambda: False
|
||||
try:
|
||||
from multi_res_output import MultiResolutionHLSOutput
|
||||
except ImportError:
|
||||
MultiResolutionHLSOutput = None
|
||||
|
||||
self._init()
|
||||
|
||||
@@ -945,13 +954,23 @@ class StreamInterpreter:
|
||||
hls_dir = output[:-4] # Remove /hls suffix
|
||||
out = HLSOutput(hls_dir, size=(w, h), fps=fps, audio_source=audio)
|
||||
elif output.endswith("/ipfs-hls"):
|
||||
# IPFS HLS output - segments uploaded to IPFS as they're created
|
||||
# IPFS HLS output - multi-resolution adaptive streaming
|
||||
hls_dir = output[:-9] # Remove /ipfs-hls suffix
|
||||
import os
|
||||
ipfs_gateway = os.environ.get("IPFS_GATEWAY_URL", "https://ipfs.io/ipfs")
|
||||
# Use GPU encoding if available (zero-copy, much faster)
|
||||
if GPUHLSOutput is not None and check_gpu_encode_available():
|
||||
print(f"[StreamInterpreter] Using GPU zero-copy encoding", file=sys.stderr)
|
||||
# Use multi-resolution output (renders original + 720p + 360p)
|
||||
if MultiResolutionHLSOutput is not None:
|
||||
print(f"[StreamInterpreter] Using multi-resolution HLS output ({w}x{h} + 720p + 360p)", file=sys.stderr)
|
||||
out = MultiResolutionHLSOutput(
|
||||
hls_dir,
|
||||
source_size=(w, h),
|
||||
fps=fps,
|
||||
ipfs_gateway=ipfs_gateway,
|
||||
on_playlist_update=self.on_playlist_update
|
||||
)
|
||||
# Fallback to GPU single-resolution if multi-res not available
|
||||
elif GPUHLSOutput is not None and check_gpu_encode_available():
|
||||
print(f"[StreamInterpreter] Using GPU zero-copy encoding (single resolution)", file=sys.stderr)
|
||||
out = GPUHLSOutput(hls_dir, size=(w, h), fps=fps, audio_source=audio, ipfs_gateway=ipfs_gateway,
|
||||
on_playlist_update=self.on_playlist_update)
|
||||
else:
|
||||
@@ -1014,6 +1033,13 @@ class StreamInterpreter:
|
||||
target_ms = 1000 * frame_time
|
||||
print(f"\r{pct:5.1f}% [{avg_ms:.0f}ms/frame, target {target_ms:.0f}ms] scan={avg_scan:.0f}ms eval={avg_eval:.0f}ms write={avg_write:.0f}ms", end="", file=sys.stderr, flush=True)
|
||||
|
||||
# Call progress callback if set (for Celery task state updates)
|
||||
if self.on_progress:
|
||||
try:
|
||||
self.on_progress(pct, frame_num, n_frames)
|
||||
except Exception as e:
|
||||
print(f"Warning: progress callback failed: {e}", file=sys.stderr)
|
||||
|
||||
finally:
|
||||
out.close()
|
||||
# Store output for access to properties like playlist_cid
|
||||
|
||||
Reference in New Issue
Block a user