Mark Duppenthaler commited on
Commit
013aff2
·
1 Parent(s): 08dfd47

Video Examples

Browse files
backend/examples.py CHANGED
@@ -10,7 +10,7 @@ def group_files_by_index(file_paths, data_type="audio"):
10
  if data_type == "audio":
11
  pattern = r"audio_(\d+).(png|wav)"
12
  elif data_type == "video":
13
- pattern = r"video_(\d+).(png|mkv)"
14
  else:
15
  pattern = r"img_(\d+).png"
16
  # Dictionary to store the grouped files
@@ -110,11 +110,12 @@ def build_infos(abs_path: Path, datatype: str, dataset_name: str, db_key: str):
110
  eval_results_path = abs_path + f"{dataset_name}_1k/examples_eval_results.json"
111
  elif datatype == "video":
112
  quality_metrics = ["psnr", "ssim", "lpips", "msssim", "vmaf"]
113
- extensions = ["mkv"]
114
  datatype_abbr = "video"
115
  eval_results_path = abs_path + f"{dataset_name}/examples_eval_results.json"
116
 
117
  response = requests.get(eval_results_path)
 
118
  if response.status_code == 200:
119
  results_data = response.json()
120
  else:
@@ -130,7 +131,7 @@ def build_infos(abs_path: Path, datatype: str, dataset_name: str, db_key: str):
130
  ]
131
 
132
  file_patterns = generate_file_patterns(prefixes, extensions)
133
-
134
  infos = {}
135
  for model_name in dataset.keys():
136
  model_infos = {}
@@ -192,7 +193,7 @@ def build_infos(abs_path: Path, datatype: str, dataset_name: str, db_key: str):
192
  file_info["image_url"] = file.replace(".wav", ".png")
193
  file_info["audio_url"] = file
194
  elif datatype == "video":
195
- file_info["image_url"] = file.replace(".mkv", ".png")
196
  file_info["video_url"] = file
197
  else:
198
  file_info["image_url"] = file
@@ -263,7 +264,8 @@ def image_examples_tab(abs_path: Path):
263
 
264
 
265
  def video_examples_tab(abs_path: Path):
266
- dataset_name = "sav_val_full"
 
267
  datatype = "video"
268
  db_key = "sa-v_sav_val_videos"
269
 
 
10
  if data_type == "audio":
11
  pattern = r"audio_(\d+).(png|wav)"
12
  elif data_type == "video":
13
+ pattern = r"video_(\d+).(png|mp4)"
14
  else:
15
  pattern = r"img_(\d+).png"
16
  # Dictionary to store the grouped files
 
110
  eval_results_path = abs_path + f"{dataset_name}_1k/examples_eval_results.json"
111
  elif datatype == "video":
112
  quality_metrics = ["psnr", "ssim", "lpips", "msssim", "vmaf"]
113
+ extensions = ["mp4"]
114
  datatype_abbr = "video"
115
  eval_results_path = abs_path + f"{dataset_name}/examples_eval_results.json"
116
 
117
  response = requests.get(eval_results_path)
118
+ print(eval_results_path)
119
  if response.status_code == 200:
120
  results_data = response.json()
121
  else:
 
131
  ]
132
 
133
  file_patterns = generate_file_patterns(prefixes, extensions)
134
+ print(f"File patterns: {file_patterns}")
135
  infos = {}
136
  for model_name in dataset.keys():
137
  model_infos = {}
 
193
  file_info["image_url"] = file.replace(".wav", ".png")
194
  file_info["audio_url"] = file
195
  elif datatype == "video":
196
+ # file_info["image_url"] = file.replace(".mp4", ".png")
197
  file_info["video_url"] = file
198
  else:
199
  file_info["image_url"] = file
 
264
 
265
 
266
  def video_examples_tab(abs_path: Path):
267
+ # dataset_name = "sav_val_full"
268
+ dataset_name = "sav_val_full_v2"
269
  datatype = "video"
270
  db_key = "sa-v_sav_val_videos"
271
 
frontend/src/components/VideoGallery.tsx CHANGED
@@ -4,6 +4,7 @@ import { groupByNameAndVariant } from './galleryUtils'
4
  import ExampleVariantMetricsTable from './ExampleVariantMetricsTable'
5
  import ExampleDetailsSection from './ExampleDetailsSection'
6
  import ExampleVariantSelector from './ExampleVariantSelector'
 
7
 
