Skip to content

Commit 4f134e5

Browse files
authored
Merge pull request #92 from eth-ait/bugfix-video-export
Fix broken video export
2 parents b8433da + b0a4714 commit 4f134e5

2 files changed

Lines changed: 37 additions & 5 deletions

File tree

aitviewer/viewer.py

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Copyright (C) 2022-2026 ETH Zurich, Manuel Kaufmann, Velko Vechev, Dario Mylonopoulos
22
import copy
33
import os
4+
import subprocess
45
import sys
56
from array import array
67
from collections import namedtuple
@@ -31,6 +32,41 @@
3132
from aitviewer.utils.perf_timer import PerfTimer
3233
from aitviewer.utils.utils import get_video_paths, video_to_gif
3334

35+
36+
class FFmpegWriter:
37+
"""Thin ffmpeg pipe writer, replaces scikit-video which broke on NumPy 2.0."""
38+
39+
def __init__(self, path, inputdict, outputdict):
40+
self._path = path
41+
self._inputdict = inputdict
42+
self._outputdict = outputdict
43+
self._proc = None
44+
45+
def _start(self, frame):
46+
h, w = frame.shape[:2]
47+
pix_fmt = "rgba" if frame.ndim == 3 and frame.shape[2] == 4 else "rgb24"
48+
input_args = [a for k, v in self._inputdict.items() for a in (k, str(v))]
49+
output_args = [a for k, v in self._outputdict.items() for a in (k, str(v))]
50+
cmd = (
51+
["ffmpeg", "-y"]
52+
+ input_args
53+
+ ["-f", "rawvideo", "-pix_fmt", pix_fmt, "-s", f"{w}x{h}", "-i", "pipe:0"]
54+
+ output_args
55+
+ [self._path]
56+
)
57+
self._proc = subprocess.Popen(cmd, stdin=subprocess.PIPE)
58+
59+
def writeFrame(self, frame):
60+
if self._proc is None:
61+
self._start(frame)
62+
self._proc.stdin.write(frame.tobytes())
63+
64+
def close(self):
65+
if self._proc is not None:
66+
self._proc.stdin.close()
67+
self._proc.wait()
68+
69+
3470
MeshMouseIntersection = namedtuple(
3571
"MeshMouseIntersection",
3672
"node instance_id tri_id vert_id point_world point_local bc_coords",
@@ -1867,9 +1903,6 @@ def export_video(
18671903
quality="medium",
18681904
ensure_no_overwrite=True,
18691905
):
1870-
# Load this module to reduce load time.
1871-
import skvideo.io
1872-
18731906
if rotate_camera and not isinstance(self.scene.camera, ViewerCamera):
18741907
print("Cannot export a video with camera rotation while using a camera that is not a ViewerCamera")
18751908
return
@@ -1965,7 +1998,7 @@ def export_video(
19651998
}
19661999
)
19672000

1968-
writer = skvideo.io.FFmpegWriter(
2001+
writer = FFmpegWriter(
19692002
path_video,
19702003
inputdict={
19712004
"-framerate": str(output_fps),

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ dependencies = [
4040
"roma>=1.2.3",
4141
"joblib",
4242
"scikit-image>=0.9.0",
43-
"scikit-video",
4443
"Pillow",
4544
"websockets",
4645
"usd-core>=23.5",

0 commit comments

Comments
 (0)