Spaces:
Build error
Build error
Miquel Farre
commited on
Commit
·
e05c441
1
Parent(s):
9bada46
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)
|