Spaces:
Sleeping
Sleeping
Kosala Nayanajith Deshapriya commited on
Commit ยท
a70e30f
1
Parent(s): 3b1ecaa
Add Whisper pacing and Channel History features
Browse files- candidates.json +5 -0
- channel_history.json +10 -0
- dashboard.py +16 -0
- pipeline.py +37 -0
candidates.json
CHANGED
|
@@ -70,6 +70,11 @@
|
|
| 70 |
"type": "silence",
|
| 71 |
"score": 0.6
|
| 72 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 73 |
{
|
| 74 |
"timestamp": 286.89,
|
| 75 |
"type": "silence",
|
|
|
|
| 70 |
"type": "silence",
|
| 71 |
"score": 0.6
|
| 72 |
},
|
| 73 |
+
{
|
| 74 |
+
"timestamp": 275.88,
|
| 75 |
+
"type": "transcript_boundary",
|
| 76 |
+
"score": 0.7
|
| 77 |
+
},
|
| 78 |
{
|
| 79 |
"timestamp": 286.89,
|
| 80 |
"type": "silence",
|
channel_history.json
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"timestamp": "2026-06-11 11:30",
|
| 4 |
+
"video_id": "4Rq-LY16WxM",
|
| 5 |
+
"video_path": "flashgard.mp4",
|
| 6 |
+
"duration": "9m 27s",
|
| 7 |
+
"placements": 3,
|
| 8 |
+
"is_prediction": false
|
| 9 |
+
}
|
| 10 |
+
]
|
dashboard.py
CHANGED
|
@@ -902,6 +902,22 @@ with st.expander("๐ฌ View All Analyzed Moments (Advanced)"):
|
|
| 902 |
st.dataframe(df_show, width='stretch', hide_index=True)
|
| 903 |
|
| 904 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 905 |
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 906 |
# FOOTER
|
| 907 |
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
|
|
| 902 |
st.dataframe(df_show, width='stretch', hide_index=True)
|
| 903 |
|
| 904 |
|
| 905 |
+
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 906 |
+
# PAST ANALYSES (CHANNEL HISTORY)
|
| 907 |
+
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 908 |
+
history_data = load_json("channel_history.json")
|
| 909 |
+
if history_data:
|
| 910 |
+
st.markdown('<div class="gradient-divider"></div>', unsafe_allow_html=True)
|
| 911 |
+
with st.expander("๐ Past Analyses (Channel History)"):
|
| 912 |
+
# Reverse the list so newest is on top
|
| 913 |
+
history_data = history_data[::-1]
|
| 914 |
+
df_history = pd.DataFrame(history_data)
|
| 915 |
+
df_history = df_history[["timestamp", "video_path", "duration", "placements", "is_prediction"]]
|
| 916 |
+
df_history.columns = ["Date", "Video", "Duration", "Spots Found", "Predicted?"]
|
| 917 |
+
df_history["Predicted?"] = df_history["Predicted?"].apply(lambda x: "๐ฎ Yes" if x else "โ
No")
|
| 918 |
+
st.dataframe(df_history, width='stretch', hide_index=True)
|
| 919 |
+
|
| 920 |
+
|
| 921 |
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 922 |
# FOOTER
|
| 923 |
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
pipeline.py
CHANGED
|
@@ -5,9 +5,24 @@ pipeline.py โ Runs full pipeline as functions (no subprocess needed on Render)
|
|
| 5 |
import json
|
| 6 |
import os
|
| 7 |
import tempfile
|
|
|
|
| 8 |
import numpy as np
|
| 9 |
import pandas as pd
|
| 10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
|
| 12 |
# โโ Component 1: Candidate Generator โโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 13 |
|
|
@@ -420,6 +435,17 @@ def run_full_pipeline(video_path, video_id, creds, progress_callback=None):
|
|
| 420 |
update("๐ฏ Step 4/4 โ Generating final recommendations...")
|
| 421 |
result = run_component4()
|
| 422 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 423 |
update("โ
Analysis complete!")
|
| 424 |
return result
|
| 425 |
|
|
@@ -450,5 +476,16 @@ def run_full_pipeline_offline(video_path, progress_callback=None):
|
|
| 450 |
update("๐ฏ Step 4/4 โ Generating final predictions...")
|
| 451 |
result = run_component4()
|
| 452 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 453 |
update("โ
Prediction complete!")
|
| 454 |
return result
|
|
|
|
| 5 |
import json
|
| 6 |
import os
|
| 7 |
import tempfile
|
| 8 |
+
import datetime
|
| 9 |
import numpy as np
|
| 10 |
import pandas as pd
|
| 11 |
|
| 12 |
+
def save_to_history(entry):
|
| 13 |
+
"""Save an analysis result to channel history."""
|
| 14 |
+
history_file = "channel_history.json"
|
| 15 |
+
history = []
|
| 16 |
+
if os.path.exists(history_file):
|
| 17 |
+
with open(history_file, "r") as f:
|
| 18 |
+
try:
|
| 19 |
+
history = json.load(f)
|
| 20 |
+
except:
|
| 21 |
+
pass
|
| 22 |
+
history.append(entry)
|
| 23 |
+
with open(history_file, "w") as f:
|
| 24 |
+
json.dump(history, f, indent=2)
|
| 25 |
+
|
| 26 |
|
| 27 |
# โโ Component 1: Candidate Generator โโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 28 |
|
|
|
|
| 435 |
update("๐ฏ Step 4/4 โ Generating final recommendations...")
|
| 436 |
result = run_component4()
|
| 437 |
|
| 438 |
+
# Save to history
|
| 439 |
+
entry = {
|
| 440 |
+
"timestamp": datetime.datetime.now().strftime("%Y-%m-%d %H:%M"),
|
| 441 |
+
"video_id": video_id,
|
| 442 |
+
"video_path": os.path.basename(video_path),
|
| 443 |
+
"duration": result.get("video_duration_formatted", "0m 0s"),
|
| 444 |
+
"placements": result.get("total_placements_recommended", 0),
|
| 445 |
+
"is_prediction": False
|
| 446 |
+
}
|
| 447 |
+
save_to_history(entry)
|
| 448 |
+
|
| 449 |
update("โ
Analysis complete!")
|
| 450 |
return result
|
| 451 |
|
|
|
|
| 476 |
update("๐ฏ Step 4/4 โ Generating final predictions...")
|
| 477 |
result = run_component4()
|
| 478 |
|
| 479 |
+
# Save to history
|
| 480 |
+
entry = {
|
| 481 |
+
"timestamp": datetime.datetime.now().strftime("%Y-%m-%d %H:%M"),
|
| 482 |
+
"video_id": None,
|
| 483 |
+
"video_path": os.path.basename(video_path),
|
| 484 |
+
"duration": result.get("video_duration_formatted", "0m 0s"),
|
| 485 |
+
"placements": result.get("total_placements_recommended", 0),
|
| 486 |
+
"is_prediction": True
|
| 487 |
+
}
|
| 488 |
+
save_to_history(entry)
|
| 489 |
+
|
| 490 |
update("โ
Prediction complete!")
|
| 491 |
return result
|