update
Browse files
app.py
CHANGED
@@ -1,15 +1,16 @@
|
|
1 |
import os
|
2 |
import json
|
3 |
import gradio as gr
|
4 |
-
import tempfile
|
5 |
import torch
|
6 |
import spaces
|
|
|
7 |
from pathlib import Path
|
8 |
-
from transformers import AutoProcessor, AutoModelForVision2Seq
|
9 |
import subprocess
|
10 |
import logging
|
11 |
import xml.etree.ElementTree as ET
|
12 |
from xml.dom import minidom
|
|
|
|
|
13 |
|
14 |
logging.basicConfig(level=logging.INFO)
|
15 |
logger = logging.getLogger(__name__)
|
@@ -152,49 +153,43 @@ class VideoHighlightDetector:
|
|
152 |
outputs = self.model.generate(**inputs, max_new_tokens=64, do_sample=False)
|
153 |
response = self.processor.decode(outputs[0], skip_special_tokens=True).lower().split("assistant: ")[1]
|
154 |
return "yes" in response
|
|
|
155 |
def create_xspf_playlist(video_path: str, segments: list, descriptions: list) -> str:
|
156 |
"""Create XSPF playlist from segments with descriptions."""
|
157 |
-
|
158 |
-
ET.register_namespace('vlc', 'http://www.videolan.org/vlc/playlist/ns/0/')
|
159 |
-
ET.register_namespace('', 'http://xspf.org/ns/0/')
|
160 |
-
|
161 |
-
root = ET.Element("{http://xspf.org/ns/0/}playlist", {"version": "1"})
|
162 |
|
163 |
# Get video filename for the title
|
164 |
video_filename = os.path.basename(video_path)
|
165 |
-
title = ET.SubElement(root, "
|
166 |
title.text = f"{video_filename} - Highlights"
|
167 |
|
168 |
-
tracklist = ET.SubElement(root, "
|
169 |
|
170 |
for idx, ((start_time, end_time), description) in enumerate(zip(segments, descriptions)):
|
171 |
-
track = ET.SubElement(tracklist, "
|
172 |
|
173 |
-
location = ET.SubElement(track, "
|
174 |
location.text = f"file:///{video_filename}"
|
175 |
|
176 |
-
title = ET.SubElement(track, "
|
177 |
title.text = f"Highlight {idx + 1}"
|
178 |
|
179 |
-
annotation = ET.SubElement(track, "
|
180 |
annotation.text = description
|
181 |
|
182 |
-
start_meta = ET.SubElement(track, "
|
183 |
start_meta.text = format_duration(start_time)
|
184 |
|
185 |
-
end_meta = ET.SubElement(track, "
|
186 |
end_meta.text = format_duration(end_time)
|
187 |
|
188 |
# Add VLC extension
|
189 |
-
extension = ET.SubElement(root, "
|
190 |
-
{"application": "http://www.videolan.org/vlc/playlist/0"})
|
191 |
-
|
192 |
for i in range(len(segments)):
|
193 |
-
ET.SubElement(extension, "
|
194 |
-
{"tid": str(i)})
|
195 |
|
196 |
# Convert to string with pretty printing
|
197 |
-
xml_str = minidom.parseString(ET.tostring(root
|
198 |
return xml_str
|
199 |
|
200 |
def create_ui(examples_path: str, model_path: str):
|
@@ -243,7 +238,7 @@ def create_ui(examples_path: str, model_path: str):
|
|
243 |
|
244 |
try:
|
245 |
duration = get_video_duration_seconds(video)
|
246 |
-
if duration >
|
247 |
return [
|
248 |
None,
|
249 |
"Video must be shorter than 30 minutes",
|
@@ -286,7 +281,6 @@ def create_ui(examples_path: str, model_path: str):
|
|
286 |
|
287 |
if detector.process_segment(temp_segment.name, highlights):
|
288 |
# Get segment description
|
289 |
-
print("KEEPING SEGMENT")
|
290 |
description = detector.analyze_segment(temp_segment.name)
|
291 |
kept_segments.append((start_time, end_time))
|
292 |
segment_descriptions.append(description)
|
|
|
1 |
import os
|
2 |
import json
|
3 |
import gradio as gr
|
|
|
4 |
import torch
|
5 |
import spaces
|
6 |
+
import tempfile
|
7 |
from pathlib import Path
|
|
|
8 |
import subprocess
|
9 |
import logging
|
10 |
import xml.etree.ElementTree as ET
|
11 |
from xml.dom import minidom
|
12 |
+
from transformers import AutoProcessor, AutoModelForVision2Seq
|
13 |
+
|
14 |
|
15 |
logging.basicConfig(level=logging.INFO)
|
16 |
logger = logging.getLogger(__name__)
|
|
|
153 |
outputs = self.model.generate(**inputs, max_new_tokens=64, do_sample=False)
|
154 |
response = self.processor.decode(outputs[0], skip_special_tokens=True).lower().split("assistant: ")[1]
|
155 |
return "yes" in response
|
156 |
+
|
157 |
def create_xspf_playlist(video_path: str, segments: list, descriptions: list) -> str:
|
158 |
"""Create XSPF playlist from segments with descriptions."""
|
159 |
+
root = ET.Element("playlist", version="1", xmlns="http://xspf.org/ns/0/")
|
|
|
|
|
|
|
|
|
160 |
|
161 |
# Get video filename for the title
|
162 |
video_filename = os.path.basename(video_path)
|
163 |
+
title = ET.SubElement(root, "title")
|
164 |
title.text = f"{video_filename} - Highlights"
|
165 |
|
166 |
+
tracklist = ET.SubElement(root, "trackList")
|
167 |
|
168 |
for idx, ((start_time, end_time), description) in enumerate(zip(segments, descriptions)):
|
169 |
+
track = ET.SubElement(tracklist, "track")
|
170 |
|
171 |
+
location = ET.SubElement(track, "location")
|
172 |
location.text = f"file:///{video_filename}"
|
173 |
|
174 |
+
title = ET.SubElement(track, "title")
|
175 |
title.text = f"Highlight {idx + 1}"
|
176 |
|
177 |
+
annotation = ET.SubElement(track, "annotation")
|
178 |
annotation.text = description
|
179 |
|
180 |
+
start_meta = ET.SubElement(track, "meta", rel="start")
|
181 |
start_meta.text = format_duration(start_time)
|
182 |
|
183 |
+
end_meta = ET.SubElement(track, "meta", rel="end")
|
184 |
end_meta.text = format_duration(end_time)
|
185 |
|
186 |
# Add VLC extension
|
187 |
+
extension = ET.SubElement(root, "extension", application="http://www.videolan.org/vlc/playlist/0")
|
|
|
|
|
188 |
for i in range(len(segments)):
|
189 |
+
item = ET.SubElement(extension, "vlc:item", tid=str(i))
|
|
|
190 |
|
191 |
# Convert to string with pretty printing
|
192 |
+
xml_str = minidom.parseString(ET.tostring(root)).toprettyxml(indent=" ")
|
193 |
return xml_str
|
194 |
|
195 |
def create_ui(examples_path: str, model_path: str):
|
|
|
238 |
|
239 |
try:
|
240 |
duration = get_video_duration_seconds(video)
|
241 |
+
if duration > 1800: # 30 minutes
|
242 |
return [
|
243 |
None,
|
244 |
"Video must be shorter than 30 minutes",
|
|
|
281 |
|
282 |
if detector.process_segment(temp_segment.name, highlights):
|
283 |
# Get segment description
|
|
|
284 |
description = detector.analyze_segment(temp_segment.name)
|
285 |
kept_segments.append((start_time, end_time))
|
286 |
segment_descriptions.append(description)
|