8
  interface GalleryProps {
9
  selectedModel: string
@@ -23,6 +24,68 @@ const VideoGallery: React.FC<GalleryProps> = ({ selectedModel, selectedAttack, e
23
  const variants = grouped[selectedVideo] || {}
24
  const variantKeys = Object.keys(variants)
25
  const [selectedVariant, setSelectedVariant] = React.useState(variantKeys[0] || '')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
  React.useEffect(() => {
28
  setSelectedVariant(variantKeys[0] || '')
@@ -72,14 +135,60 @@ const VideoGallery: React.FC<GalleryProps> = ({ selectedModel, selectedAttack, e
72
  selectedVariant={selectedVariant}
73
  setSelectedVariant={setSelectedVariant}
74
  />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  <div className="flex flex-col items-center gap-4">
76
- {variants[selectedVariant].video_url && (
77
- <video
78
- controls
79
- src={variants[selectedVariant].video_url}
80
- className="example-video"
81
- style={{ maxWidth: 400, maxHeight: 300 }}
82
- />
 
 
 
 
 
 
 
 
 
 
 
 
83
  )}
84
  </div>
85
  </ExampleDetailsSection>
 
4
  import ExampleVariantMetricsTable from './ExampleVariantMetricsTable'
5
  import ExampleDetailsSection from './ExampleDetailsSection'
6
  import ExampleVariantSelector from './ExampleVariantSelector'
7
+ import ExampleVariantToggle from './ExampleVariantToggle'
8
 
9
  interface GalleryProps {
10
  selectedModel: string
 
24
  const variants = grouped[selectedVideo] || {}
25
  const variantKeys = Object.keys(variants)
26
  const [selectedVariant, setSelectedVariant] = React.useState(variantKeys[0] || '')
27
+ const [toggleMode, setToggleMode] = React.useState<'wmd' | 'attacked'>('wmd')
28
+ // Add state for rewind seconds
29
+ const [rewindSeconds, setRewindSeconds] = React.useState(0.5)
30
+ // State for video scale
31
+ const [videoScale, setVideoScale] = React.useState(1)
32
+
33
+ // Playback time ref for syncing position
34
+ const playbackTimeRef = React.useRef(0)
35
+ // Refs for all video elements
36
+ const videoRefs = React.useMemo(() => {
37
+ const refs: Record<string, React.RefObject<HTMLVideoElement>> = {}
38
+ variantKeys.forEach((v) => {
39
+ refs[v] = React.createRef<HTMLVideoElement>()
40
+ })
41
+ return refs
42
+ }, [variantKeys.join(',')])
43
+
44
+ // Track which variant is currently playing
45
+ const [playingVariant, setPlayingVariant] = React.useState<string | null>(null)
46
+
47
+ // Play handler: pause all others, sync time
48
+ const handlePlay = (variant: string) => {
49
+ setPlayingVariant(variant)
50
+ variantKeys.forEach((v) => {
51
+ if (v !== variant && videoRefs[v]?.current) {
52
+ videoRefs[v]?.current?.pause()
53
+ }
54
+ })
55
+ }
56
+ // Pause handler
57
+ const handlePause = (variant: string) => {
58
+ if (playingVariant === variant) setPlayingVariant(null)
59
+ }
60
+
61
+ // When selectedVariant changes, sync playback position, rewind, and play state
62
+ React.useEffect(() => {
63
+ if (!selectedVariant) return
64
+ // Rewind playbackTimeRef by rewindSeconds, clamp to 0
65
+ playbackTimeRef.current = Math.max(0, playbackTimeRef.current - rewindSeconds)
66
+ // Set all videos to the new time, pause all except selected
67
+ variantKeys.forEach((v) => {
68
+ const ref = videoRefs[v]?.current
69
+ if (ref) {
70
+ ref.currentTime = playbackTimeRef.current
71
+ if (v !== selectedVariant) {
72
+ ref.pause()
73
+ }
74
+ }
75
+ })
76
+ // If a video was playing, continue playing the swapped variant
77
+ if (playingVariant && videoRefs[selectedVariant]?.current) {
78
+ videoRefs[selectedVariant].current.play()
79
+ }
80
+ }, [selectedVariant])
81
+
82
+ // When the selected video plays, update playbackTimeRef
83
+ const handleTimeUpdate = (variantKey: string) => {
84
+ const ref = videoRefs[variantKey]?.current
85
+ if (ref && variantKey === selectedVariant) {
86
+ playbackTimeRef.current = ref.currentTime
87
+ }
88
+ }
89
 
90
  React.useEffect(() => {
91
  setSelectedVariant(variantKeys[0] || '')
 
135
  selectedVariant={selectedVariant}
136
  setSelectedVariant={setSelectedVariant}
137
  />
138
+ <ExampleVariantToggle
139
+ toggleMode={toggleMode}
140
+ setToggleMode={setToggleMode}
141
+ type="button"
142
+ selectedVariant={selectedVariant}
143
+ setSelectedVariant={setSelectedVariant}
144
+ variantKeys={variantKeys}
145
+ />
146
+ <div className="flex items-center gap-4 mt-2">
147
+ <label htmlFor="rewind-seconds" className="font-mono text-xs">Rewind Seconds:</label>
148
+ <input
149
+ id="rewind-seconds"
150
+ type="number"
151
+ min={0}
152
+ step={0.1}
153
+ value={rewindSeconds}
154
+ onChange={(e) => setRewindSeconds(Math.max(0, Number(e.target.value)))}
155
+ className="input input-bordered input-xs w-20"
156
+ placeholder="Seconds"
157
+ />
158
+ <label htmlFor="video-scale" className="font-mono text-xs ml-4">Scale:</label>
159
+ <input
160
+ id="video-scale"
161
+ type="range"
162
+ min={0.3}
163
+ max={1}
164
+ step={0.01}
165
+ value={videoScale}
166
+ onChange={e => setVideoScale(Number(e.target.value))}
167
+ className="range range-xs w-40"
168
+ style={{ verticalAlign: 'middle' }}
169
+ />
170
+ <span className="ml-2 font-mono text-xs">{(videoScale * 100).toFixed(0)}%</span>
171
+ </div>
172
  <div className="flex flex-col items-center gap-4">
173
+ {variantKeys.map((variantKey) =>
174
+ variants[variantKey].video_url ? (
175
+ <video
176
+ key={variantKey}
177
+ ref={videoRefs[variantKey]}
178
+ controls
179
+ src={variants[variantKey].video_url}
180
+ className="example-video"
181
+ style={{
182
+ width: `${videoScale * 100}%`,
183
+ height: 'auto',
184
+ display: selectedVariant === variantKey ? 'block' : 'none',
185
+ maxWidth: '100%',
186
+ }}
187
+ onTimeUpdate={() => handleTimeUpdate(variantKey)}
188
+ onPlay={() => handlePlay(variantKey)}
189
+ onPause={() => handlePause(variantKey)}
190
+ />
191
+ ) : null
192
  )}
193
  </div>
194
  </ExampleDetailsSection>